457 comments

[ 3.2 ms ] story [ 257 ms ] thread
Eh. Everyone hates on jQuery, but for most informational sites that's really all you need for basic interaction.

Speed really isn't bad, and it's so straightforward that it's hard to mis-use at this point.

I seem to have way more issues with newer frameworks/SPA if I'm not using chrome with no extensions.

Makes me nervous dealing with important stuff like banking or government sites.

For basic interaction, you don't need anything but vanilla JS. Browsers have come a long way since the days where jQuery was almost necessary to deal with all of the minor differences/bugs in various browsers.
It's a much nicer syntax and has a ton of useful helpers.

Vanilla js for similar things just looks like someone has waved the ugly stick at it.

There are sound arguments against jQuery but the "you can just use vanilla" is the least convincing.

Not having to load yet another JS library on your page if you don't really need it is a pretty good argument, I'd say.
OP's argument is that jQuery is all you need for basic use cases, so that'd be the only JS library loaded.
Except we've become so used to loading multiple megabytes of JS even on a simple blog post, that a 30KB library probably won't make a noticeable difference. Insofar as file size is concerned, I'd much rather pull in jQuery than some random npm package that depends on god-knows-how-many other random packages.

Even GOV.UK, an incredibly lean website by today's standards, only noticed a 10% difference in their benchmarks.

A 10% performance gain is quite a big deal, I wouldn't just shove it under the table like that.
Like every % comparison, it depends on the baseline.

Cue all the people going on about big O for parts of the code that are indistinguishable from noise in actual benchmarks.

Yes. You'll note that I already anticipated that in my original point. I was very specific in how I worded it for good reason.
To add: jQuery is a pretty huge library for what it does. Talking both bundle size and execution speed. Not that the latter is noticeable for most cases, but it's still a cost. The question is: What for?

The primary use case for it has been cross browser compatibility plus a bit of sugar. The former is _gone_ and the latter is easily replaced with a few lines of JS. Then there is an ecosystem of libraries and components around it. Many of them have ditched jQuery or have provided an API that doesn't require it.

30kb minified and gzipped! Less than most hero images. It's a nice API for simple stuff.

I think if you strip out the AJAX support it can get extremely tiny.

30kb gzipped is still 10x larger than Preact for reference
that doesn't make it an issue in any way, it's not a numbers competition unless you have a 56K
One of the explicit goals of gov.uk is to be maximally accessible, and that includes for people accessing the Internet on a potato or who have a metered connection.
It adds tens of milliseconds to just downloading on a fast connection, plus it has to be parsed before what ever you need it to do will be functional.

To compare, just roughly:

For roughly the same size you can get declarative/reactive rendering with React, or an optimized FP standard library with ClojureScript, or data driven visualizations with d3 (roughly 2x the size).

For a tenth of the size you can get stuff like htmx, or a json validation library (avj), or like someone said Preact (React alternative).

But for jQuery, you're paying that for basically nothing the browser APIs don't already provide. It was a godsend 10y ago, but with legacy browsers finally fading out, the last one being ie11, you really don't _need_ it anymore.

This is not the case anymore but I remember when Angular was including a version of jQuery, and having methods like "doSthAsInJquery" (paraphrasing) in Angular, and I could still hear everyday that Angular didn't have the overhead of including jQuery.

I wish we could have standardized in the Linq-like API of jQuery.

I'll admit I'm a bit out of practice with the state of vanilla JS, but it seems like you'll be re-inventing the wheel for simple stuff.

Like a collapsible section that's lightly animated.

I worry too about people not considering accessibility.

A lot of my bugs day to day is not being able to tab into things like hover menus or being able to activate buttons because someone forgot to consider correct event callbacks.

Maybe it's different now, but using a jQuery makes it more likely the code will cover cases like that.

You bring up some interesting concerns. It's a good example of why there isn't a one size fits all answer. The UK gov site has high standards for these kind of things so will do it right anyway, but for a small shop leaning on a framework makes a lot of sense
In 2020, a collapsible section is a matter of adding / removing a classname and a CSS animation; there's a few ways to do so, using jQuery is one, but you don't need thousands of lines of a JS library (network bandwidth + JS interpretation) to achieve that.
Can CSS transitions and animations handle animating to auto height/widths yet?
I don't think so. One trick I've used to good effect is setting an high max-height, then translating by 100% and removing pointer events.
I feel like this solution feels subtly "wrong" if you're animating, because that high max height will be arbitrarily far away from where you'd normally want to animate to. Doubly so for easing out.
Yeah it's a bit weird, but haven't found a better trick yet.
Collapsible section? https://developer.mozilla.org/en-US/docs/Web/HTML/Element/de...

There's some CSS transition stuff you can add to that to make it lightly animated: https://css-tricks.com/how-to-animate-the-details-element/

Yeah, jQuery might make some things easier, but when possible, using native HTML elements makes things even easier,

Hmm, I would agree that you can do 95%+ of stuff jQuery used to be used for in vanilla js or html/css in a nicer way but animated collapsible divs still require a stupid amount of js to achieve.
(comment deleted)
I worry too about people not considering accessibility.

This isn't a complaint you can level at the gov.uk team. They're obsessed with accessibility. Gov.uk is probably the best example of a well-designed, well-built, completely accessible website on the whole internet.

I meant more for anyone building a website.
Whilst *.GOV.IN (India) is the worst.
If you've been using jQuery for years, know it, and can write a good amount of code without looking at a reference, then by all means, keep using it. It's not going anywhere anytime soon.
i see a lot of

   const $ = document.querySelector.bind(document);
Right. However, jQuery isn't just for cross-browser.

It provides a clean API for manipulating the DOM, as this site demonstrates (which is ironic): https://youmightnotneedjquery.com/

Personally, for simple sites, I aim for vanilla JS but use jQuery (cash, actually) where it makes sense - such as working on collections of elements.

