We’ll also take the opportunity to explain the details of the solution we’ve developed: a feature called DeferJS.
What is a blocking script and why does it slow down the loading of a web page
We explained this process in a previous article, the principle is illustrated here :
The code may contain on premise scripts or scripts from third parties. Be aware that in the second case, as the browser has to fetch the third party scripts from where they are located (on a remote server, a cache...), the time needed for loading is even longer, and your performance may be impacted.
Making a script “non-blocking” with Async and Defer attributes
The HTML code contains information that guides the browser, which can be oriented using additional instructions that direct its work.
- Async: to download the script while continuing to parse the HTML to build the DOM, and execute the script once it is available. This is a recommended option especially for third party scripts or scripts that do not impact other files, this attribute improves the UX but may block the HTML parsing at runtime;
Smartly automate the rewriting of code to Defer script execution
As we’ve seen, to make a blocking script “non-blocking,” an essential point you have to take into account is the potential dependency between scripts.
Indeed, the first scripts generally declare libraries (like JQuery) which will be used by the scripts included in the page or declared later.
For this reason, you can’t apply an async attribute (which doesn’t follow the HTML parsing order to execute the scripts) to them because that would mean risking the library not being ready when it’s supposed to perform.
And what about the Defer attribute? That could work because it allows you to keep the script execution order, but… only on the condition that it applies to all scripts and that no script built into the page has dependencies with libraries. This is a very rare case—you’d be better off looking for a needle in a haystack.
Given these clarifications, you can understand why it’s difficult to systematically use the Async and Defer attributes, since they don’t account for the cases where scripts change the DOM in the declared location (via document.write).
So, now let’s talk about our favourite subject: smart automation of web performance optimizations!
You can get around the limitations of async and defer by orchestrating the execution of JS, and that’s exactly what DeferJS does.
In practical terms, here’s how DeferJS works:
- The blocking scripts are only executed at the time of DOMContentLoaded to reproduce the behaviour of the Defer attribute and not block the initial rendering of the page.
- The deferred scripts can write in the DOM at the location provided for in the document.write instructions. They can then correctly make calls to the DOM by simulating a partially built DOM up to the script node (even if the DOM is only really constructed at the time of execution).
As an orchestrator, DeferJS takes into account any declarations of the Async and Defer attributes present in the <script> tag to maintain loading properties as provided for in the code.
Did you know?
So, what happens in the HTML file? The src attributes of the <script> elements are transformed into frz_orig_src and the engine adds a new type of attribute whose value is defined as text/frzjs. A window.onload manager is added to the HTML, which then execute all of the deferred scripts.
Script before and after being optimized with DeferJS feature
And that’s not all! We also add a pre-loading link to each deferred script to ensure they load as fast as possible. That compensates for the fact that the pre-scanned HTML can’t discover the URL of the scripts before knowing the attributes.
Proper usage of DeferJS
In what situations is DeferJS most useful? Mainly for scripts that have an impact on the interactivity of the page.
Are there situations where it’s better to avoid deferring the scripts? Yes!
It’s worth noting that for A/B testing scripts that may greatly modify the DOM and for scripts managing carousels or the lazy-loading of images, deferring would only delay complete display of the page.
That’s why this feature allows for precise settings so that you can isolate scripts critical for page rendering and choose tags to be excluded from processing.
Like all of our features, DeferJS is continuously improved to help you better manage your third party scripts and have better and better responsive pages.
Curious about our features to improve your loading speed and user experience?
Find here all the reasons to automate your frontend optimization:
up to +40% conversions rates and +25% of SEO traffic ... and many more :