Hacker News new | past | comments | ask | show | jobs | submit login
Don’t let jQuery’s $(document).ready() slow you down (encosia.com)
139 points by gspyrou on Aug 19, 2010 | hide | past | web | favorite | 22 comments

Important takeaway: Use Firebug's network monitoring to find out what actually happens when your page loads.

the rest seems to be summarised as: don't wait for things you don't need to wait for.

$(document).ready() can be a bit of a sledgehammer in terms of latency.

Don't just base your conclusions on one page load, though, as this article seems to do. I wish there was a tool for Web Inspector/Firebug to select various elements over a series of page loads and give me statistics after e.g. 100 refreshes. Page load is highly variable and dependent on things like caching server-side, client-side, within the database, etc. as well as network conditions so repeating the tests is important.

None of those conclusions are based on the two screenshots shown in the article. I just set those up and included them for illustrative purposes. The article's points themselves are based on my experience routinely using those optimizations in production.

Sorry if that wasn't very clear in the article.

I'm not sure he knows how .live works. .live doesn't wait for items to be ready and it only binds one event on to the top level document. .live waits for bubbled events and if the item bubbling the event matches this .live selector it calls back. Pretty smart if you think about it.

But either way he makes a great point on the document.ready if your page depends on ajax or some sort of ui styling its probably best in the header script.

Right, that's the crux of my overall point about .live(). Since it's using event delegation, the DOM elements don't need to be present at the time you declare it. If you have the opportunity to set up your .live() handlers early, you should.

Seems to me that AJAX before document-ready could get complicated once you want to actually do something with the response. Normally one would do something like this:

    $.getJSON(my_url, function(data) {
But if we call getJSON before document-ready, the node $('#some_container') may not yet exist! Now we need some way to wait until both the AJAX request is complete and the document is ready…recommendations?

EDIT: Thanks for the responses, glad to know it's safer than I thought!

The way browsers implement both JavaScript and document rendering via a single-threaded execution queue, that isn't an issue. Once the page begins rendering, callbacks won't have a chance to execute until after the document is rendered and ready. That's the same mechanism that makes the setTimeout(fn, 0) trick work, for example.

It feels a bit like driving fast with no seat belt on, but it's safe.

If you do want to be extra cautious, MBlume's suggestion to wrap the success handler in $(document).ready() works fine too. That's effectively the same as not wrapping it.

swap the first two lines:

  $.getJSON(my_url, function(data) {

Very clever. This works because $(document).ready will execute immediately if the page is already loaded.

I know this is off topic, but there's another reason it slows you down - too many keystrokes.

I prefer




I'm torn when it comes to that. The readability of $(document).ready() is better. Especially for later devs who may not be familiar with jQuery.

For devs not familiar with jQuery (and on the off-chance that you'll need no-conflicts mode at some point), you might even avoid the dollar sign.


On the other hand, if a dev is that unfamiliar with jQuery code, they shouldn't maintaining jQuery code.

Using $(function(){}); serves as a nice warning to this effect.

That is an awful argument. Can you imagine what software would look like if people took that approach with everything? Development would have ground to a halt decades ago.

I think the point is that they should learn enough jQuery before maintaining jQuery code.

Or even better:


You can also use the module pattern[1] to isolate code from tampering or conflicts:

  (function($, window, undefined) {
      // etc.
  }(jQuery, window);
[1] http://www.yuiblog.com/blog/2007/06/12/module-pattern/

Even further off-topic, I really like the succinctness of the former in CoffeeScript:

  $(function () {
      $('#index').append($('article p:first-child'));

  $ -> $('#index').append $('article p:first-child')
Not exactly noob-friendly, but very concise.

This is my preferred pattern:



It would avoid noConflict type problems.

.live() needs more promotion.

If you like live(), you'll enjoy delegate() more.

But, regardless, event delegation needs more love, yup.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact