You might not need jQuery
youmightnotneedjquery.com
youmightnotneedjquery.com
One of the biggest benefits jQuery introduces is the concept of treating single selections and multiple selections identically. While using jQuery, I can emit a $(".class").hide() call, which will apply to all elements with the matching class. Simple and elegant.
However, using native JS as the page suggests, I will need to construct a loop within my function, especially if I'm using the DOM supported getElementsByClassName method, returns a pseudo-array of DOM nodes which don't have the style method available on them. You'll notice the examples already assume a selected element and leave much of this heavy lifting out.
Furthermore, jQuery offers the selection simplicities of Sizzle (ie: "#div .container .item). To do the same selection process in vanilla JS, I'll need to nest 2 getElementsByClassName functions in a getElementByID function, and return the concatenated results from each potential .container. That is to say nothing of more complex selectors.
So yes, if you're addressing the absolute simplest form of selection, this works, but otherwise I don't think it's really presenting the situation honestly.
IE9 and later also support a native each. You are correct however that you'd have to use Array.prototype.each.call, because the NodeList is not a real array.
Good SO discussion on this topic: http://stackoverflow.com/questions/11503534/jquery-vs-docume...
The one I hate most is that qSA returns Yet Another JavaScript Collection That Is A Lot Like An Array But Isn't An Array And Therefore Doesn't Have Any Of The Nice Methods(TM). Yes, you're going to have to iterate over the thing using an index in a loop.
There's others:
http://ejohn.org/blog/thoughts-on-queryselectorall/
I'm really not sure how the standards-makers got this so terribly wrong given that the libraries had already started to solve the problem.
http://dom.spec.whatwg.org/#elements
But AFAICT isn't implemented anywhere, which makes it not that useful. Perhaps a polyfill could be done.
Array.prototype.slice.call(document.querySelectorAll('.myClass'), 0);
Or if you want to abstract that into a utility function: function qsa(sel) {
return Array.prototype.slice.call(document.querySelectorAll(sel), 0);
}
qsa('.myClass'); // Returns array of elementsAdd a few more helper functions, separate it all out to its own js file, reuse the js file in other projects, and soon people will complain about the bloated js file you keep using in your projects.
Man, I really do enjoy my chosen line of work. It creates such fun things to debate over.
However, your Sizzle example is covered by document.querySelectorAll: https://developer.mozilla.org/en-US/docs/Web/API/DocumentFra...
Since a library is written once and used in many different places, it's worth going to a little more effort to make it more flexible.
You don't really need jQuery for that, though. You just need a forEach-like function that works with NodeLists. This is easily implemented in three lines of JavaScript.
> Furthermore, jQuery offers the selection simplicities of Sizzle (ie: "#div .container .item). To do the same selection process in vanilla JS, I'll need to nest 2 getElementsByClassName functions in a getElementByID function, and return the concatenated results from each potential .container. That is to say nothing of more complex selectors.
Not since IE8. These days, you can just do document.querySelectorAll('#div .container .item'). For most common selectors like the one you showed, Sizzle ends up delegating to this method anyway. You only need Sizzle for selectors that cannot be expressed in CSS (e.g. "select a UL with only one child", which would require the CSS4 ! marker).
// Using underscore/lo-dash and ES6.
_.forEach(document.querySelectorAll('.class'), elem => elem.hidden = true);
// Building reusable utility functions
function forEachSelector(sel, cb) { _.forEach(document.querySelectorAll(sel), cb); }
function hideElement(el) { el.hidden = true; }
forEachSelector('.class', hideElement);
Of course, there is the danger of ending up with homegrown jQuery that is less well tested and less well thought out. Perhaps there is a place for a small JS library that works with native DOM elements, in the same non-invasive way lo-dash and underscore work with data structures.The problem with jQuery is that it's an all-or-nothing approach. The way it wraps native DOM nodes means it keeps trying to pull you back to using its inbuilt utility methods.
Not true at all. You can do a custom build and leave out things you don't need. You can even leave out stuff you DO need and replace with your own simpler shim. See the README file.
The APIs seem to be designed with the assumption that all your code will be using jQuery. For example converting a wrapped node to a native DOM node requires an extra call that, in my opinion, is ugly: $('.something').get(0); and could be considered to be an anti-pattern.
I don't think this is a bad thing. jQuery does a good job at providing a DSL that replaces native DOM access. But if you want a library instead of a framework its strongly opinionated style can be off-putting.
Again, not true. For example, the `this` in an event handler is the actual DOM element, not a jQuery object. Whether you handle that directly with DOM methods or wrap it with `$(this)` is up to you. Many people prefer the latter but the former is often smaller and prettier.
> For example converting a wrapped node to a native DOM node requires an extra call that, in my opinion, is ugly: $('.something').get(0); and could be considered to be an anti-pattern.
How common is that, really? Your example assumes a single element with that class name. Why not chain a jQuery method behind it and handle the 0 or N cases as well?
Just because jQuery is loaded doesn't mean you have to use it for everything on the page.
The premise of the examples list seems a bit disingenuous.
Very few of these things take into account the full convenience of jQuery. It's much more than saving a couple lines of code or knowing the native way to accomplish the most basic version of a task. jQuery's real benefit is preserving simplicity as your needs grow more complex.
Right off the bat I feel like the getJSON[1] example is a bit simplistic. Almost anyone using ajax needs to serialize data, handle errors, prevent caching, etc. jQuery has thought about all this[2].
Don't get me wrong -- most of my work has been without jQuery, but that means I know exactly how much work it is.
The Good:
The format is a nice way to show people (who really don't know otherwise) the native JS plumbing.
"The number of people who don't know that jQuery != Javascript is too damn high". So to help combat that, I really appreciate the idea behind this site.
It's great to show side-by-side how jQuery isn't "magic", since many people seem to learn jQuery these days without even knowing the first thing about Javascript, but I just think it should be presented with a slightly different premise.
[1]: http://youmightnotneedjquery.com/#json -- side note, why did they set the handler after the `send`? It seems like that could cause problems if the result was returnable quickly, such as from cache, though I haven't tested it.
[2]: http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
Edit: it actually literally says it's for library developers.
False:
- CSS browser prefixes are automatically inserted by jQuery
- Many jQuery selectors don't exist in the CSS selector specification
- Looks really really ugly and that makes it hard to read for you and other coders.
var pairs = $(".form").not(".old").serialize();
/* without jQuery */
var pairs = [].slice.call(document.querySelectorAll(".form"));
var data = forms.filter(function(ele){
return /\bold\b/.test(ele.className);
}).map(function(ele){
var form = ele.querySelectorAll("select, input, textarea");
var pairs = [].slice.call(form).map(function(subele){
// maybe if subele.type === "select"
// but I got tired of writing this example
// but that's the point anyway
return subele.name + ":" + (subele.value || "") + ";";
});
return pairs
}).join("").replace(/;$/, "");
So be kind with your co-workers, use jQuery. Even my 5 year old android can run jQuery without freezing the built-in browser.This point might have been better made if you hadn't intentionally structured it to be as unreadable as possible, and also shoved in a few lines of comments to pad it out and make it look bigger than it needs to be. Not a very honest example at all, considering native JS can be as readable as you want to make it.
> So be kind with your co-workers, use jQuery. Even my 5 year old android can run jQuery without freezing the built-in browser.
My co-workers can read and write native JS with or without jQuery as it is, why is it being _kind_ to avoid writing in the style of the native language?
$(".enemy").after('<div class="crash">').remove()
Without jQuery: var enemies = document.querySelectorAll(".enemy")
for (var i = 0; i < enemies.length; i++) {
var div = document.createElement("div");
div.className = "crash";
enemies[i].parentNode.insertBefore(div, enemies[i]);
enemies[i].parentNode.removeChild(enemies[i]);
}
Here the last one is comprehensible but even then, it takes longer for a programmer who just found it to figure out what it is doing; and, caring about other peoples time (and future yours) can be referred as 'kind'.Can you make an honest version of the example? (genuine interest, no sarcasm)
Second, the many debates that have happened on HN it is quite clear there is no set "style" in coding Javascript. My style of coding in the native language may be quite different than your style. Therefore, if you use your style in a verbose manner because you choose to not use jQuery and I use my style in a more concise manner because I am using jQuery, it could be said the more concise method is kinder to someone following behind.
But like all things considered a style, opinions vary.
Do not reinvent the wheel to solve problems that can't be solved in much cleaner and nicer ways. Managing dependencies can be annoying, but we all bite the bullet for a very good reason, because reusing solid well tested code is a good thing.
But that isn't the case here. When something like jQuery comes along, hiding so many gory details, and has been tested to death both in development and in production use all over the world, we are all better off because we remove so much failure surface area from our code.
What if you need several polyfills? Drop them in too. You should always know what browser feature you are using. The same argument goes for using libraries. What if you need more than jQuery? Bring them in too. There are asset pipelines and/or pure front end packaging solutions like AMD to help you. What's the problem?
Why? If I just drop jQuery in and treat that as my API baseline, what do I lose? A little performance, a few hundred kilobytes' download (almost certainly cached from a CDN anyway). And it frees me up from remembering a bunch of corner cases and keeping track of a bunch of implementation details, letting me focus my attention on more important things.
You seem to be laying much of the "mediocre experience" on jQuery in this case. I would like to know why you feel this way. Seems to me that loading in polyfills for every browser inconsistency can lead you to the same problems you feel exist with jQuery.
I don't just care what my browser is doing, I care what all of them are doing; which often leads to using jQuery. Depends on the project and the number of expected browsers involved.
Polyfills are things you learn once and drop in once? So is jQuery.
What if the best experience to be provided suggests using jQuery? Would you use it?
All in all, to use or not use jQuery often depends on the project. If it fits, use it; if it doesn't, don't use it.
The problem is that this shuts you out of a lot of hot, emerging markets that can be quite lucrative. You will never work for Google (as a front-end engineer) if you only know JQuery and not the native DOM APIs. Your mobile HTML5 apps will suck and will lose out to native counterparts in the app store. You're at a disadvantage in any competitive web market where people bounce from the website if it's too slow (there are more of these than you think).
If you're willing to limit yourself in this way, sure, go for JQuery. There is still a pretty booming market for Intranet apps or progressive-enhancement mostly-static sites where JQuery is just fine, and it provides a nice productivity boost for those use-cases.
The advantage of polyfills is that they give you flexibility and let you push the edge of technology today, and then they don't become obsolete tomorrow. As the web evolves you just get rid of the polyfill and you already know the latest & greatest of tomorrow. That lets you push into the emerging new markets that can be quite lucrative, at the expense of actually learning the (sometimes hard-to-use) APIs on the bleeding edge.
But for those aspiring to create big things another approach is to find a niche where you can offer something exclusive that people want. Thefacebook offered something that students would have put up with > 1s load times to see that they couldn't reliably get anywhere else. http://en.wikipedia.org/wiki/File:Thefacebook.png
You silly goose!
For example,
$(el).hide()
is quite more readable than el.style.display = 'none'
. And I'm not even talking about the other advantages. el.hidden = true;
in modern browsers" it is incorrect to use hidden to hide panels in a tabbed dialog, because the tabbed interface is merely a kind of overflow presentation — one could equally well just show all the form controls in one big page with a scrollbar"
It's easily overridden by CSS.
el.style.display = 'none' pretty much works everywhere.
To me, it seems to depend upon what the purpose of hiding/showing the element is in specific cases.
> el.style.display = 'none'
You meant something more like
document.querySelectorAll(el).forEach(function(e) { e.style.display = 'none'; }
and a polyfill for IE8 due to lack of native Array#forEach, right?jQuery rarely dumbly duplicates some native functionnality, as for the example above, most of the time it will diverge in meaningful ways.
As a side note, I know this is totally a matter of taste but "chainable" in the JQuery sense reads to me as "spaghetti generator".
I think this is more important than a side note. The reason jQuery's 'children' or 'find' is way better in my eyes is because of the support for arrays as target and argument, and the possibility to pass the resulting collection to the next command as is.
Going the native route, filtering the children will need an extra loop, doing so on an array of parent elements will also bring an other loop. And we'd have to deal with a Nodelist instead of an array. A 2 command jQuery line would be 5 to 10 lines in native code, every time there is some node tree to filter.
Manipulating collections of DOM elements is such a common case that having to deal with loops every time is just tiring, less readable and more prone to basic errors.
In a way I see it as an anti-spaghetti feature. Less boilerplate, shorter, more concise code with clearer intents.
My side note would be that el.querySelectorAll(selector) is versatile, but not as much as the jQuery find. Telling which cases for which browsers would not work with the native function could be some interview question, but that's not the kind of thing I'd like to remember.
document.getElementById('non-existent').classList; // error
$('#non-existent').addClass('yay'); // hidden bug
I prefer the explicit solution.The sibling comment points out how a function silently failing when given empty value can be deceiptive. I guess your way of seeing it would be also in line with checking valid values before using them.
It's a very sane approach, and it requires more care and attention for each step. I'm not against it, but usually I'm not sure to see a real payoff for very conservative programming in front end DOM manipulation, I tend to prefer taking some performance hit and ignore the nitty gritty details as well as the small errors, as long as it can be recovered at a higher level.
There are a lot of ways to skin this poor cat, but at this time they are generally manual and therefore unused. As a result, we try to solve dead code problems as if it is an entirely new challenge.
Dynamic code, and especially code with insufficient test coverage, poses a particular challenge, but again, it is generally possible to instrument code to see if it is ever called by the application.
A personal anecdote: I recently un-jQueried a little piece of code and ended up with only a couple lines of extra code.
Certain parts of jQuery are heavenly and well worth it, but really basic usage doesn't actually save that much. $("#something") instead of document.getElementById("something") is not really buying you much in the way of cross platform-ness or thoroughly debugged code and is hardly reinventing the wheel.
The new-stuff, while great for styling, isn't all that relevant for scripting. nth-child, say, is often (though not always) simply an indexing operation on the return value of querySelectorAll; and in general you don't even want that since usually you have a specific element in mind and have labelled that element with a class to find it.
I don't support IE8 anymore, and use CSS3 liberally in the actual css, yet I can't think of more than a handful of cases I used the selectors from javascript, certainly none of them critical. Do you actually use this?
However, the author goes beyond just selector vs. getElementById().
Does the way the author uses XMLHttpRequest work in other browsers the way it works in IE? I honestly dont even remember anymore.
How about the code for fade? I never even knew the details of this feature. And I'm not sure I want to.
http://www.w3.org/TR/XMLHttpRequest/#interface-xmlhttpreques...
http://msdn.microsoft.com/en-us/library/ie/ms535874(v=vs.85)...
http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdoma...
"to render impotent or deprive of vitality"
Pedantry aside, your point stands, CSS transitions can use the GPU and degrade gracefully.
Sure, but if you use a few libraries that all use a couple features of jQuery you still only need to load jQuery one time and everything just works. You may not care if it only works on the most modern browsers, but someone who uses your library probably will.
or even just document.querySelectorAll("#something")
Probably best to do this within a closure so that you're not hijacking any jQuery instances that may be on the page.
Since I code mostly in clojurescript in my home hours any functional idioms from jQuery I no longer use. A long time ago jresig joked about making an oo form of jQuery. It's not that funny now, as it might be slightly easier to wrap an object based lib for all the various compile down to js languages (typescript, coffeescript, clojurescript, scalajs, etc)
Starting with jQuery's battle-tested event handling code, I trimmed features unnecessary for my widget: event.data, IE7 support, consistent focus events. I replaced jQuery's indispensable descendant selector feature, formerly jQuery.delegate, with a simple conditional in my event handlers. (e.g. Walk parentNode references from event.target, looking for a class name.)
I was left with about 75 lines of code in my DOM abstraction library. I preserved jQuery's tricks for Microsoft's attachEvent and Safari's text nodes. About 15 lines were dedicated to normalizing attributes. My polyfills for preventDefault and stopPropagation were about 10 lines each.
It's amazing how far native DOM has come in recent years.
1) The minified jquery script is ~100kb, for a script that is loaded once per website that's pretty tiny. Especially when you consider the fact that the latency involved with opening the network connection to fetch the file will likely exceed the time required to pull the file down. Once you've initiated the download the difference between pulling down 20kb and 100kb isn't all that much.
2) You can use the google jquery file reference. That means a big % of your site visitors will already have the cached script in memory, and for those that don't the download will be pretty speedy given that it can be fetched from the google domain in the background (while the rest of your site assets are being fetched by the browser).
JQuery has down sides other than size. There is also maintenance, dependency and backwards compatibility issues.
EDIT: Plus it adds a lot of extra syntactic mess, extra () $ and .
As a library author it's becoming more important to think case-by-case -- use raw JS if you just have some simple selections or XHRs, or use Zepto/etc if that covers you, and only depend on jQuery if you really need its richness in your lib.
So in that spirit, I appreciated the article.
Well, Angular has jQuery (lite) built in.
But if it's a library intended for Angular then the library would be built with Angular as a dependency, much like it would be with jQuery.
I don't see a negative with a library being built that has dependencies if it is intended to be used in conjunction with the thing it is depending upon, since in most likelihood a like-minded developer is already using it.
Also, last time I checked jquery uses "querySelectorAll" for that fancy $("selector") syntax, which is slow as hell with every possible browser compared to "getElementBy*". This might not be issue with desktop machines, but you will probably lose most of your mobile users because of that. Jquery does also exposes very dangearous things from the API. For example: most of the time use of css modifying from JS just implies that your UI logic is fundamentally flawed (also, incredibly slow as poking CSS from JS will force full relayout which will make your mobile users throw their devices to wall or leave your site).
Jquery lets people cut corners which will give short term benefits, true. But in long term you are just killing your user experience. And like others said, people mostly use like 1% of the API, which has as easy native browser support.
The flip side of this is that iterating over a querySelectorAll nodelist is significantly faster than iterating over a getElementsBy* nodelist. You really don't want to call .length on a getElementsBy* nodelist, because it's O(N) and has to traverse the full nodelist. .length on a querySelectorAll nodelist is just a field lookup. That means that when you combine the original call with one iteration, you're usually about breaking even with querySelectorAll.
Also, setting CSS properties doesn't for a full relayout; it just sets a dirty bit and the property. Setting CSS properties and then querying the DOM causes a full relayout. Unfortunately JQuery often does the latter in .css, which makes it slow as molasses. You can do direct .style manipulations all you want with very little performance penalty though.
I seriously doubt you ever "checked". You would know that jQuery's selector engine (Sizzle) is optimized and uses getElementBy* when it can. You would also know that every browser has bugs in querySelectorAll, and jQuery's selector engine detects the bugs and routes around the browser bugs.
Not true, and has never been true; maybe you confused jQuery with Zepto? "#id" uses getElementById, ".class" uses getElementsByClassName, more complex selectors go through querySelectorAll, and custom selectors through Sizzle.
> And like others said, people mostly use like 1% of the API, which has as easy native browser support.
Hard to argue with that statistic since it's made up!
This cannot possibly be true. Do you have some data to back it up?
2) In 2014, jQuery feels like it is the wheel reinvented. I'm looking at the jQuery API modules now and here's what I consider jQuery is still useful (as in nontrivial to replicate):
- AJAX (Too many cross-browser differences in XHR/XDR implementations)
- Event delegation (Too many cross-browser differences in what gets triggered/bubble/cancelable)
Most things in jQuery may only save you a couple of keystrokes to a few lines of code. For everything else, you can drop in a small library / polyfill when needed to get back something like $.Deferred or the $.fn.serialize() or $.fn.val(). In fact, there are already many small libraries that aim to do just one thing only and do it well.3) You never need all of jQuery. If you need all of jQuery, you are doing it wrong. I don't even want to look at your giant pile of procedural, chained-20-times-for-every-element hourglass-shaped callback pasta.
4) The plugin ecosystem is horrible. This might have to do with the fact that jQuery doesn't give you any help other than a namespace. Most plugins come with ginormous pile of options and/or very rigid and opaque HTML/CSS structures. Most of them don't come with tests, are extremely buggy and very very hard to tweak.
5) jQuery is extremely slow. Its slowest parts are creating the context because of Sizzle and event delegation. My recent PR for Backbone to make jQuery optional in its View is around 70% faster using all native DOM methods.
6) jQuery was born in 2006, when IE6 still had 70% of market share. jQuery's many layers of smooth-overs come at a very high performance cost, and it doesn't even smooth things over that well. There are still many edge cases in event handling such as triggering a click that bubbles on a detached element on Webkit that jQuery just can't do for you. Shouldn't you aim to provide the best experience for the 50-80% of users out there who are on modern browsers instead of a mediocre experience for 100% of them?
Ignoring the Webkit example and focusing on IE, isn't that what jQuery 2 is for?
Here is his benchmark: http://jsperf.com/backbone-patch-22be8f9/2
It only compares jQuery 1 and the DOM API, no jQuery 2.
TestBaseView: DOM API
TestPaulView: Reduced jQuery usage
TestView: jQueryAlso, this is just one test - wyuenho's claim was for jQ vs. the DOM in general, which is a much broader claim than an unknown subset of functionality.
I don't doubt that native DOM methods are faster than jQ, but I like claims to be backed up by evidence.
The onus is on the person making the claim, not the person trying to verify it.
In my experience, this decision is not as cut and dried as you make it seem. But I don't work for a startup, so take that for what it's worth.
For my use case, Backbone would also have to lose it's jQuery dependency for RESTful model persistence, but maybe that means I should get to work on it and submit a PR :-)
You can the only hard dependency of backbone is underscore.
You don't have to use plugins you know, its not a law.
Much the same; even if jQuery is that much slower it can sometimes provide something that overcomes the slowness factor. It varies from project to project. Especially if the project scope practically requires you to rewrite jQuery from scratch, you might as well use it.
When writing web apps, brevity counts for a lot.
I'm working on a widget that other people will embed on their page. I cannot make assumptions about jQuery being available and I cannot afford to add jQuery as a dependency. Assuming the widget was valuable to you, would you want to add my widget to your page if it included 94kb (jQuery 1.10.2 minified) of JS before my code was even added on top? If you cared about performance, it's highly unlikely you would.
So for that reason I've been working with plain JS for months now. We have browser support back to IE9 (maybe even 8), and our entire codebase is around 25kb minified (gzipped < 6kb). We have one or two collections of utilities, but most of it is application code that would still be there even if we had jQuery as a dependency. All I can say is it is not that big a problem. If you're not sure how to get something to work across browsers, look at the source of jQuery (this website [0] is fantastic for this purpose) or any other library that is well regarded.
But you know what? Most of the time it isn't even a problem. And with modern tools [1][2] and a good test suite, it's not difficult testing across multiple browsers to quickly find issues.
Before even working on this project I decided to go on a self-administered "jQuery diet". I haven't used jQuery in any personal projects [3][4] for at least a year and it's great. It took a little adjusting, but not much. If anything it was a little shocking. I thought I was a good JS dev, but it really opened my eyes to how little I knew about the DOM and other native browser APIs and, honestly, I felt a little ashamed.
Conclusion: sometimes going it alone is the right decision. jQuery is absolutely the right choice in some environments, but it doesn't make it the right choice absolutely
[0] http://james.padolsey.com/jquery/
[1] http://karma-runner.github.io
[2] http://vanamco.com/ghostlab/
Having tools at your disposal is a good thing. Why would you type out four sentences when you can have pages of pre-written content?
If you're creating a simple brochure website for a small business and literally just need to show one hidden element on a click or do something else very simple, there's a legitimate argument to avoid jQuery. It depends on the level of complexity you need.
The web is filled with unnecessary bloat and I'd like to get rid of some of that.
But it doesnt hurt to understand how basic stuff works under the hood of jquery and to know native dom operations. The world is not black and white. Good developers know that, they dont get stuck in discussions whatever jQuery should be used everywhere or nowhere.
And yes, less code, less abstraction, and less requirements are damn good reasons not to do something.
This.
A thing that the examples on that site did not address is the power of jQuery("element.selector") selects a "bucket"/array of elements and functions are executed on each element in that bucket.
So now you may have to add that functionality into your library. Then there is always a non-logical browser inconsistency that needs to be taken care of. Then you need to write tests. Time used for managing the library piles up very fast.
I usually drop animations and the event shortcut functions. These seem pretty junky to me anyway.
I understand the visceral opposition, but once you start writing a fallback to support some browser (something to support IE or FF or Safari or Chrome ...) you might as well use the battle-tested solution (and write your own thing if you find performance to be unacceptable and trace the bottleneck to jQuery)
There isn't a one-size-fits-all answer for this, but you should have some idea of what your traffic breakdown by browser is, and ideally what your cost in conversion rate is for each additional ms of latency (this varies by industry). I don't remember offhand what the cost per byte in latency is, but IIRC we measured something like 1ms per 1K bytes at Google (this would work out to a 1 MBps = 10Mbps connection, which seems around right for typical cable/residential fiber households these days).
As far as latency is concerned, I hear you and that makes sense, but the things I'm talking about are not very big, so the latency gain isn't going to matter much for our purposes.
Yeah, we definitely look at the analytics. But even if it the old browser users are sub 1 percentage point, I see the number and think, "I could take this 5 line polyfill out, but then these 1000 uniques wouldn't work."
And I just don't have the heart...
I thought that the issue in this thread is JQuery, which is a layer on top of the modern browser API (probably because the modern browser API didn't exist when it was created, and is in a large part a native implementation of JQuery functionality), and so incurs the cost of all its legacy compatibility support even if you don't need it.
Take a look at the caniuse tables for common functionality in JQuery:
http://caniuse.com/#search=classList
http://caniuse.com/#search=querySelector
http://caniuse.com/#feat=css-transitions
http://caniuse.com/#feat=getcomputedstyle
http://kangax.github.io/es5-compat-table/#Array.prototype.fo...
For anyone else, just use jQuery.
git fork jquery
git branch "fix-performance-issue-at-<feature>"
git commit ...
git pushWhen you improve a slow implementation, it should be tested against that existing dizzying array of use cases.
I will lose a beautiful API with a simple, terse and familiar syntax. I will have to work with an ugly, inconsistent and loquacious API, which has no guarantee of being cross-browser (or accounting for various browser quirks).
And for what? I doubt 81 KB would make much difference to 99.9% of my visitors.
As for performance -- it makes sense to rewrite bottlenecks in pure highly-optimized JS. But to write vanilla JS from scratch, without even knowing whether you'd need that performance boost is a pure waste of time.
UPD: it has been pointed out that this webpage is directed at developers of JS libraries. In this case, all these points are valid, but the title, then, seems to be either misleading (as in "link-bait" misleading) or a plain truism.
I decide to call an e-mail address verification as a service API, their library uses jquery 1.8
I decide to call an address verification as a service API, their library uses jquery 1.11
I decide to call a credit card validation as a service API, their library uses jquery 2.0
You go to the e-mail address verification company and say "Do you have a version that supports a newer version of jquery" and they say "yes, also we redesigned our library's interface so if you upgrade you'll have to change all your code..."
But yeah, if you are just writing code for your own site then knock yourself out.
http://caniuse.com/#search=classList
It used to be that the first thing I'd reach for when building a prototype was JQuery off a CDN, but now I find that more and more of what I use JQuery for is built into the browser, and in my last few prototypes I've just stopped including it at all because I don't need it.
"Similar things" as in hackathons for fun, or hackathons structured to test out different approaches and tech?
Compatibility issues still exist.
Let's say we know a consultant, let's call him Bob, who works on client projects. He needs to implement new features fast, and does not want to worry about low level stuff. Once he's done with a project, he moves on to another.
Then, we meet a JS-framework developer, let's call her Alice. She has to weight every line of code she writes because her decision can have have a huge impact on thousand of developers using her stuff. She needs to understand a lot of low-level details in order to make good decisions and ship rock solid stuff.
Now, both Bob and Alice have to decide whether they need to include jQuery in their projects or not. Heck, they need to justify their decisions to their teams / managers.
What's Bob going to say? He will start thinking about what will happen if he does not include jQuery to his project. Well, he will have to implement some of the low-level stuff by himself, and later maintain the code. Probably, in a month he's going to be working on another project and will have to copy & paste the same stuff over. And if there was a bug? Is he going to update all the previous projects he is not getting paid for anymore? If he's smart, he's going to say: we'll take jQuery, as it provides a nice, stable, robust and battle-hardened API. We're going to move faster if we use it, as we don't want to reinvent the wheel.
What about Alice? She will probably have to consider introducing a new dependency to her framework. Is it OK to add those additional hundreds of lines of jQuery code to an already large codebase? Is she going to be able to provide a consistent experience between different (and future) versions of jQuery? Is the core of her application going to rely on an external tool, even if it is rock-solid and lose the potential to make low-level optimizations and have full control? Maybe, she's going to say: well, I'm going to identify the elements that need some of jQuery's stuff and implement it by myself. She will be taking the time and effort needed to test it well and be sure that it works across different platforms.
At the end of the day, both will have made the right decision, even if in absolute terms they took the exact opposite action.
Software engineering is about making decisions, in a given context and moment, for a given purpose. As software engineers, we should not generalize about some of the decisions people have to make. There is no one single truth, it all depends on a variety of variables and factors. Let's be Bob and Alice, be smart and make the best decisions for our projects.
My project currently depends on libraries which in turn have dependencies on mutually exclusive versions of jQuery, so we conditionally load a whole second copy some of the time. I've been meaning to fix the libraries that require older jQuery so we can fix this, but the bugs run deep, the libraries are pretty unmaintainable, and I'm under pressure to keep shipping features.
The real problem with not using jQuery is that all of the collective knowledge we have about browser inconsistencies is encapsulated in jQuery. When you run into this, and Google it, you'll find a million StackOverflow answers telling you to use jQuery, and if you get lucky a blog post from 2007 that actually answers your question. The result is that you end up spending time reverse-engineering jQuery to get your thing working.
To be clear, in my case the tradeoff was worth it (the code for my entire widget including the bits of library I had to write is smaller than jQuery), but it's not a tradeoff I would make unless I had a good reason.
FadeIn:
element.style.transition = 'opacity 400ms ease-in-out';
element.style.opacity = 1;
Each & filter (this also applies to people's complaints about browser methods not working on collections): [].forEach.call(document.querySelectorAll(selector), function(el) { ... })
The native versions also usually run several times faster than the JQuery versions, which is the main reason to use them. This meme that you can't build performant, jank-free HTML5 mobile apps? It's largely because of JS libraries and developers that don't know which operations are fast and which are slow.I'll also plug my colleague's autogenerated index of the HTML5 APIs:
And ultimately, why not? jQuery works, has a wide base of users, etc. Sure your trivial Js might not need jQuery features now, but as you add more dynamic behaviour, at some point you'll wish you had just used it to begin with.
A better message might be: make sure you know what the underlying javascript looks like, because there are a lot of people helpless without jQuery.
PLUG: if you're bored of jQuery, try Dojo. Far more power, in a less intrusive form, IMO.
Also, jQuery is not trival to use in conjunction with other js libs (Dojo) as namespacing proponents claim. It's not like you just include both & they don't interfere. You have to follow a specific initialization pattern.
Zillions of people do it anyway, so it's not like you won't have lots of company.
Unless the headline was changed by the mods, there's no hyperbole or sensationalism here. You might not need jQuery. Obviously. But many of these reactions don't belong here, they belong in a post titled You don't need jQuery, which would of course deserve to be downvoted to hell.
Obviously you don't need to pull in jQuery for every little twenty-line gizmo you publish on github. But don't you dare brag about this or you'll offend the sensibilities of those who've invested all their mental energy into learning jQuery and therefore remained ignorant of how browsers actually work.
The beauty of jQuery is working with the DOM as collections. I don't see how it's better to have all these helpers like `nextSibling`, `matches`, or `filter` thrown in the global scope or having to remember is this a real array? jQuery already built solutions for these common problems and exposes a nice API.
If all I need is querying the DOM and I don't have to support IE8 then I may consider using vanilla JavaScript, or building my own simple jQuery-esque library. But you'd start with some structure, and expose your own API. I re-invented the DOM wheel many times, and from my experience, although the code is smaller, I end up going back to jQuery because it covers some edge case or provides something else I need, like AJAX, or nice events, etc.
But building your own DOM library is a good educational challenge. Querying the DOM is all about collections, and if you don't need IE8 then you can use all the ES5 arrays methods, like map and filter. It all boils down to four functions to work with collections: toArray, unique, flatten and query. And four functions to work with the DOM: compose, join, dot, loop. See here for an example http://jsbin.com/EgIkega/1/edit. The article is more about techniques to build your own jQuery-like library; I wouldn't use "el.nextElementSibling || nextElementSibling(el)" when I can use "$(el).next()". C'mon!
Conclusion, you are probably going to use jQuery anyway.
The amazing part of jQuery still to this day, beyond the selectors (which can now be replaced yes), is the plugin system. Just like Python, there is a plugin for everything and if you don't like them or there isn't one, developers can easily make one and share it with the world and it just works (tm). It is the most easily pluggable javascript library. It creates a baseplane that developers can be more efficient in. Everybody tries to replace the jQuery selectors, animation etc but they miss that jQuery is a platform and a pluggable one at that. It is responsible for tons of productivity.
Use jQuery please.
Rewriting jQuery methods with vanilla js usually turns out to be a hack job that is buggy and ugly. Just use jQuery.
Even worse: suppose you build a product with the approach you recommend, it's very successful, and then your sales team makes a major sale to a stodgy old bank that still uses IE7. Or maybe you just never make the sale because you don't support the browser they use.
OK, let's say we should all turn away money from IE7 users because it's insecure and old. For OP's strategy to work, we have to assume all browsers we care about will be compatible going forward. I think this is a very unsafe assumption to make. While one small incompatibility would only be a minor annoyance, once you have more than a handful of these, a compatibility layer like jQuery again looks very nice.
And none of this even speaks to the fact that the jQuery implementation in the source article is generally at least as short and readable as the alternative, or that most people are more familiar with the jQuery version.
The only reason I can think of for dumping jQuery is maybe speed optimization, and even in that case, well-implemented jQuery should be no slower than the native speed plus the cost of a function call. If it's slow and you want to optimize something, why not optimize/bug-fix jQuery itself and help everyone, not just your one project?
People don't use Ruby because C's standard library works differently across different platforms.
This isn't about "rewriting jQuery methods with vanilla js". It's about using the built-in, native, vastly more performant methods that come standard on modern browsers.
But anyway, writing code in any 'lower' layer is very educational.
I wouldn't call myself "old school," "hard core" or anything like it, but I just don't see what's so difficult about--or wrong with--replacing any library with "ad hoc" code that accomplishes a small subset of the library's functionality if the majority of the library's purpose is to provide that small subset. "Small", of course, is relative and context dependent.
- Setting or getting css attributes - Querying the DOM - Manipulating and walking through arrays
Each of these features can be replicated with fewer than 10 lines of code.
I could be convinced of the latter but not the former.
For Offline, PACE, Odometer, Tether, and many of our other OS projects (http://github.hubspot.com), we chose not to depend on jQuery because it means our libraries can be smaller and more people can use them.
We're happy and proud to use jQuery when building an application. As many other commenters have noticed, it can be extremely useful at reducing code complexity—and let's just say it: it can make it more enjoyable to write front-end code!
I totally agree, but not everyone lives in a post-IE8 world. It's as much as 10% of our traffic on some sites and several big clients use it.
You're average web app perhaps doesn't need the latest Ruby/Python/PHP framework, or perhaps it you can write it without the framework. Or perhaps you can a compiled as opposed to interpreted language because that would be faster. OR maybe you can use something that is even faster, like perhaps Assembler! Fuck it write machine code if speed is the most important thing.
Do you know why you don't? Cause writing Assembler or machine code sucks. You lose very little in load time by including a minified version of jQuery, while you gain an enormous amount of ease of use and readability. Also it'll be more fun.
Just include the jQuery and be done with it.
How many lines of code are actually needed to give you selectors and the most common DOM manipulations?
How many lines of code are in jQuery?
Is there anything which would not be in selectors + common manipulations that you need, and which only jQuery can provide?
But then that becomes a whole another endeavor - how much load time will be saved by only using the parts you need, and how long will it take to figure out what you need and what you dont? It's all about return on investment. What do I need now, what won't I ever use, and what might I use later. It becomes more work to save, what, 1/4 second? Maybe a bit more on mobile. It isn't worth the trouble.
The whole obsession over the load time of jquery feels like an exercise in OCD.
http://robertnyman.com/2008/10/16/beware-of-javascript-semic...
I've also started using Angular.js quite a bit and have found most of the time, it requires less code than jQuery. It also has its own subset of jQuery "jqLite" which has a much smaller footprint so your app doesn't need to rely on that jQuery dependency.
You might be able to use jQuery 2.x instead, which is smaller, faster, and drops support for IE8 and below.
http://code.jquery.com/jquery-1.11.0.js
Notice the rbuggyQSA variable.
Also check out Quirksmode:
But I still support the case that not every plugin/library developer should depend on jQuery by default, even if it is not necessary.
[1] https://github.com/WebReflection/ie8 [2] https://github.com/es-shims/es5-shim [3] https://github.com/eligrey/classList.js
Now about this site itself. This is a great idea getting people to use and understand native methods, but please also understand that native methods aren't always necessarily the most efficient choice. There are a few of parts of this site I think send the wrong message. Don't get me wrong, I think this is great, but sometimes native methods are no better than jQuery's.
The first one being jQuery's each method. It is a known fact that jQuery's each method is extremely slow, it works, but from a optimisation perspective native ways of looping an array are always the fastest and most efficient.
The alternative given for a jQuery.each statement is the IE9+ supported Array.prototype.forEach — now you'd think this would be faster right? It's actually still not as performant as it could be. As this jsPerf set of benchmarks shows is that a for loop is the most performant option: http://jsperf.com/foreach-vs-jquery-each/38 — it might not be as pretty as jQuery.each or Array.prototype.forEach, but heck, it's a whole lot faster than the alternatives.
The second being the use of querySelectorAll (which is awesome btw). It has similar capabilities to that of jQuery's native wrapper for querying, it looks just as nice, but once again the performance isn't all that great. Looking through multiple jsPerf benchmarks, querySelectorAll is rarely the best option to use in most cases. This is an example of one: http://jsperf.com/queryselectorall-vs-getelementsbytagname/4... — if your selector is extremely complicated, think to yourself, how can I make this easier to write? Do I need to query a chain of five classes and use CSS3 selectors, or can I just add an ID to the element I want and query it using document.getElementById instead.
Sometimes jQuery is needed though. It saves considerable amounts of time, especially when the budget of a project is tight and timeline is even tighter and you just need to get something out the door as soon as possible. If you have the time to properly build whatever it is you are building, consider spending that extra 15 seconds writing a for loop to iterate over that array or object.
And to those who understand and have taken a look into the internals of how some jQuery methods work like document.ready, you'll appreciate and know just how many different browser quirks the jQuery team have solved for us. There are quite a few methods where jQuery hides the gory details of a sometimes difficult to get right across all browsers feature.
Personally my favourite thing about Javascript is the power of documentFragment: https://developer.mozilla.org/en/docs/Web/API/DocumentFragme... — this is something all developers who use Javascript need to know about. It helps prevent reflowing and redrawing as well as being extremely efficient and fast for modifying and inserting elements into a page.
Over all of this I think we all need to reflect on the state of Javascript. It's a whole lot more powerful and better than it was 10 years ago, but I think because of the likes of jQuery and others, people have become obsessed with pretty code and methods. I know for loops and prototype methods might not be as nice as your one line of jQuery code, but don't take the easy way out, because you'll soon find the longer your Javascript grows in your app/site, the slower it will become.
[1]: http://sailsjs.org
i think you mean "know the library but not the DOM and additional HTML5 APIs" - they are after all just native libraries. ES5/6 would be the "language"
Are you saying something different?
So I'm by no means a compilers or js engine expert, and this really is an honest to god question and not an attempt at sideways criticism.
When I use each, forEach, map, or something like that, I'm usually optimizing for my own readability and to try to create more concise and understandable code (admittedly only for folks comfortable with those paradigms) and not actual raw performance.
Is it the case that Array.prototype.forEach is faster than a for loop for all modern browsers, and could that change with engine optimizations? My wonder there is that it smells like premature optimization while sacrificing readability (again, assuming you think map/forEach/etc is more readable, which might be a huge assumption).
Thoughts?
I think it's just important to be aware of the alternatives and trade-offs using certain methods and knowing when to a 3 line method in place of a one-liner piece of jQuery. On a site I am currently working on I am using jQuery.each, I am modifying elements in the page using jQuery.width and all kinds of other things I normally would advise against in a large application. But the site I am building which is a Wordpress theme uses such little amounts of Javascript that using a more optimal method wouldn't really make much of a different interaction and latency wise.
My point was more-so that there are developers out there using poorer methods even in large-scale applications because that's the only way they know how to do it. Just being aware of what you can do in Javascript can be a beautiful thing and even save your hide in a situation where the page is freezing up when you scroll (an event I recently witnessed occur and had to fix).
In time I do believe native methods and certain implementations will get better. Javascript has evolved quite a lot in the last few years and shows no signs of slowing down.
It is true, however, that array.forEach can theoretically be worse than a hand-written loop - and I think in some cases it currently is. This is due to the fact that a call through Array.forEach might have to enter and exit C++ code, instead of remaining entirely in JS, which prevents optimizations like inlining and invariant code motion.
However, these problems will go away over time as most JS builtins are moved to pure JS implementations (which enables full optimizations).
If you are trying to determine things like 'what's the fastest way to iterate a sequence', the ONLY REALISTIC WAY to do this is to benchmark your actual use case, in context and see which approach is faster. Microbenchmarks applied to a language like JavaScript are, 99% of the time, complete horseshit.
Next up: you might not need <insert abstraction>.
Really?! What does "need" mean? Go write assembly.
You also get the same thing from the existential operator in coffeescript, if you're in to that.
Uncoring the Native DOM API http://blog.ponyfoo.com/2013/06/10/uncovering-the-native-dom...
Getting Over jQuery http://blog.ponyfoo.com/2013/07/09/getting-over-jquery
> jQuery and its cousins are great, and by all means use them if it makes it easier to develop your application.
However, operating in the world without jQuery is scary for a new developer. I think it has its utility.
Note: I tend to prefer not to use jQuery, especially with AngularJS around. YMMV
1) The fact that some people don't realize that JavaScript != jQuery scares me.
2) jQuery born when cross-browser compatibility was a mess and today it still carries that weight. I think nowadays it needs to be more modular and less monolithic.
DOM != Javascript
That's the thing you dont understand and makes you say silly things.
One question though, what is the pure javascript equivalent of $(document).on('click', '.selector', function() { // do something });
This is the new jquery .live() replacement and i need it because normal events stop working after async postbacks (eg. from an asp.net UpdatePanel).
Will this code do the trick if i attach it to the document element? Also i need IE8+ support :)
function addEventListener(el, eventName, handler) { if (el.addEventListener) el.addEventListener(eventName, handler) else el.attachEvent('on' + eventName, handler) }
addEventListener(el, eventName, handler)
It's as if there are now two "levels" of people - "regular developers" and "framework designers", and only the latter are really supposed to know about the nitty-gritty. The excitement of finding out about standard, cross-browser gems like insertAdjacentHtml is all but gone :(
I get it that people are focusing more on the entrepreneurial side of things now, but I miss the banter of aspiring tinkerers.
Although this is true, you don't really need any library. The problem comes when you start to need that library. You make a decision to not use it at the start of the project and then the dependency of lower level JS functions grow and it turns out you do need it. What do you do then? Go and get a copy of jQuery and start to rewrite all your functions?
Hindsight is the problem here, I'd rather make the decision to use the (relatively) low sized jQuery library and not have to worry about how the project grows.
As the old saying goes, "It's better to have it and not need it, than need it and not have it".
It seems to me that if you are making a library, and therefore do not want to make assumptions about the availability of jQuery, one potential solution would be to go the route of AngularJS[1] and have a 'soft' dependency on jQuery.
In this instance you would use jQuery if it was present, but fall back on the code found in this submission if it wasn't.
Are there potential downsides to this solution that I am missing?
I've seen thousands of js snippets using jquery just because the developer doesn't the pure js syntax, or because he is used to start from adding jquery.
very good page indeed, thanks for spreading the knowledge.
I can see myself reaching for this page a lot. And the author has a point as the only reason I used Zepto on my last project was one of the libraries I needed used it.
If I am gonna use a fix it library today, it's more about nodejs/browser compatibility than worrying about browser issues.
http://coding.smashingmagazine.com/2012/10/09/designing-java...
I agree that you probably only want to use a small subset of jQuery (e.g., none of the UI, none of the transitions), and zeptojs is actually a really good alternative. But it really does provide some convenience.
Either way, this is pretty neat, and I'll probably be bookmarking it. We're using ClojureScript now and migrating away from jQuery, so this may prove handy.
> $('<div>').append($(el).clone()).html()
vs
> el.outerHTML
Why not $(el)[0].outerHTML?
People that are not fans of jQuery are people that are are only familiar w/ MVC on client side and are not using APIs (ex: Parse, Kinvey, etc.)
I've already got fall-back for people who've turned off JS, but I've yet to write anything for unsupported JS.
Sometimes it's just as simple as testing if the function your about to call exists before you call it.
In a post IE8 world adding a minified jQuery library is not a big deal.
Oh wait -- that's what jQuery is!
Y[t]MN(NJ)
"You're [the] man now, ninja!"?As in: Code ninja?
Re-use is fun. See?
i have better things to do than merely writing my own dependency
Choose one:
- Performance
- Rapid development
> data = JSON.parse(request.responseText)
Maybe "var data = ..."?
Does Angular use the jQuery library?
Yes, Angular can use jQuery if it's present in your app when the application is being bootstrapped. If jQuery is not present in your script path, Angular falls back to its own implementation of the subset of jQuery that we call jQLite.
Due to a change to use on()/off() rather than bind()/unbind(), Angular 1.2 only operates with jQuery 1.7.1 or above.