No, please no. If size is an issue for some reason or you want to have no dependencies you can use something like http://zeptojs.com/ and just embed everything in one minified file. If you do things right only the functions you are actually using will get placed in there as well.
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.
I believe the point is that many libraries use about 1% of jQuery. That hardly justifies pulling in the entire thing.
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.
Considering XMLHttpRequest is what other browsers used before IE caught up, I assume it does work the way you'd expect across modern browsers. I'd have to check the standard and IE8+'s conformance to the standard to be sure. That's what this post is really about for me, reminding that modern browsers follow a standard that allows for getting rid of most of jQuery. Reading it also made me recall a post from 2005 by PHP's creator: http://rajshekhar.net/blog/archives/85-Rasmus-30-second-AJAX... (Note IE uses ActiveXObject.)
As I recall, they specifically implemented it in order to facilitate Outlook’s web interface – their collective regret may be tempered by the satisfaction they got from all those high-margin site license sales to which that feature contributed.
For me jquery is all about events. Making sure I get the event tree bubbling in the correct way across the entire universe of browsers and all its data being normalized is such a time saver. Even their support isn't perfect, but I'm sure its way better than any other event library out there in terms of breadth and depth of testing. The selectors bit is a nice to have, but that is getting easier since its inclusion in dom itself.
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)
About one year ago, I developed a shared widget. Some fraction of my clients refused to load jQuery, as they still preferred older, less popular DOM libraries.
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.
If you are looking for a standalone event (delegation) library check out one I wrote http://craig.is/riding/gators. The syntax is very similar to jQuery.
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).
You think that a page that loads jQuery but doesn't use most of it incurs a performance penalty? I'll grant there are a few initializations and dom checks that jQuery does, but it probably blocks for all of 20ms.
Most modern browsers are able to paint while loading script files, especially if you put your script files at the bottom of the page, where they belong. So, no, 20ms of parsing, compiling, and a small amount of execution is not a lot of time. Period.
> I believe the point is that many libraries use about 1% of jQuery. That hardly justifies pulling in the entire thing.
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.
In practice, especially for javascript usage, the old CSS selectors cover all the bases.
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?
You lose some browser compatibility with qSA, whereas gEBId works everywhere. You need IE8+ for qSA, and you need to ensure the page isn't in quirks mode. If you're OK with that then you can also do: var $ = document.querySelectorAll.
Probably best to do this within a closure so that you're not hijacking any jQuery instances that may be on the page.
1) Zepto is POS. It offers the illusion of jQuery compatibility while delivering only maybe 80% of it. You simply cannot reverse-engineer something 100% without doing everything the original does, so you might as well use jQuery.
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?
> 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?
Nope. jQuery 2 just removed code for IE 6/7/8. Nothing was added. Code sized reduced, but almost the same performance. My benchmark shows only 10-15% improvement. That's nothing compared to using the DOM API straight up.
Hmm, I'm wary of a test that involves another framework to test the underlying jQ v. Native DOM performance difference. I'd be much more comfortable eliminating Backbone from the equation.
Also, 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.
See my previous comment[0]. That perf test is testing Backbone's use of jQ vs. native DOM, not jQ v. DOM in isolation. I don't trust that there aren't side effects and interactions in the test.
>> 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?
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.
I love the idea of removing Backbone's jQuery dependency. If I could use Backbone without jQuery, I would gladly leave jQuery behind.
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 :-)
jquery is really just an abstraction for dom, it is not an api for application building. When I have to use the dom, I definitely turn to it. I'm not sure why people object to having additional helper functions in jquery for a measely 100k or so.
You don't have to use plugins you know, its not a law.
Whether 100k is huge or not depends on the project's requirements. In some cases it's perfectly fine, in other cases it's a problem. Such a broad statement cannot be supported.
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.
100k is huge, period. Whether or not a huge dependency is acceptable depends on the project. Yes, we know it depends on the project, that was the point of the site. The whole point is "if you are making a library, and don't really need jquery, please don't force that extra dependency on users of your library".
Fantastic point. Abstractions can be dangerous because they often aren't developed right.
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.
As near as I can tell, browsers are already at least sometimes caching compiled representations of JS; the win from shipping specific versions of jQuery would be minimal, and not work unless you used specific CDNs anyhow.
are you serious ? thats actually a good example on why you should use jquery.
First of all the dev needs to know exactly on which platforms he will run into problems and how to solve them...And what if you need not one but several polyfills ? That gets messy pretty quickly.
Ah no. First of all, you should always know which platform you target and what works and what don't work on those platforms, even if you are using jQuery. jQuery is not perfect. Platform specific corner cases are still exposed to you.
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?
> You should always know what browser feature you are using.
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 can certainly use JQuery as your API base if you're willing to take the hit on performance and a few hundred KB download, and are willing to take that hit on every project you write.
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.
That makes a lot of sense especially in areas where you are competing for people's attention. If you aspire to being a front-end engineer it'd be silly not to know the DOM APIs inside and out, especially now that browsers have such nice dev tooling.
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
The point is, jQuery doesn't free you up from remembering lower level details, they are still there in your face all the time, especially when it comes to event delegation and handling. jQuery also doesn't help you with CSS, which is even more of a pain than DOM inconsistencies. The whole point of polyfills is to patch browser incompatibilities, often times without losing any performance to newer browsers, so you can provide the best experience to half the people in the world on newer browsers and a mediocre experience to the rest, instead of a mediocre experience for everyone. If you care about attention to details, you should understand what your browser is doing. Polyfills are things that you only have to learn once and drop in once. Isn't providing a good experience one of the more important things?
Actually, jQuery can help with CSS inconsistencies, much the same way vanilla Javascript can, if you have the mind to use it that way.
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.
And style.display='block' for jQuery.show() does not work with <tr>'s (which need 'inline-block') and rules which have an !important clause in the CSS (which need to first set the display to empty string and then set it again).
Size really is issue when dealing with mobile devices. Even from disk cache each KB increases startuptime by about 1ms (and jquery 2 is ~32kb minified, for < 2.0 lot more). Over cellular connection you can nicely multiply each KB by 100ms. This is even worse when you minify and concat your JS library dependencies, as most likely your cache headers expire way too fast for them. If you have bothered to set them at all.
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 speed difference between querySelectorAll and getElementsBy* is entirely because of the difference between live nodelists and static nodelists. getElementsBy* returns a nodelist that reflects changes in the DOM in real time - this means that it's just returning a pointer. querySelectorAll copies the full result set into an array-like object at method-call time.
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.
> 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*".
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!
> 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".
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.
How complicated your query have to be to run into these QSA bugs? Don't forget that you are paying a very high performance cost for compatibility. I mean, how many people are still on Chrome 21 and Firefox 3.5?
jQuery might use querySelectorAll for its selector, but also looks for basic patterns and optimizes them by using things like getElementBy* eg. $("#test") will use getElementById behind the scenes, not querySelectorAll.
In most cases where you have any level of complexity, you are better off using jQuery or some other already tested out libraries. That being said, blanket statements about technology choices are suspect because every project has different needs and requirements. You should evaluate things on a case by case basis.
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.
It's better if libraries don't just assume jQuery is everywhere, because I suspect those days are ending. Apps built on newer front-end frameworks like Angular and React might not need it, for example.
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.
If it's just a general library to use anywhere, then sure build it with no dependencies.
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.
You do realise zepto works in IE10+ only, and even then you need an additional module for support. I wouldn't say it's worthwhile. It is not a viable alternative.
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
No thanks, I'll take something that I'm sure 99% of web developer know by heart and works cross browser. I don't want/need to spend hours upon hours writing "clean" code that doesn't use jQuery. I have business problems to solve.
Abstractions are meant to, well, abstract an implementation. You might very well want to abstract a native operation for a bunch of different reasons. You don't need to, but maybe you should.
For example,
$(el).hide()
is quite more readable than
el.style.display = 'none'
. And I'm not even talking about the other advantages.
" 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"
You wont have $.contains, instead $(el).children(child) returns a chainable filtered list of the first level of child nodes, or $(el).find(child) will go down recursively.
jQuery rarely dumbly duplicates some native functionnality, as for the example above, most of the time it will diverge in meaningful ways.
These two new functions you mentioned are both in the article linked to above. 'el.children' and 'el.querySelectorAll(selector)' are given as alternates. It is true they aren't 100% the same but JQuery isn't different enough in my opinion for there to be any clear reason to use it instead of what is already available.
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".
> 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.
It's not, but then you fall on IE9+ land, and you'll have to check if querySelectorAll returns anything first.
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.
> 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.
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.
We have a challenge in that so many of our web applications are built in a way that prevents us from performing analysis across technologies. For example, a modern rails app will possibly include haml, sass, coffeescript, and ruby along with the usual html, Javascript, css, etc., that are included in the various gems and plugins.
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.
Its not about reinventing the wheel. Its about being open minded. jQuery is great, and if you are going to use zepto, you might as well use jquery 2.0
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.
This response is quite strange in my eyes, because the website doesn't invent anything new, it actually says to use less bloat, which is always a good thing. Why use a well tested function if you can completely get rid of it?
And yes, less code, less abstraction, and less requirements are damn good reasons not to do something.
You're right in principle, but Zepto is a horrible recommendation because it gives the middle finger to anyone on IE < 10. I was originally designed explicitly for mobile browsers, so it makes sense, but it means it's rather unfit for the majority of businesses.
What would be awesome is if jQuery had the same kind of download builder as jQuery UI, so that you could only include the parts of it that you actually need for a library.
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.