(comment deleted)
I loved jquery back in the day. It made web development bearable in a time when it was a clusterfuck.

I think a lot of people owe a lot of thanks to jquery.

But in 2022 vanilla javascript is all you really need.

jQuery still offers a much nicer experience. The built-in dom apis are neither very elegant nor ergonomic.

    // jquery
    $(selector).on('click', fn)
     
    // vanilla js
    document.querySelectorAll(selector).forEach(el => 
      el.addEventListener('click', fn)
    )
It takes 1min to write a wrapper around that, though.

Having said that, for the sake of 25kb - if you use more than a handful of features you might as well just include it.

That's the problem.

It takes only 1 minute to write a wrapper, so you will write one, and I'll write one, and your dog will write one.

Then compare it with dog's and pick the simpler one :) I don't know what's wrong with a utils.js file that only has what you need in a way that fits your project exactly. Woof.
But writing that utils.js will end up rewriting jQuery.
I've seen this argument a lot, but based on my experience it will take ~5 small functions to get what I need and how I need.

It's even easier if you copy paste from here: https://anguscroll.com/just/

your dog will not look for a simpler impl before making one.

your npm's dependencies authors cat will write a small wrapper and wont know about yours.

If that is literally the only wrapper you need, sure go ahead.

But most of the time, you find you need another wrapper, and then another, and the next thing you know you have most of jQuery, just not as uniform or as well tested.

I've seen this with database ORMs also.

Fully agree, and your example is still relatively simple. Method chaining in jQuery allows for extremely expressive one-liners that would require a huge amount of boilerplate in vanilla JS.
or delegate...?

document.addEventListener('click', function(e){ var t = e.target;

  if(t.closest('.foo') && t.nodeName.toLowerCase() === 'button'){
     e.preventDefault();
     // do stuff here
  }
  else if(t.closest('.bar') && t.nodeName.toLowerCase() === 'a' && t.classList.contains('here')){
     e.preventDefault();
     // do smth else here
  }
}, false);

one listener to rule them all...?

elegant enough and once you get used to it...

.closest can be pollyfilled too..

Is it worth adding the library (download size + script parsing & execution) for that though?

At the very least there are some jQuery alternatives that are modular, smaller, and have less backwards compatibility like iirc zepto.

Yup. Because the size of the library and the execution time just isn't that big of a deal, it's something people seem to obsess over but it doesn't really matter much.
Web development is still a clusterfuck.
I agree if you are talking about frontend. Backend is still pleasant. And even frontend becomes bearable thanks to HTMX.
If you just want “basic interaction” without any framework complexity, alpine.js is way better than jquery. It’s extremely simple and does the basic data binding stuff that jquery lacks.
I will always think fondly of jQuery. It did a great job for what it was intended, saved a lot of time. jQuery's time has passed, and that's ok too.
>> Eh. Everyone hates on jQuery, but for most informational sites that's really all you need for basic interaction.

The point seems to be that you don't even need that any more, so just get rid of it. Not sure why people latch onto cruft so much and defend its continued use.

On the performance side they cite 10 percent improvement, which doesn't sound like much to a lot of people. But remember that performance gains/regressions get compounded. Maybe there are 8 things that each eat 10 percent - you either start improving somewhere or you just refuse to even try. If I could improve 10 percent while removing a dependency I'd be all over that.

For AJAX, jQuery is still simpler than vanilla JS.
Even fetch?
Definitely not Fetch. I don't believe anyone can argue that Fetch is more complicated.

I think this really seems to stem from a "I'm only used to jQuery, anything else is a big mental effort to learn and I'd rather stick with what I know".

I get it. Vanilla JS, if you're not used to it, is scary. But if you're advocating for jQuery "for simple interactions", and assuming it's simpler than vanilla JS, at some point you should ask yourself if you're just letting your skills stagnate, and staying stuck in the past. You owe it to yourself to update your skillset. If you decide you still need jQuery (e.g. maybe you need a plugin/library that requires jQuery), then fine. But at least you'll be making an informed decision, not a FUD-driven one.

As someone kinda obsessed with handcrafting all of its software without any dependency and is highly used to dom operations, I can't but thing you're making it much more of a deal than it is.

Handcrafting JavaScript applications without jQuery is possible, the real question though is: is it convenient if you like and find productive using jQuery? Here's a fact: you can always remove jQuery later when the product is mature and standards understood and there is time budget for it.

> Not sure why people latch onto cruft so much and defend its continued use.

A characteristic of communities with lots of people that do not have a theoretical background. JS, PHP, jQuery, some parts of Ruby/Python -- they defend it with their life, and I argue it's because the rest of the world looks very scary to them.

(comment deleted)
I miss the days when jQuery reigned supreme, and all the tenderfoot magpie developers didn't yet have the twinkle of React in their eyes
I remember doing pocs with observables, angular and react back when they were all way new and thinking observables really makes the other two unnecessary.
I don't; it was an improvement when BackboneJS came out so I could reason about larger scale applications, and another improvement when AngularJS came out so I could build and write tests for logical, reusable components, and another when React (especially in 2022) was there and reduced these components to simple JS functions.

That said, I don't like how complicated modern day front-end development is, to the point where you need a university degree to even try and fathom some of React's inner workings (e.g. https://reactjs.org/blog/2019/11/06/building-great-user-expe...) etc.

Oh god, Backbone. I absolutely hated that framework. It didn't even seem to do anything, it seemed like I had to implement all of the logic myself. Except I had to do it their way, for some reason, and practically nothing made sense. (I haven't touched it in years, though, so my memory is probably distorting my experience)

