Async and document ready
defer
would definitely help here.
defer
is generally better than async
because it:
- loads asynchronously (just like
async
) - guarantees the execution order (unlike
async
) - executes at the end (unlike
async
that executes in parallel when the page is still loading and it actually halts the dom-parsing!) - jquery
ready
fires after the "deferred" scripts have been loaded (this is what you're asking)
This SO answer has a very nice picture illustrating defer/async load order, super-understandable.
If you didn't want to use a script loader, you could use the following approach which would allow you to leave your $(document).ready scripts in place - modified as follows:
$(()=>{
function checkAllDownloads() {
// Ensure your namespace exists.
window.mynamespace = window.mynamespace || {};
// Have each of your scripts setup a variable in your namespace when the download has completed.
// That way you can set async on all your scripts except jquery.
// Use the document ready event - this code - to check if all your scripts have downloaded.
if (window.mynamespace.script1 && window.mynamespace.script2){
// Proceed with page initialisation now that all scripts have been downloaded.
// [ Add your page initialisation code here ].
return;
}
// Not all downloads have completed.
// Schedule another check to give the async downloads time to complete.
setTimeout(checkAllDownloads, 500);
}
// check if it is safe to initialise the page by checking if all downloads have completed.
checkAllDownloads();
})
After some extensive research, I can definitely say that putting scripts at the end of the page is THE best practice.
Yahoo agrees with me : http://developer.yahoo.com/performance/rules.html#js_bottom
Google don't talk about this practice and seems to prefer async scripts : https://developers.google.com/speed/docs/best-practices/rtt#PreferAsyncResources
IMHO, putting script at the end of the page has several benefits over async/defer:
- It will work for all browser (yes, even IE ;) )
- You guarantee the execution order
- You do not need to use
$(document).ready
or$(window).load
- Your scripts can execute before your images are loaded
- As async/defer, your page will be displayed quicker
- When the DOM trigger the ready event, all scripts are loaded
- Can be optimized by merging all js in one file without problem (by a tool like mod_pagespeed)
The only drawback that I can see is that the browser won't be able to parallelize the downloads. One good reason to use async/defer instead is when you have a script that is completly independant ( do not need to rely on the execution order) and that don't need to be executed at a specific timing. Example : google analytics.