Search code examples
javascriptjqueryperformancedelaydomready

$.ready() before closing body


This is not a real coding question, more of a real-world statement.

I have previously noted that DOMReady events are slow, very slow. So, I noticed while browsing the jQuery source that the jQuery domeready event can be trigger using $.ready(). Then I thought, placing this simple execution script just before closing the body should trigger all the "onDomReady" listeners that where previoulsy attached. And yes, it works as expected:

     <script>$.ready()</script>
</body>

Here are two examples, this one measures the ms spent while waiting for DOMReady:

http://jsbin.com/aqifon/10

As you can see, the DOMReady trigger is very natively slow, the user has to wait for a whole 200-300 milliseconds before the domready script kick in.

Anyway, if we place $.ready() just before closing the BODY tag we get this:

http://jsbin.com/aqifon/16

See the difference? By triggering domready manually, we can cut off 100-300 ms of execution delay. This is a major deal, because we can rely on jQuery to take care of DOM manipulations before we see them.

Now, to a question, I have never seen this being recommended or discussed before, but still it seems like a major performance issue. Everything is about optimizing the code itself, which is good of course, but it is in vain if the execution is delayed for such a long time that the user sees a "flash of "unjQueryedContent".

Any ideas why this is not discussed/recommended more frequently?


Solution

  • Any ideas why this is not discussed/recommended more frequently?

    Placing JavaScript just before </body> has been discussed a lot, and as you know it's recommended if you're looking for faster page loads. Manually triggering the jQuery ready handlers is in fact poorly discussed. Why? Well, I don't think there is one single objective answer to that, but I'll try to outline some possibilities here:

    1. Performance is not the main goal of jQuery (anthough it's definitely a concern), and performance freaks will usually look for lighter libraries for cross-browser DOM manipulation and event handling, or roll their own.

    2. It's an extra step, and it doesn't look clean. jQuery tries to be clean and elegant, and recommending an extra step to initialize scripts doesn't sound like something that's gonna happen. They recommend binding to ready, so recommending to force .ready() and ignoring the actual browser event looks "wrong". Whoever is concerned about that probably knows that initializing scripts right before </body> is faster.

    3. Optimizing DOMContentLoaded sounds like a task for browser vendors. I'm not sure why it's slower, though, and maybe there's not much room for optimization – in my understanding, calling init scripts before </body> should always be the fastest way to initialize stuff (as it's executed immediately when parsing the container <script> tag, while browsers must finish parsing the whole file before triggering DOMContentLoaded).

    You probably remember that not so long ago it was common practice to have <script> blocks scattered everywhere on the HTML. Then the Web Standards movement came, and recommended more sane and maintanable ways to do things. That included bootstraping scripts from a single place – initially, window.onload, which was then considered problematic for being slow, then DOMContentLoaded and its emulations for IE8 and below. However, we still see spaghetti-HTML with scripts everywhere on a daily basis here on StackOverflow. So I'm not sure if recommending placing scripts before the end of the body is a good call today, because it may be interpreted as a license to add scripts anywhere within the body.

    Finally, if you're really concerned about loading your script fast, and your code does not manipulate the DOM, the fastest way to load it is to put it in the <head> before any stylesheets. And I'm stating that just to say that there's no silver bullet, no optimal way to init scripts that is the fastest and most elegant in every scenario. I think that's why the community sticks with recommending something that looks sane and tends to create more maintainable code, instead of other better performing alternatives.