I like the idea of React, just not what it has turned into. The amount of tooling that it has created to do things that should be simple (but aren't because of the runtime and/or the programmer), and the gymnastics it goes through so that people can have their precious (often unnecessary) SPAs, is ridiculous. That, and JSX continues to be an abomination that shits all over separation of concerns so that smoothbrains don't hurt themselves trying to reason over it.

Re: React, have you looked at Vanilla custom elements:

https://javascript.info/custom-elements

I've been using them lately and I think they are the bees knees.

Yeah I have been looking them over and they seem very interesting. Have not tried them yet.

Would love for there to be One True Way(tm) without the framework question.

HTMX + custom elements + Alpine.js = love
Good policy, but also not huge gains here IMO. I wouldn't choose jQuery as I can do everything I need without it, but I also don't know of any serious issues it represents if it hangs around here or there.

I have a bunch of old code that uses jQuery, it works, everything new is vanilla but otherwise it's not a big impediment / problem that I find.

We found it to be about 32kb gzip+minified in our builds. I just dropped it from one of our apps, where it wasn't even used except in a legacy logging module. We replaced the ajax call with XHR. The other app we maintain has it as well, again only for the ajax method.

While it may be nice, for large production apps we'll take the filesize gains where we can find them.

I believe it's kind of sad that in the days of 2 TB USB sticks that 32kb matter.
Our product is used by all sorts of devices and resources. Many use it on super old hardware in different countries. 32kb isn't much, but when you're analyzing Time To Render metrics, you might be surprised how little is necessary to move the needle.

That said I don't expect a massive impact from this change, but removing unused code is going in the right direction.

Removing large chunks of unused code feels refreshing, that is true.
Then, on the other side of things, every fast food android app is ~60 MB. Even Five Guy's is 45 MB. Why? They all do the same thing, and none of the data that is used is included in the app, and all the logic might as well be the same.

And then on top of each restaurant app, you also have Uber Eats, Door Dash, etc., which again, basically so the same thing.

There should really be a single fast food app, I select my restaurant, and it shows me the options (which is basically google maps with mobile websites that would actually work). There's no reason for every restaurant and delivery service to have their own app.

The gains aren't massive — certainly not something any human using the site would notice (about 20ms faster to render pages for the average mobile phone user).

Still good to remove unncessary dependencies, though.

Not on an individual scale, no, but when you consider the millions of visits and views they get per year it adds up from a global / zoomed out point of view.

I'm sure with some math you can make a calculation on how much bandwidth and energy was saved with this One Clever Trick.

A government is the perfect place to look at this "zoomed out" view.

Your citizens an average rate of pay of Y per year. Some of time they save by getting stuff done on a government website will be put into getting more economic work done. If the citizens do 10 billion pageviews of gov.uk per year, and you shave off 20ms, thats 27 human-years of work per year. So it is certainly worth making this optimization, even if it takes a few people a few months to figure out how to remove jquery.

Tangential, but sometimes I see people say that jQuery is dead/failed. While it's not as popular anymore, I think that's actually the perfect evolution for it. jQuery was making up for browser API shortcomings, and now many of those shortcomings have been addressed and been incorporated into browser APIs (not everything, but quite a bit).
I agree. Also reminds me of CSS resets, the goal of modern-normalize is to make itself obsolete.
I really don't get this discourse, jQuery API is much more ergonomic, concise and clearer than the DOM api. Sure you can do it but that doesn't mean you should
Just replace that one liner with a 15 liner.
document.querySelector('html')

And for React: https://javascript.info/custom-elements

Other functions are much more difficult to replace

    $('.sth').closest('ul')
To me jQuery is like Regex or Linq. I think it had a really good api.
This did not exist the last time I looked. TIL. Thank you!
Is not the same thing as it is a Element method, not NodeList one, so you will would need to map it instead. Because NodeList doesn't have the .map method you would also need to transform it to a Array first.

So the actually drop-in replacement of `$(foo).closest(bar)` would be something like:

    Array.from(document.querySelector(foo)).map(el => el.closest(bar))
Is it harder or just a bit longer-winded? E.g. i'm thinking this is the same behaviour

    document.getElementsByClassName('sth')[0]?.closest('ul');
Thanks, this is now standard it seems. TIL
That's not exactly the same, I don't think, because jQuery will give you all the `ul` that are closest to `.sth`, not just the first. You'd have to write a loop over the list returned from `document.getElementsByClassName('sth')` to get the same behaviour (because it doesn't look like the standardised `closest` works on lists.)
If i'm following right, i think this expression would match?

    Array.from(document.getElementsByClassName("sth")).map(e => e.closest("ul"))
The jQuery is definitely nicer to read than this though
(comment deleted)
(comment deleted)
It's not because you know how to do a hello world that you know how to program.
And you would replace $.getJSON by how many lines?
are we doing CORS? Adding headers? If it is just a one-off fetch, I'd probably long-hand it. If I intended to be fetching from many endpoints, I'd probably write a tiny little abstraction. I'm not exactly keen on loading a 30kb lib (gzipped) so that I can write (maybe) fewer lines for data fetching. Especially considering jQuery's async requests don't conform to the fetch standard. (They reject on 404s)
I think it's a bit of both. jQuery served the purpose of making web development more sane back in the day by handling all browser quirks. Part of that was the nice syntax.

I personally have tried to drop jQuery, but truthfully, its syntax is just much easier to use. Nowadays, I use Cash https://github.com/fabiospampinato/cash to give me the nice syntax without the bloat. It strikes the perfect balance for me.

