7 ms·
Stop Paying Your jQuery Tax
- EGreg 15y agoThat is a great point! An interesting question is, why not just put ALL scripts at the end of the <body> tag, after the HTML of the page has loaded and the CSS probably did as well? The only thing I can think of is if you have code ON the page which uses these scripts. But why not just put that code at the end of the page, too?
- sams99 15y agoThe main reason this happens is that most MVC platforms generate pages piecemeal, say for example you are generating a 'product' page: It has a 'template' that contains your header,footer and scripts that everyone relies on. Then the product piece may also need a script or 2 and finally it may need to add some dynamic love to the page like say: $(myMagicHelper(779,'magic');), in general people are used to just inlining these kind of mini-scripts close to the bit that generates the product html. It can be migrated to a system that defer generates it in the footer, but usually would involve a larger amount of change (at least on projects I worked on). I guess this trick saves you a bit of time migrating some inline scripts to the bottom.
- joevandyk 15y agorails has content_for (http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#method-i-content_for http://api.rubyonrails.org/classes/ActionView/Helpers/Captur...) that helps with this.
- sams99 15y agotrue, still verbose, but more elegant than the solution in asp.net mvc
- riffraff 15y agoout of sheer curiosity, what is the asp.net mvc solution?
- sams99 15y agoMy current thinking is: http://snipt.org/uNq8 http://snipt.org/uNq8
- untog 15y agoIt doesn't really have one. Annoying, because it's 90% of the way there- views can insert code into specific "sections" of the template, but sub-views can't. If they just enabled that then you could make a "JS" section just before </body> and have all your JS inserted there.
- deleted 15y ago[deleted]
- oinksoft 15y agoA strong reason to not do so is when you want some part of the page to be immediately enhanced with JavaScript (like a login form). If the page has many images and other resources, your users will have an awkward experience, with the scripts suddenly engaging at a time that feels arbitrary. While some scripts absolutely belong at the bottom of the page, it is a very good idea to decorate JavaScript widgets immediately after the HTML is rendered, as in: <div id="widget1234"></div> <script> (function() { var widget = new Widget({ el: document.getElementById('widget1234') }); // ... })(); </script> Note that the script is also inlined here: Losing the overhead of an HTTP request is beneficial when a widget needs to spring to life immediately: You want it to be active the moment the HTML is finished.
- EGreg 15y agoSimply have the widgets start as display: none -- or even better -- visibility: hidden until they are rendered with js. The css accompanying the widgets should do this.
- oinksoft 15y agoYes, that should be the case anyway: The widget shows itself when it is finished decorating. But even then, there's no sense in deferring decoration until after some other arbitrary resources have loaded.
- fourstar 15y agoSo is the article saying you are basically putting an alias for jQuery's `$` in the header and so if you need to put `$(function() {});` or `$(document).ready(function(){})` elsewhere in your page you rely on that alias and then once jQuery has loaded, map the `$` to it?
- sams99 15y agoThat is one technique you can use to assist you in pushing your jQuery include to the bottom, the others are having a smart script registration piece that takes care of it for you or running code that rewrites the html like blaze.io does
- alecco 15y agoComplex solution to simple problems.
- alecco 15y agoYes, WTF worthy.
- whichdan 15y ago"Chrome seems to be able to do it under 10ms, IE9 and Opera at around 20ms and Firefox at 80ms (though I probably have a plugin that is causing that pain). IE7 at over 100ms. On mobile the pain is extreme, for example: on my iPhone 4S this can take about 80ms." I'd be very interested in seeing some more concrete benchmarks for this.
- ericflo 15y agoHere's an interesting chart I came across recently: https://docs.google.com/spreadsheet/ccc?key=0Aq_a4WNAMuCEdDdjSlhyWXJaTkQ0TVJFc1k1RzlTTlE#gid=0 https://docs.google.com/spreadsheet/ccc?key=0Aq_a4WNAMuCEdDd... (via http://blog.pamelafox.org/2011/11/porting-from-jquery-to-zepto.html http://blog.pamelafox.org/2011/11/porting-from-jquery-to-zep...)
- firefoxman1 15y agoHow does Pushing jQuery to the footer solve the "constant tax"?
- sams99 15y agoyou get to see your content on the page rendered before jQuery is parsed and compiled. There are other approaches like asyc or defer that are preferred but harder to implement and you could go for a leaner jQuery like say jQuip
- pacomerh 15y agoWhat you just said is this article summed up I think. Getting to read the content before the jQuery is parsed is the key and solves the cache issues. The other part where you collect all the jQuery functionality and you push it to the array/.ready loader at once, forces you to be organized.
- deleted 15y ago[deleted]
- alexchamberlain 15y agoI hope it also forces people to use CSS where possible (which is more efficient for certain animations etc), and only use jQuery where necessary.
- sdsd 15y agosdsdsddsds
- VMG 15y agoNah, I'm going to pay the tax rather than optimize prematurely. But I'll add that to my bag of tricks when I start optimizing.
- heimidal 15y agoI'm not sure this qualifies as premature optimization. Allowing jQuery to block page load incurs a bit of load time where the user has to sit around waiting. Anything that can be done to minimize user frustration (and maximize user experience) is probably worth doing when it's so simple.
- Sodel 15y agoAgreed. Premature optimization is about "maybe", and feared performance loss. Responsiveness matters to users; to them, speed is a feature, insofar as they can perceive it. The "JQuery tax" absolutely is a real, and user-perceptible issue. "Avoiding premature optimization" can sometimes make it hard to undo poor design choices made early on that could have been avoided.
- VMG 15y ago> Responsiveness matters to users; to them, speed is a feature, insofar as they can perceive it. The "JQuery tax" absolutely is a real, and user-perceptible issue. I think the evil of premature optimization is attacking the wrong target first. 80ms isn't a small amount, but moving script tags around could have more potential side effects than say using proper caching, minifying etc
- Sodel 15y agoGood point. This hadn't even occurred to me.
- speleding 15y agoAfter the initial load from the CDN the tax is 10ms (Chrome), 20ms (IE9) or 80ms (Firefox). So for modern browsers it's really a tiny amount you save. For IE7 users the tax is more than 100ms but it seems a waste of time to optimize for them given their market share. I'd say saving 20ms is premature unless you are already doing everything else you can do.
- Yahivin 15y agoWhy do you still need a document ready function if all your scripts are loading after the html anyway?
- deleted 15y ago[deleted]
- sams99 15y agowell its more of a legacy problem, we are used to using it everywhere, deferring external scripts is a fairly easy exercise but those tiny snippets everywhere that have $(doStuff) are more annoying to port
- ehynds 15y agoIf all your scripts are before the closing </body>, the DOM will be ready by the time they execute, and you can safely ditch your legacy ready wrappers.
- beaumartinez 15y agoThe DOM will have been parsed if your scripts are at the end—but external components (links, imgs) may not have loaded yet.
- ehynds 15y agoThe same is true whether or not you use a document.ready statement; you're thinking of window.onready, which fires once all images have been downloaded.
- beaumartinez 15y agoYou are correct! Thanks. Been spending too long with document.readyState.
- ricardobeat 15y agoyou meant window.onload
- radicalbyte 15y agoIf you're looking into these kinds of optimilisations then why not sidestep the problem by moving to a single page application model? Or is it still acceptable to support clients who do not enable javascript?
- bru 15y ago> Or is it still acceptable to support clients who do not enable javascript? I deeply believe that yes, it is. Making Javascript mandatory on websites where it should only enhance the user experience still seems to me like a very bad practice, and I hope it will stay so. I even want to say that, if your website if correctly designed, offering its content in a Javascript-less way should not be that hard...
- bruce511 15y agoI think it's less an absolute, and a lot more "it depends". If you're building a 3 page website for a mom and pop operation, then ok, have a JavaScript free site. If you're happy with the sites from the 1990's, then no JavaScript is just fine. It's possible in some cases to use progressive enhancement, so that those without JavaScript get a working, albeit really poor, experience. How much effort you put into creating that option, and maintaining it, depends on your cost-benefit analysis. If however you want to build a site that the user interacts with, then JavaScript makes such an important difference that not to use JavaScript results in a crappy user experience. I want every bit of data entry to be validated when it's entered, either on the client or the server, not wait for the user to click "submit". I want forms to morph as the user enters data. Shipping address same as Billing address? Great, user clicks "Same As Billing" and all the Shipping Address fields vanish. Shipping out-of-country? Ok, shippers that service the US only are removed from the Shipping options drop-down. Don't get me started on a zillion user-interface improvements, like data-lookups, sliders, menus, autocomplete etc which enhance the user experience and make people want to use my app, and come back to it. There are only 2 groups who don't have JavaScript support. Those using truly ancient browsers, and those who've actively turned it off. I honestly don't see the point of degrading the experience for everyone based one these two demographics. It's unlikely that either group will contribute significantly to my income, certainly not in proportion to what it costs to support them. We make this trade-off all the time. If I write a desktop Windows program, I'm ignoring the 10-15% of folk not on Windows. If I write an iOS app I'm ignoring the folks with Android et al. So - it depends.
- chokma 15y agoThe Grails framework has a plugin to organize resources like JavaScript - http://grails-plugins.github.com/grails-resources http://grails-plugins.github.com/grails-resources (scripts will by default be added to the end of the page and even if your page consists of several template files which depend on jQuery etc, they will only be included once).
- jackmoore 15y agoThis is clever. However, it depends on scripts using the shorthand notation for jQuery's ready method. Maybe it would be better form to use something explicit instead rather than doubling up $ operator.
- sams99 15y agotrue, we are used to using the shorthand notation in fact at SO we use a special internal variant called StackExchange.ready for a similar purpose, you could get $(document).ready remapped with a similar trick if you wanted, or you could simply push the inlines to the bottom as well.
- collypops 15y agoHere's my attempt at the similar trick, covering all 4 possible ways to bind to DOM ready using jQuery: http://blog.colin-gourlay.com/blog/2012/02/safely-using-ready-before-including-jquery/ http://blog.colin-gourlay.com/blog/2012/02/safely-using-read...
- alecco 15y agoPlease go check out StackOverflow's source code before bandwagoning on this topic. This is shifting blame to the tools. The problem lies on StackOverflow's lacking design and not in jQuery. Pushing jQuery to the bottom of the page is trivial if you do proper HTML architecture. Pages should have only HTML. JS files only JS. JS files referenced at the very bottom of the body. Very simple. (if your asp/c#/* framework doesn't make it easy, blame the framework and not jQuery) Inlining JS and even having JS code in the title attributes is ridiculous. Fix your HTML and only then you get the right to say anything. Another telling gem is StackOverflow page doesn't even have a proper encoding declaration. You don't need to use jQuery for everything. This is very typical of developers coming from backend who don't take web development seriously. Use CSS as much as possible. Another misplaced attack is refresh, with proper cache headers it should not take that long. If some browsers are slow and don't keep a pre-parsed cache, blame the browser vendor and not jQuery. jQuery taking 80ms on mobiles is quite OK. If you really care about mobile make a page optimized for mobile and minimize JS rendering and styling. I absolutely love StackOverflow and it's one of the best things to happen to programmers in the last few years. But this self-righteousness attack on a very important tool is very misleading and ungrateful. Edit: the proposed "solution" of catching $.ready and later calling those is insane.
- marcofucci 15y agoAgree, I use Django and I had no idea what they were talking about. They should check out other frameworks before writing posts with generic headlines.
- sams99 15y agoLet's be clear ... I am not attacking jQuery here, just saying it is misuse to chuck it in the header and offering a practical mechanism to get out of a mess you create. I explain the cost of placing it in the header. I am not perfect, I make mistakes daily, I try to learn.
- ehynds 15y agoYou pointed out a few best-practices, but it's a shame that this article is written in the context of jQuery, rather than recognizing that these "taxes" are true with every script tag you place on your website.
- bmuon 15y agoI think they're still missing the point. The idea is to stop using jQuery like that. Think of it as another required module of your application and move everything to requireJS. You'll gain speed and peace of mind once you learn to modularize all your JavaScript code.
- alecco 15y agoThat's yet another dependency. Not my cup of tea. I'd rather wait for the upcoming light/modularized jQuery rewrite.
- sequoia 15y agoI'm very confused... why aren't the scripts in the footer? Because of inline javascript? What problem is this solving? What does this have to do with jQuery in particular? I'm very confused...
- pragmatic 15y agoThis linked article is good: the Performance Golden Rule http://www.stevesouders.com/blog/2012/02/10/the-performance-golden-rule/ http://www.stevesouders.com/blog/2012/02/10/the-performance-... (submitted days ago but got no traction) For years we have been told that we will have to wait on the database so it doesn't matter how fast your implementation language is... Well it's half true, depending on what you consider your implementation language: server side or client side. Front end performance matters just as much (or by this article) more than "backend."
- pragmatic 15y agoHow does this (http://37signals.com/svn/posts/3112-how-basecamp-next-got-to-be-so-damn-fast-without-using-much-client-side-ui http://37signals.com/svn/posts/3112-how-basecamp-next-got-to...) get to be number one, while this http://www.stevesouders.com/blog/2012/02/10/the-performance-golden-rule/ http://www.stevesouders.com/blog/2012/02/10/the-performance-... goes nowhere? Are we upvoting simply by name recognition? http://stevesouders.com/about.php http://stevesouders.com/about.php He only wrote the book on high performance web sites... http://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309 http://www.amazon.com/High-Performance-Web-Sites-Essential/d...
- joshuacc 15y agoIt's partly name recognition and partly novelty. The 37signals approach is unusual, while most competent front-end developers are already aware of the principles in Souders' post.
- awj 15y agoSounders post is 5% halfheartedly evangelizing (maybe not-so) common knowledge and 95% reiterating his point about the split between frontend/backend time on fulfilling a request. After reading it I'm pretty sure it could eliminate all but the last graph and be just as valuable at 1/4 the length. That he did a rather comprehensive evaluation is commendable, but I think the post loses track of its main point in favor of sailing the sea of data that was collected.
- ricardobeat 15y agoStop paying your .NET tax and start using proper javascript.
- Roboprog 15y agoWhile I personally would prefer to put most JavaScript in an separate file, rather than sprinkled inline, it happens. So, why doesn't the browser handle this problem for us??? Why not have the browser drop all of the js script fragments and references into a queue, then run them later? Why make people reshuffle the stuff that they have working? Hell, for that matter, I'm a bit puzzled why js even runs before the document is ready anyway. Is there some user in a hurry to get his alerts and popup windows?
- tghw 15y agoWhen we were working on WebPutty.net, we found headjs (http://headjs.com/ http://headjs.com/) to be very useful for ensuring all other script calls are run outside of the <head> tag. The full library runs 2.7k gzipped, while just the loader is 1.3k and is the only javascript file you need to block on. (The full script includes a modernizer library in addition to the script loading functionality.)
- jebblue 15y agoI think the world should just go back to rich client apps and forego the web browser development tax in general. At least consider something like GWT which let's developer code the server and client in Java and Google worries about how to optimize JavaScript.