A common pattern among web developers is to wrap code in a document.ready
callback and more specifically, because of the popularity of jQuery, most developers wrap their code with the $(document).ready(function() { /* my code... */ });
wrapper or more concisely $(function() { /* my code... */ });
. I think that because of the prevalence of this pattern and the frequent need to wait for all DOM elements to be present or the need for all scripts to have loaded this pattern is used far more often than it should be.
Don't wait for document.ready
The problem is that document.ready
and even worse, window.load
can take a VERY long time to occur. Especially in contexts where there are a lot of scripts or a lot of images involved. Most of our code doesn't need to wait for either of these things to occur. Most javascript is just defining functions and variables. The only thing that really needs to wait for window.load
is code that deals with positioning. The only code that needs to wait for document.ready
is code that deals with DOM elements that are inserted after the script being executed.
document.ready
shouldn't be invoked by scripts that are referenced in the <head>
of your site. If that script block needs to wait for the DOM to be ready, odds are the script can be referenced and executed at the end of the document at which point almost all of the DOM should be ready anyway. As for scripts referenced in the footer of the site most of the DOM is, again, already available for manipulation so there's no need to wait for an event handler to run your code.
window.load
takes even longer to trigger than document.ready
. This is because window.load
doesn't just wait for the DOM to be prepared but also the complete loading of every stylesheet, script, image and other asset referenced on your page. If you have a page with 80 images on it, window.load
isn't going to get triggered for quite some time and that means that code which doesn't deal with positioning specifically is unnecessarily delayed. Users are waiting for your page to boot up when they could be clicking through and spending money.
As a recap: A great deal of code that gets written gets thrown into a jQuery(document).ready(function(){});
block and it doesn't need to be. You only need to wait for that event if you're changing something in the DOM. And more practically you only need to wait for that event if you're changing something in the DOM and the script isn't at the end of the body tag which it should be. I propose that we all start using an IIFE as a standard and only wait for document.ready if we really need to.
When to wait for document.ready
- When you're not able to move DOM-based JavaScript tags to the footer of the page.
- When you need to group a bunch of code together into a single file and part of it needs to execute right away and the other part needs to wait for the DOM.
- Basically never, otherwise.
When not to wait for document.ready
- When your script is in the
<head>
and could be moved to the footer. - When your script is a library or utility that is called by other scripts.
- When your script has nothing to do with the DOM.
- All the time. Because you're an awesome developer and you love high-performance websites.