I did a javascript project targeting web/blackberry and early ios. We used jQuery to smooth out the kinks (or that's what our lead told us). It worked as expected.

Went from disliking it to really liking the syntax. Its pretty clear and easy to use, which is why I still use it. We don't use it extensively becaue we're still on the "submit form, get page back with javascript graph and data tables table, development model. We probably should transition to a framework, but they evolve so quickly ...

> I personally have tried to drop jQuery, but truthfully, its syntax is just much easier to use.

It's not just the syntax, it's also the expression-heavy and chained API which makes it much more flexible. As well as the set-oriented approach, which can lead to performance issues if you're not careful but is generally extremely enjoyable.

The DOM is an extremely procedural, plodding API, you need to name everything because you always need to set attributes and call non-chainable side-effecting APIs, not to mention the fecking NodeList which has to be converted to an array to do basically anything useful (in part because Javascript never really embraced iterators, and instead uses arrays for everything still).

I guess you could mitigate that with an "API adapter", but...

Although writing jQuery is still shorter (And likely will forever be). Editor (like vscode) nowadays is much more smarter then the era.

A lot of API with long names is no longer a issue to type. You just mark the variable as a element. After that, autocomplete handles the rest for you. Shorten the gap with experience of using jQuery. If developer tools is still as dumb as that era. I would think the transition is impossible.

And there are also more frameworks to enhance experience of style modification or templating. Back to then, there are only some dumb template that do initial rendering. But framework these days also handles update for you. So you don't really need to modify it directly by yourself unless in some edge case.

Yes, the DOM API is painful to work with.
(comment deleted)
Ad hoc manipulation of the DOM contradicts the philosophy of a lot of frameworks, as that is state which is unaccounted for.
> jQuery was making up for browser API shortcomings

While this is true, I can still code circles around frontend developers using vanilla JS.

The decline of jQuery is mostly due to the rise of webapp frameworks like React and Vue. But if you are tasked with adding like, a button to a static webpage, jQuery is still the king.

one of the nice features of AngularJS when it came out was the inclusion of the jquery lite api for interacting with the dom.
I never really knew jQuery besides the five things that I googled, so once I had to do more "dynamic" frontend things I just looked into Vanilla JS and it kind of works for me. Not sure if I had WTF-moments besides the normal "this seems to be how things work" stuff, so I think it's easy enough?!?

Only thing I always have to look up is how to make sure my script is executed once everything is done and not before and "ready()" is obviously easier than adding an event listener to "DOMContentLoaded". Yeah, had to look it up for the comment.

Simplifying interaction with the DOM is obviously a huge feature of jQuery. But also the functions are just very nicely laid out with the assumption you are doing web stuff.

$(thing).doThis() is just so perfectly terse and understandable for what it's doing. Not just writing, I find jQuery to be very, very easy to understand and read.

Yeah, you're right. Maybe I should give jQuery another look. :-)
>While this is true, I can still code circles around frontend developers using vanilla JS.

My first use of jQuery was in the dark days was building UIs (with things like drag and drop, etc) that had to run on Internet Explorer and Netscape. We'd started with "vanilla" but were ending up with what was effectively two separate codebases. Moving over to jQuery let us eliminate a massive amount of duplicate code and dramatically increased our productivity.

>The decline of jQuery is mostly due to the rise of webapp frameworks like React and Vue.

Partly. Frameworks like Angular/React/Vue are a necessary byproduct of building and maintaining large codebases. But the fall of jQuery was largely a result of a more standards approach in mainstream browsers (said another way: deprecation of IE and not needing to work at maintaining consistent behavior across browsers), as well as adding traditional jQuery-like features to vanilla JS.

There really isn't a big use-case for jQuery anymore, although I will remember it fondly.

I call bullshit on all accounts. If someone actually tasked you with adding a button to a webpage...
When people have said this to me in the past I would trot out a list of features that were still useful, but there are one or two where I think the defaults are backward. There was a long time between when "jQuery is dead" and parent selectors of any kind existed, and list comprehension is still a huge miss.

I still wonder occasionally if there's a place for a library that works like a strict subset of jQuery, but with different error/empty set handling defaults. Especially with list comprehensions. I found that 9 times out of 10 if I run a selector I'm expecting results, and jQuery will silently eat that error, requiring a bunch of inline error handling in the 'interesting' paths in your code. I'd be much happier with an optional parameter for silent failure or even writing the occasional try/catch.

Javascript has become so nice, now that browsers support modules.

I use a module "dqs.js" for all my query needs. It contains only these two lines:

    export const dqs  = document.querySelector.bind(document);
    export const dqsA = document.querySelectorAll.bind(document);
And use it like this:

    import { dqsA } from 'lib/dqs.js';

    for (const rabbit of dqsA('#rabbits .green')) {
        ... do something with all green rabbits ...
    }
There is .forEach() on NodeLists, so you can do stuff like this in every browser, no lib, no helper functions needed:

    document.querySelectorAll('a').forEach(tag => {
      // operate on tag
    })
I think it's just for brevity, rather than because a helper is needed. OP listed the entire source code of their module in their comment.
Brevity is cool, but that's kind of like naming all your variables one letter chars for brevity.

This is something every web dev will instantly know what it does:

    document.querySelectorAll('#rabbit .green').forEach(tag => {
      
    })
Whereas this is something nobody knows what the fuck it is because it's completely non-standard.

    for (const rabbit of dqsA('#rabbits .green')) {

    }
And get what, 10 characters less in one row? Basically nothing.
for/of vs .forEach isn't the issue here. Frankly I almost always use for/of because it's implemented for all iterators and I prefer being outside of a function (e.g. I can use await).

All they did was alias `dqsA`. If anything, it's the fn name that could be better.

It’s no more ‘non-standard’ than jQuery’s `$`.

Most IDEs will allow you to see what dqsA aliases by mousing over. I don’t really see a problem with it.

It also looks like the kind of thing a pre-commit hook could trivially expand if you’re working with other people who might find it in some way unacceptable.

how's browser support for something like "a:has(img[src$='.gif'])" though?
You probably shouldn't be making that query, unless you're doing something specific like web scraping and don't have control over the content of the site.
That's always been the blessing and curse with JQuery. It allows you to easily filter objects but it doesn't encourage efficiency.

A lot of people don't have control over the content of their site in enterprise situations. If you're stuck using an old framework or CMS you could be beholden to someone else. And at the same time there's a lot of devs who dgaf and just ship what works.

you could be using it already w/jquery though and if you just switched to the native selector it would stop working everywhere but safari.

"#some_combo:has(option:selected[value=..]) + .." seems like a reasonable way to conditionally target something to me, is it terribly worse than some other way?

> is it terribly worse than some other way?

Yeah, it's fragile and will easily lead to bugs when someone changes the markup without realizing it's going to break some crazy selector in another part of the code.

It would make a lot more sense to just add a class to the element you're trying to select.

it's a conditional select, you're saying just add code to add/remove a class to the target - of course, but that defeats the point of wanting a conditional selector in the first place
The point of selecting an element is to do something with it. How does selecting it by class defeat the point?

Look, if you need this for some one off thing and you've determined it's the best way to do it in this special case, it's not hard to create a function that will find the element you want.

It's not a good argument for using jQuery IMO, because if you're doing this regularly there's probably a better way to do it.

But coming soon™ you will be able to do even this with `document.querySelector`.

Edit: I didn't pay close attention to your second example. I was speaking mostly related to the a:has example before. Your second example seems to be something that would be desired more in CSS than JS, and I don't think it's unreasonable to do that in CSS. If you need to do it in JS you can workaround browser limitations just fine by writing more than one line of code to do the selection and test the condition.

That selector does not seem fragile at all. It selects any anchor elements with gifs in them. A lot of the time we can't change the markup, either.
:has doesn't exist but you can do [].map.call(document.querySelectorAll("a img[src$='.gif']"), (e)=>e.closest("a")).filter(e=>e)
:has certainly does exist, but only in Safari. Hopefully Chrome and Firefox will catch up soon.
alternatively, if you need to use anything other than `forEach` for working on the list, you can turn the NodeList into an array using the array spread syntax (equivalent to using Array.from) e.g.

  [...document.querySelectorAll('a')]
  .filter(node => node.getAttribute("data-foo") === "bar")
Not everyone wants to be so wasteful.
what do you mean by "wasteful"?
Creating an array, populating it with however many elements just to be able to call some methods and destroying it immediately afterwards. And doing it all over the app, just because it's syntactically convenient. (all while you already have an iterable collection in the form of NodeList)
It is a bit weird to consume an iterator into an array when a NodeList is already iterable.

Not sure why it caught on.

I see it a lot with other iterables, too. People may like one liners and functional style more than a procedural `for (of)` construct, so they use `[...iterable].any_array_function(...)` everywhere, except when foced not to by async code :).

