Deferred loading of resources can tremendously increase the percievable load time of a web page. That can be easily done with Javascript files which is described here or with HTML5’s async attribute.
If we do not use the async
attribute, we
- create a
script
element, - assign the element’s
src
property to the value of the URL of the script, - assign the
onload
oronreadystatechange
handler function to determine when the script has actually loaded - attach the newly created
<script>
element to thehead
element of the document
However that is not so easy with CSS stylesheets. Actually, the main problem is that link
element does not always have the onload
event to determine whether the element has loaded. It is important when we have to perform the necessary initialization operations, like removing the “loading” screen etc.
As a workaround, we use polling: create a well-known stylesheet rule with an element on our page that we monitor after we add the link
element to the page. When we detect the known property change of the element, we trigger the callback function. This method has already been described on the require.js home page as well, however the thing they lack is actual code to do this 🙂
The code
I wrote a require.js plugin, called “require-css”, which is available on Github. To use it, all you have to do is to (1) add CSS rule to your stylesheet sample.css
that defines the height
property: .sample-css-loaded { height: 1px; }
, and (2) call the require
function as follows:
require(['css!css/sample.css'], function() {
alert('Stylesheet has been loaded');
});
What this CSS loading plugin does is:
- creates the
link
element with the necessary attributes and adds to the document’shead
element - creates an absolutely off-screen positioned (to avoid any visual glitches on the page) dummy
div
element and adds to the document’sbody
element - in
window.setInterval
callback function, monitors the test element’soffsetHeight
property and when it is greater than zero, clears the interval, removes the dummy element, and calls the require.js’ callback method;
Additional notes
The plugin can be extended by assigning any arbitrary CSS property to monitor, something like
require(['css!css/sample.css#offsetWidth'], function() {
...
});
offsetWidth
could be replaced by any other property whose value type is length
.
I guess, that would be useful when user of the plugin has no control over the CSS he or she wants to load, however I haven’t had such a use case yet.
This was a really wonderful post. !!!!!! Thank you for providing this information
Thanks for sharing the information
Thank you for sharing GTU