Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is jQuery.ready recommended when it’s so slow?

I have asked a similar question before but I never made my point exactly clear, or at least I think it’s such a relevant question that it’s worth to bring it up and see if anyone can give some insightful thoughts.

When using jQuery, many of us use the jQuery.ready function to execute an init when the DOM has loaded. It has become the de-facto standard way of adding DOM manipulation programs to a web page using jQuery. A related event exists natively some browsers, but jQuery emulates it in other browsers, such as some IE versions. Example:

<head>
<script>
    var init = function() { alert('hello world'); };
    $.ready(init);
</script>

Now, all our tests show that this event can be quite slow. It’s not nearly as slow as window.onload, but it’s still often around 100 ms delay before execution. If FF it can be up to 200-300 ms, especially on refresh.

These are some very important milliseconds, because this is the amount of time the initial layout is shown before any DOM manipulations are made (such as hiding a dropdown). Many times, a layout "flicker" is mainly caused by using a slow DOM ready event, forcing programmers to hide elements using CSS instead and potentially making it less accessible.

Now if we instead place an init function in a script tag before closing the body tag, it will be executed much faster, usually around half the time but sometimes even faster:

<head>
<script>
    var init = function() { alert('hello world'); };
</script>
</head>
<body>
<!-- some HTML -->
<script>init();</script>
</body>

A simple test page that proves the differences: http://jsbin.com/aqifon/10

I mean, we are not talking about barely noticeable differences as some of the "optimization police" promotes when it comes to using effective selectors. We are talking about some major delays when doing DOM manipulations onload. Trying this example in FF, domready can sometimes be more than 100 times slower (300ms vs 2ms).

Now to my question: Why is jQuery.ready recommended to use when it’s obviously much slower that other alternatives? And what are the drawbacks of calling the init before closing the BODY vs using jQuery.ready? It’s arguably more "safe" to use domReady, but in what context is it more safe than the other option? (I’m thinking stuff like document.write and deferred scripts) We have used the BODY way for nearly 5 years on many client sites, and we never run into any problems. It’s just a lot faster.

I’m also wondering, since there is so much fuzz about jsPerf and optimizing selectors for a couple of ms per 10000 executions, how come there is not much talk about this? It’s basically the first delay the user faces, and it seems to be fairly simple to slice 50-100 ms on each page load...

like image 248
David Hellsing Avatar asked Mar 04 '12 18:03

David Hellsing


People also ask

Why do we need document ready jQuery?

The ready() method is used to make a function available after the document is loaded. Whatever code you write inside the $(document ). ready() method will run once the page DOM is ready to execute JavaScript code.

Why is jQuery so slow?

The load process blocks everything else and makes your site feel slow. jQuery is also far from fast loading. It is heavy and slows page loading down a lot. So it has to go and that means anything that uses jQuery has to go as well.

Can I use jQuery without document ready?

It is in no way required. All it does is make sure that the DOM is loaded before trying to query for and use the elements inside the DOM (usually after dom is ready and before body. onload fires). You can use jquery perfectly fine without it.

What does jQuery ready do?

jQuery | ready() with Examples The ready() method is an inbuilt method in jQuery which helps to load the whole page then execute the rest code. This method specify the function to execute when the DOM is fully loaded. Parameters: This method accepts single parameter function which is mandatory.


3 Answers

To the point first:

No, there is no disadvantage in calling you init before closing the <body>. It will as you have noticed perform better that relying on $.ready() and will also work with all the browsers flawlessly (even on IE).

Now, there are however reasons to use $.ready(), which in your case they do not probably apply:

  1. $.ready() makes it easy for developers to do stuff in the right order. In particular, the critical thing is to not reference DOM elements that have not been loaded. While this is simple enough, lots of developers still find it confusing. $.ready() is a no-brainer, albeit a slow one.
  2. In you have say several scripts that need to init(), it is not necessarily easy/convenient to manually do that at the end of your body. It requires discipline and knowledge of what these scripts do. In particular you will often see $.ready() in libraries dependent on jQuery, since it makes things work no matter what way developers will use to load the libs.
  3. With Asynchronous Module Definition (for instance require.js) becoming popular as a way to load your javascript, the end of <body/> method is not guaranteed.
like image 144
ggozad Avatar answered Oct 19 '22 17:10

ggozad


One advantage would be, that you are able to place the code anywhere in the page. In our case, we use a templating system in our CMS that stitches the page together from around 10 - 30 templates for the different parts (depending on complexity).

Since you want the templates to work on any page they are used, you need to include the necessary Javascript in it. For those cases, the ready() function is a real life saver.

like image 6
nfechner Avatar answered Oct 19 '22 18:10

nfechner


If you've written a JS file that other people are including in their pages it is safer to use document.ready within that file (assuming it needs to do some processing automatically after the DOM is ready) because you can't be sure whether the file will be included in the head or at the end of the body.

When it comes to pages that you have complete control over then obviously you don't have that worry, so I don't see that it is any more "safe" to use document.ready rather than calling your init() from the end of the body. Using document.ready (or onload) and putting script at the end of the body are the two most common ways to do it, and they're common because they both work well.

You mentioned document.write() as a possible exception, but you don't want to be calling that from document.ready or at the end of the body because either way the whole page has already been parsed.

like image 2
nnnnnn Avatar answered Oct 19 '22 17:10

nnnnnn