Might also have something to do with Redux and immutable patterns. (the use of spread operator in general)

Usually it’s because you want to use an array function like .filter() that isn’t implemented by the iterable itself.
NodeList.prototype.filter = Array.prototype.filter;

and you can querySelectorAll('...').filter(el => ...) without any copies.

(comment deleted)
I'm also one of those guys that will always spread NodeLists (and other iterable-but-not-array type of objects) but it's really only because I find functional style a lot more readable than imperative style for loops. It might be iterable, but if it doesn't have map/filter/reduce and friends, might as well not be for me.
NodeList.prototype.filter = Array.prototype.filter;

and you can querySelectorAll('...').filter(el => ...) without any copies.

ditto for other mentioned functions. Prototypal nature of Javascript is there for a reason.

In every single project or company I've ever worked on/with, monkey patching was _extremely_ frowned upon (for good reasons). Also, how would you be able to filter without any copies? you'd at least be forced to make one. filter is _not_ supposed to mutate anything. so you'd have to create a new Array and/or NodeList, and put the filtered values back in. Even then, doing all this stuff for what is effectively one single copy that is likely to be insignificant at a performance level is, in my opinion, excessive. I just copy once and make the code clearer.
I add the parent element to mine

    const $ = (selector, parent = document) => parent.querySelector(selector);
    const $$ = (selector, parent = document) => parent.querySelectorAll(selector);
This is the way. In addition to `$` and `$$`, I usually have `$h` for creating elements:

    /**
     * @param {string} name
     * @param {HTMLElement.prototype} props
     * @param {Array<HTMLElement|string>} children
     * @return HTMLElement
     */
    function $h(name = 'div', props = {}, children = []) {
        const el = document.createElement(name);
        Object.assign(el, props);
        el.append(...children);
        return el;
    }
I still use jQuery for frontend JavaScript when I can. It's so much more efficient than native JavaScript. I can't imagine anyone prefers to write document.getElementById('element').style.display = 'none' rather than $('#element').hide();
When you are dealing with less than 5 "interactive things", jQuery is awesome... beyond that it might be better to consider a front-end framework.

Jr devs have the tendency then to discard jquery because "is old" not because it isn't working anymore.

Though for that little work, I'd rather have a small local library that implements what I need over standard DOM & JS parts instead of the full weight of jQuery.

Unless of course I need to support legacy browsers, then jQ is a no-brainer - that crap is solved there and I don't want to have to deal with it myself.

And while jQ is large compared to my little home-grown set of wrappers, it is small compared to all the other stuff many pages draw in these days, so perhaps size isn't a great metric to criticise it on!

that crap is solved in a lot of places, jQuery is no longer the only library, and you don't need to support legacy browsers as much anymore, if at all

Companies are getting more security-conscious because of all the hacks and the pain of keeping old browser support is no longer outweighing the risks of upgrading is my theory.

There are tools like babel (even typescript) which can help you support older browsers.
For personal projects I'm far beyond caring about ancient browsers. In DayJob well hopefully soon be dropping support for IE completely. Unless someone is specifically paying me to care then I don't need help supporting truly legacy UAs.
I think it's not so bad if you organize things reasonably well and minimize "lemme just modify the DOM a wee bit here" hacks. jQuery was popular at a time when "cowboy programming" was very common, leading to a lot of really bad/difficult jQuery apps; but that wasn't strictly jQuery's fault, as such.

That said, front-end frameworks can of course be a better choice for many things, even if it's just because it provides this kind of organisation by default making it easier for the, ehm, less organized devs.

