$.ready() before closing body
Asked Answered
M

3

10

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?

Mariannamarianne answered 12/10, 2012 at 0:30 Comment(4)
All I can say is awesome. I hope no one comes up with a good reason not to do this!Repurchase
is the dom ready in IE before the body is closed?Kimmy
@Kimmy yes, the DOM is ready when the closing of body occurs in all browsers I’m aware of. Although, I’m very curious to find a use case when this is not the case...Mariannamarianne
Excuse the stupid question but how would placing something inside a document ready handler and then manually triggering the handler differ from just having your unwrapped JS right before the closing body tag?Pd
A
3

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.

Airminded answered 14/10, 2012 at 2:16 Comment(0)
E
4

By triggering the event yourself, you are stating to your ready() handlers that your dom has been loaded BUT it may not have been! There is no short cutting the DOM ready event. If there is indeed a long wait time, then employ the amazing debugging tools of firebug, chrome, etc.... check your resources and their timing ques. It's all there in black and white and will indicate what is taking so long (the requests, the rendering, how many resources, etc.. )

Element answered 12/10, 2012 at 0:39 Comment(3)
Can you post a real world situation when the DOM is not synchronously ready when the body closes?Mariannamarianne
Who says the body is ready just because you reached the </body> tag. There is more to the DOM than just the body. I will post a real world situation right after you post yours where you guaranteed that the DOM has been FULLY loaded by your technique for all major browsers (and all race conditions, browser locks, etc.. have been successfully resolved) prior to the first ready() handler being invokedElement
Ok, start here: jsbin.com/aqifon/16. I have coded real world websites for as long as jQuery has been around, and I have always put a native trigger before closing body instead of using DOMReady. And I never heard about any situations where it didn’t work.Mariannamarianne
G
3

Actually, placing a function call before </body> tag makes it pointless to use jQuery's ready(). Just put native JS-wrapper function call that contains calls of all other functions that should be called on document ready.

In general, it's a working (though somewhat littering HTML code and therefore unacceptable for perfectionists) alternative for situations when author does not need/want to use jQuery at all. In such situations though, I would prefer to use native DOMContentLoaded event handler that is supported by most of browsers including IE9+ (for IE8- we can use window.load() as an acceptable fallback).

Gaffrigged answered 12/10, 2012 at 0:52 Comment(1)
I agree with your first sentence, although there are many "plugins" and other developer add-ons that automatically wrap their DOM-dependent manipulations in a DOMReady handler. My suggested solution would trigger them much earlier that what would normally occur.Mariannamarianne
A
3

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.

Airminded answered 14/10, 2012 at 2:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.