Non blocking CSS load on the page
Load external CSS files in an async manner
Like JavaScript, CSS files are also loaded on the page by default in a blocking manner. Luckily for us, for JavaScript we can use either async or defer attributes on the script tag itself to change the behavior of JavaScript external file loading.
There is a different between these two attributes, but this is not the subject of this article.
Just as classic JavaScript external file load blocks loading of the page, standard CSS external file load also block loading and rendering of the page. Unfortunately, loading of external CSS file in an async manner is not that easy as with JavaScript.
HTML currently does not support this, so we need to make a hack to make CSS files load asynchronously. Since we are going to do this by using JavaScript, we need to make sure our website renders properly even if the JavaScript is not supported in the browser which is loading the page.
This is the reason why we are going to load CSS files in NOSCRIPT tag like following:
<noscript id="async-stylesheets"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" /> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" /> </noscript>
If you put this NOSCRIPT tag in your page, nothing will happen. Content of NOSCRPT tag executes only if JavaScript is off in the browser, which rarely the case. As I mentioned before this is just a fall-back to our async CSS load functionality.
You notice that we declared an id attribute for NOSCRIPT tag. This is because we want to reference this tag to pull out all referencing CSS and load them dynamically.
Now we are going to load the CSS dynamically, but since we do not want to block our document load, we are going to do it once the page is loaded completely. For that we will have to add a page load handler in a JavaScript code:
document.addEventListener('DOMContentLoaded', function () {var noscriptContainer = document.getElementById("async-stylesheets");if (noscriptContainer != null) {var container = document.createElement("div");container.innerHTML = noscriptContainer.textContent;document.body.appendChild(container);}}, false);
Now if you try to load the whole document you will see that CSS files are loaded.
References
- https://www.w3schools.com/tags/att_script_async.asp
- https://www.w3schools.com/tags/att_script_defer.asp
Disclaimer
Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.
Comments for this article