I would say jQuery has a place in any codebase that's simple enough it has imperative statements like that. Past a certain not-too-high level of complexity you're much better off writing "if (condition) then <element> else null" in your view and "condition = false" in your update instead of even the short $('#element').hide();.
I prefer to write the first.
By "more efficient" it seems like you mean "less typing" because that is significantly less efficient in terms of downloaded code size and performance (the jQuery code calls the vanilla code.)

PS. $ is an alias for document.getElementById so you can just do $('my_id').style.display = 'none'.

most people probably have jquery cached in their browser if you're pulling it from the google cdn
That hasn't been the case for years because of per-origin caching. CDNs get their performance from edge routing, not caching.
Thanks to cache partitioning, this is no longer true.

See, it turns out that by carefully leveraging cached retrieval of third party resources, scripts on two different domains can figure out if they are running in the same web browser, effectively pulling off browser fingerprinting.

To stop this, modern browsers don’t share third party resource caches cross domain.

So using a well known CDN no longer confers any benefit - even if a user has pulled down jquery for another site’s benefit, when they come to your site and you request the same resource, the browser will go out and re-retrieve it, to prevent you or the third party domain from being able to infer anything about the user based on the speed of the response or whether or not the request got made.

ahh wasn't aware, and good to know
Indeed. We cannot have nice things.
LocalCDN is great for this! Avoids both the privacy concerns, plus makes things a bit speedier as everything is readily available locally already
As others have mentioned this isn't the case, also the browser still has to parse that JavaScript, which for a lower end mobile phone is often significant.
I think the more direct comparison is

document.querySelector('#element').style.display = 'none'

That has the same ergonomics as the jQuery selector, and is just a bit longer. I feel like with editors that autocomplete, it's not enough of a difference to warrant the extra dependency.

(comment deleted)
I think the vanilla JS is better actually, because I actually know what it's doing.

I've never used JQuery before and would have assumed calling .hide() on an element would set the CSS attribute "visibility: hidden" rather than "display: none"

>That has the same ergonomics as the jQuery selector

Nitpick: This crashes if #element doesn't exist, while the jQuery one does not. Also, the jQuery selector is a tiny bit more powerful (:even, :odd).

IMHO, jQuery is good for what it's built for - a nicer interface than vanilla - but the main use case is much less needed now that frameworks exist.

The same power exists, again a bit longer, :nth-of-type(odd).
A but fugly, ?. helps - document.querySelector('#element')?.style?.SetPropery('display', 'none')
I don't know if that's such a good nitpick in practice. I want my code to crash if my assumptions aren't true - especially if I'm in the process of developing the code, I want to see big red errors and stack traces that point directly to the line that failed.

If it's meant to be the case that the element may or may not be present, then I'd much rather see an explicit check for that, than assume one thing and find out another later.

jQuery was great in its time and still has some places where it can be a good tool for the job, but it isn't used less now because people like writing the longer form of Javascript; it's used less now because for many projects people are using frontend frameworks that let you operate at a higher level altogether.
Does your IDE autocomplete the jQuery code though? I'd imagine it wouldn't. But it would for the native code.
It sure does.

But I still prefer vanilla or anything but jq

but see now you are reliant on jQuery and need to figure out how to load that first.

with vanilla, it would be just typing a bunch of extra properties.

There are fewer and fewer people who know jquery, so while this might be convenient for you or me, this is just more cognitive overhead for programmers who don't know jquery. There are multiple ways to hide an element, and what does `hide()` do? Some future programmer will need to look this up, and every other jquery method they stumble across.

The main problem I have with jquery though is there's no convention for event binding, so there is literally no way to know if an element depends on a jquery event handler without grepping the js for every class, id, and data selector on the object. Even that doesn't always help. This makes it almost impossible to remove jquery from a project without breaking it.

Alpine or stimulus do a much better job of filling the event handling holes that still exist vanilla js. Dom traversal/manipulation in vanilla js is good enough, even if it isn't 100% as good as jquery.

On Alpine...

I have had such a positive and lovely experience with it. It's the reactivity I've always wanted; ie plays nicely with VanillaJS without imposing a complex build process.

I am not against jQuery but if it's just verbosity then it's quite easy to:

const $ = document.querySelectorAll.bind(document)

Then later:

$('#element').whatever

I used to be a big proponent of jQuery especially in the heyday of shims and browser hacks, but in the last few years I find it often gets in the way of what I'm trying to do. Now that the native browser APIs are maturing and relatively consistent, having direct access to the objects and their properties is simply more predictable than having to second-guess a layer of abstraction that does the same job but differently.

I have to remember, what does jQuery's .hide do again? It doesn't just set display to none or visibility hidden. Give it a duration, and it will use the style attribute to manipulate the display, width, height, opacity, padding, margin, etc. Then it leaves some style properties behind. Ugh. Do I really want to do all that stuff? Do I really want to build my UI framework around jQuery so I can avoid annoying transition artefacts?

Not hating on jQuery. Just my own experience. I used to feel liberated when using it because browser APIs were so terrible but now I feel encumbered if it's included as a dependency on a project I'm forced to work with, because it does so much black box magic. If you avoid certain things and stick to what it does well then it's not bad, but then there's no point using it because what it does well is no longer a pain point in browser APIs.

For me the main thing it excelled at was DOM selection and manipulation. Native does that just as well now. The secondary benefit was animation, which these days native CSS can go a long way without excess verbosity, and if you really need a more feature rich animation library I've not come across any better than Greensock for getting the job done, even if it does have a paid tier, though I am sure there are dozens of other libraries equally suited for animation, the point is that is not jQuery's strength either.

Anyway circling back to what you were saying, efficiency-wise, for any complex animations jQuery isn't the best tool for the job. For DOM manipulation native can be just as easy with some sugar. It can do a lot of unexpected and hidden things most people aren't aware are happening, so many bugs and time wasted realising jQuery was messing with style attributes that break an otherwise well designed layout.

