One good practice in web performance optimization is to “put script at bottom”. The reason is that while scripts are loading, most browsers block others components from loading. When you put your scripts at the bottom of the HTML document, all components can be loaded without delay, and, in the end, scripts can be loaded.
However, doing this way has some drawbacks :
- One is that the loading of externals scripts is delayed after all other components. Then, browsers have to execute it and the onload event of the page can also be delayed due to this late loading.
- Another major drawback is the presence of inline
Of course, as externals scripts are loaded at the end of the page, any inline script that needs to use it has also to be pushed at the end of the page. This can be quite easy when the HTML page is hand-made.
Especially when working with jQuery, if you load it at the bottom, all preceding
jQuery('document').ready()calls will fail.
I’ve been wondering for a long time if it would be possible to get rid of these drawbacks while reaching the following goals:
- early external jQuery loading
- non blocking jQuery loading that allow other components on the same page to be loaded in parallel, including jQuery plugins
- non blocking inline script in the HTML document, that could call
jQuery('document').ready(), even when jQuery and its plugins havent’ been loaded yet.
jQl is my solution.
jQl an inline loader
As our purpose is to async load an external script, the loader can’t be external. It has to be embedded inline in the HTML, and as short as possible.
At the moment jQl is 700bytes minified and gziped. It is small enough to be embedded in every HTML page.
Asynchronously loading jQuery
This asynchronously loads jQuery without blocking other components:
jQl automatically catches all
jQuery().ready() calls, so you can write:
jQl will queue these function calls, and execute them as soon as jQuery is loaded and the DOM is ready, as they would be executed in the usual way.
jQl also support the shorthand form :
and of course, the
$ syntax works also :
You can see a demonstration of this on http://www.yterium.net/jQl/demos/jquery-loadjQ.php
loadjQ can also get a callback function as the second argument. This is a function that will be called as soon as jQuery is loaded and jQl booted (most often, this will happen before the document.ready event).
This can be used to launch a special operation that needs jQuery but can occur before document is ready:
Most of times, we will also load jQuery plugins. A good practice is to concatenate all scripts into one large file in order to be able to load it with only one HTTP hit, and call the loadjQ method on the big script.
Asynchronous parallel loading of jQuery plugins
However you sometimes want to keep all your scripts dispatched into two or more scripts.A good reason could be web performance optimization!
Let’s explain this.
Aggregating all externals scripts in only one is sure a good practice. But it can lead to large file, and if all the rest of your page is fast loading because it is also well optimized, the unique script file downloading can become critical. In this case, splitting it in 2 or 3 files could be a good idea, if only the browser is able to download these scripts in parallel and execute jQuery-dependent modules only when jQuery is loaded.
This can be done with jQl !
The loadjQdep function helps download jQuery-dependents modules in parallel with jQuery downloading, while still executing them in the correct order. Example:
jQuery and myplugin will be downloaded in parallel. Then, as soon as jQuery is loaded, jQl will wait for the myplugin script to finish downloading (if it is not already present) and then will execute all catched inline calls to jQuery.ready() function.
If myplugin is faster to download than jQuery, it will be queued, waiting jQuery to be run, and if it is longer, it will run as soon as it is downloaded.
You can load several jQuery dependent modules in parallel, all of them will be queued and only called when jQuery is present.
One limit to loadjQdep is that only scripts from same domain as the HTML page can be loaded with, as it uses XHR loading.
It’s a good solution to improve jQuery loading in HTML documents composed in an automated way.
To try it, just replace your conventional script call by inlining minified version of jQl and loading your script :