I would rather write a few characters more code or a couple of lines more to have direct control over what's actually happening. That seems more efficient to me.

Edit: Ok on reflection I guess I am against jQuery, but I don't hate it. Using it these days just feels like trying to figure out how to get it to do what I want to the underlying APIs, when I could more easily and predictably just be manipulating the APIs directly.

These days it seems like you don't touch DOM yourself anymore because it's all about virtual DOM that is managed by the framework of choice, which is probably ReactJS.
Even easier:

  export const hideElementById = (elementId) => {
    document.getElementById(`#${elementId}`).style.display = 'none'
  };
Or perhaps

  export const toggleElementById = (elementId) => {
    const element = document.getElementById(`#${elementId}`);

    const newDisplayValue = element.style.display === 'none' ? 'block' : 'none';

    element.style.display = newDisplayValue;
  };
The more Jq goes out of fashion, the better it becomes, because it means it stops changing and you can rely on it for decades. The other framework that looks interesting is htmx
I'm using HTMX with Flask through revamping a site previously with server side page rendering + AJAX. It is excellent.

Some of the more contrived AJAX to update parts of a page is being replaced by HTMX, some page loads are being replaced. It is working very smoothly and at a vastly higher speed (also, incremental) than redoing everything with React, the other option tabled. I'll certainly be using it more.

The bashing of jQuery comes from junior devs. Of course a VDOM is clearer, more productive (and less performant) however most webapps with a minimum of logic have many legitimate uses of native dom/jquery in addition to the VDOM. And the interaction is perfectly safe as long as you do native DOM in the right lifecycle method (mounted). jQuery is a pleasure to use and give us a lot of power/expressivity. More generally this vague of juniors devs (e.g. CSS-in-JS lobby) are becoming less and less familiar with the concept of CSS/DOM selectors, despite their awesomeness and uniformity both for DOM operations, styling operations and integration tests operations (cypress) BTW a little known fact is that jQuery is not just sugar and cross-browser consistentcy, in fact it push the boundaries of what is possible vs native CSS, see e.g. the reverse direction paradigm shift of https://api.jquery.com/has-selector/ Although its true that augmenting jQuery with a batcher for performance doesn't seems currently possible? https://github.com/wilsonpage/fastdom
I do think that your complaint, while applicable to a lot of websites, is not specifically applicable to GOV.UK. They do everything to use plain HTML (and if possible no Javascript at all, but there are certain pages where Javascript is an absolute must like interactive maps), and they aren't using React but instead a special framework that is designed to minimise Javascript even to novice developers. Basically they've replaced jQuery with plain Javascript since that some older devices they're supporting (which jQuery is a better solution as it's bug-tested and optimised as much as possible) is dead.
(comment deleted)
Not sure you read the submission, but the move away from jQuery was not to move to anything "virtual DOM"/React/similar but rather that the functions provided by jQuery now have vanilla/"native" alternatives.
The main value I found with jQuery was that the more your CSS selectors and jQuery selectors diverged, the more it felt like you were doing the same work twice.

Now I'm curious what the CSS looks like for devs who have only ever known VDOM frameworks. Regular CSS can be pretty bad, particularly on a mature project. Are we talking dumpster fire or three ring circus here?

I think the css quality of newer projects has significantly regressed.
When jQuery was in its prime, stubbornella was a fixture of youtube playlists. One of the feathers in her cap was cutting yahoo's CSS in half, which resonated with a lot of us. CSS has been problematic for a long time.

I used to hate code generators because the code quality was always so bad that if a midlevel or senior dev was writing code like that I'd be talking to our manager about firing them, and for a junior dev we'd be talking about more intensive mentoring or even a PIP.

Once Sass introduced SCSS, that was the first code generator I ever met that actually impressed me, and Less is very close. The default CSS out of it looked very much like the sort of CSS you would expect from a project after someone had already gone through and cleaned up all of the cliched failure modes for medium sized projects. It felt like having a fast forward button. Still one of the fastest 'sells' for me, and I do quite a lot of technology selection for projects.

Not that it's perfect. Poorly written mixins/functions can generate way more CSS per call than is necessary, and I have a team of overbooked people that I need to sell on prioritizing fixing this sort of thing and I just can't find the bandwidth because there are always 2 more pressing issues I need to talk to them about. I can't squeeze blood from stone, and I can only ask for personal favors about as frequently as I can grant them, modulo any turnover - which has become a problem. Turns out if I take a shine to you, you're also really easy to hire somewhere else.

(comment deleted)
CSS is too much as well, client XSLT to XHTML is good enough for any reasonable website.
Agreed. So far it’s -4 karma for me.

There must be a grain of truth in there … somewhere. Nah, just an inconvenient truth.

There's almost no point talking about javascript on HN with the amount of anti JS & anti framework rhetoric that happens here
There is also excessive praise for Gov UK design system that takes up half of the vertical space with cookie banner, flash messages, and navigation bar. It has so much useless negative space.

I would give it 5 marks out of 10. It’s decent but not a bastion of good design.

Maybe not design but I would say it is a bastion of usability.
I prefer USWDS for usability: https://designsystem.digital.gov/

Gov UK design system is poorly usable. From color use to disorganized, scattered layout; it’s put together with haste and not much thought.

What it’s good at is looking sexy and minimal which captivates a lot of people.

While I haven't experienced USWDS deeply, that's kind of a problem in itself. A good design that doesn't get deployed is just that - a design. Gov.UK might not be pretty but it's consistent across different ministries, departments and instrumentalities which helps tremendously, but US government websites, even if restricted to the federal level, is a mess that I would prefer to hold my tongue at the inconsistency. What is GAO's plans to deploy them at least at a federal level? Is there even a plan? By the way, it's not solely Gov.UK which has this level of consistency (Singapore comes to my mind) so it's not a unique property.
jQuery isn't a framework though (that's half of why I like(d) it). Or are you talking about the number of lunatics on both sides of the argument crowding out everybody else?
I've used jQuery at 2 of the 3 companies I worked for. It can take you very far. Frankly some of the critical features, like making selecting element easier/shorter, should have been ported into JavaScript long ago. I think jQuery is still around largely because it makes, otherwise vanilla, JavaScript easier to use.
jQuery is still around because it's hard to get rid of. Think of all those WordPress websites that use themes, which have jQuery in it. Who is brave enough to remove jQuery?
jQuery never did make the migration to being packaged/delivered as a modern (i.e. post-2015) JavaScript module. This precludes it from being used in a lot of modern JavaScript workflows.

No matter what the library itself provides, to use it you have to go back to working like how developers in 2014 and before used to work with JavaScript, so that's a very real consideration that the "I still like to use jQuery" folks never mention. Are they writing all of their code as pre-2015 'classic' JavasScript as well?

(comment deleted)
I don't mind so much gov.uk using jQuery, but I noticed recently that the UK government's 'parliamentlive.tv' has a dependency on jQuery loaded from Google's CDN, when there was a Google outage in the country I live in (I think it was something to do with routing on Vodafone's side, rather than an actual Google outage).

I see that's now removed, but Recaptcha is still there. The site works without it, but it seems a bit odd to me that by default, my data is shared by my government with a third party company when I want to participate in democracy online.

> It really begs the question: Do we really need Ergonomy today? That's a question that GOV.UK has answered with a resounding "no".
I don't know if you've ever used gov.uk, but I have literally no complaints about it (other than a few content-level ones, which the web design team can't help with). It's honestly a brilliant site.
Bravo gov.uk, the design/web team do a fantastic job. I'd be the first on the bash-the-government bandwagon but their work is exemplary. If they can work with modern js alone and still be compatible to people on Safari 9 and IE11 then respect to them!
AFAIK (I'm not a front-end dev but tried some) vanilla JavaScript has much of the things jQuery provided built-in nowadays yet they look much longer.

Now as JavaScript accumulated a lot of legacy stuff only kept for compatibility + also numerous verbally/syntactically sub-elegant APIs IMHO it is time to design a language which would simply be "better JavaScript" - clean, modern and elegant yet have no fundamental differences so it would be very easy to transpile by just string replace/mapping, essentially just a lightweight "syntactic sugar+discipline" layer. Then it can be integrated in browsers directly.

> design a language which would simply be "better JavaScript" - clean, modern and elegant yet have no fundamental differences

JS' problem is that it is fundamentally not "clean, modern and elegant". It was designed in a couple of days. And all the greatness that's added to it nowadays is done in a much better design process than at it's inception, yet some choices made at it's inception can never be reversed.

I've written some Elm and think it is phenomenal at being a better JS; but it fundamentally very different. Rotten fundamentals are notoriously hard to fix; especially when a lot has been built on top and needs to keep running.

AFAIK Elm can not be considered "a better JavaScript" because it not only is fundamentally different, it also is not fully self-sufficient - in many cases you have to resort to JavaScript pieces while engineering an Elm app.
Same C programmers sometimes use assembly. The abstraction is leaky.

I agree it's not a clean superset like TS is, but for the app I wrote I did not have to use any JS except in instantiating the app (3 lines iirc).

The future will probably be that anything complicated enough to require frameworks like React will eventually move to web assembly, then you are free to use a newer language or compiler which strips out legacy mistakes and old sites can keep shipping their binary which will always work. Already a few of the complex web apps have become webasm.
Most developers don't seem to understand that jQuery was not just a wrapper for browser compatability. Yes, we do have all that nice functionality in a modern browser nowadays but compared to jQuery it just not as elegant. jQuery still has a place.
And that place is? Not saying I disagree, this just feels like an incomplete thought.
You are correct sir. I was trying to keep myself going on a rant. I think if you want to avoid large frameworks/build pipelines and the ugly mess that Web APIs are then jQuery fits perfectly. I have tried and failed many times writing vanilla JS for some smaller projects but always end up over budget and with code ending up looking like a worse version of jQuery. Only if you have large enough visitor count and team then using vanilla API makes practical sense because you might save couple GBs of web traffic and that is nice to see.
I love jQuery like I love a roll of duct tape. I'll use it for anything and everything but I also don't mind if a commercial jet would not like to showcase it.
I am all for dropping jQuery. But...

Unless this team perfectly did a 1:1 replacement of jQuery calls with equivalent native JS functions, this isn't "removing a 30KB dependency reduced blocking time by 11%."

It's "we rewrote our JS and it reduced blocking time"

There's only a small amount of JavaScript used on GOV.UK and everything degrades gracefully.
Talking to developers sometimes feels like hitting the same wall when I talk to people about whether putting all of your money into a house is a sound investment strategy.

There's a lot of willful blindness about cost structures. If it were just one or two people you might conclude that folks are trying to sweep things under the rug, and when I was just starting out I did feel that way. But it's so consistent that I often end up bonding with people who don't feel that way, without putting Dunbar's Number into any sort of danger.

One of the hardest "Code smell" issues I've had to contend with is the habit of people to spread out problems so thin that you can no longer see them, because they're everywhere. Like being in a room with a bad smell, eventually you can't detect it without a major change of perspective. Even though everyone new who comes in starts with, "what is that smell?"

11% of your blocking time on a library could be a perfectly reasonable *budget*. The mistake is not having a goal, or assuming the goal is zero. Zero is dumb, because if that's your target then we'd be talking a static HTML page and then why are they paying you? So what's your real budget? And given that budget, what's a reasonable proportion for different concerns? 1/9th spent on a library is probably a bargain.

Stuck out to me too, but the article is wrong, they didn't "reduce blocking time" by 11%, they reduced how long it takes to complete "JS Long Tasks" by 11% (63ms).

They do claim a "reduction in JS size" on all JS apps "between 31% and 49%."