My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Thursday, February 20, 2014

the underestimated problem about script async attribute

While authoritative bloggers seems to suggest script async attribute as the holy grail on HTML documents for non blocking JavaScript overall performance, you might probably know async behavior is not necessarily desired at all, here I'll try to explain why.

first of all: why script async

Before talking badly about this attribute, it's necessary to understand reasons behind.
async attribute aim is to not block network traffic.
Differently from deferred, where the order of scripts is preserved and the fact scripts will be parsed and executed before the DOMContentLoaded event would be regularly fired, async scripts download and parse might occur at any time before or after the DOMContentLoaded as well as the onload event have been already fired.

<script async="shenanigans">

Yes, if your library, framework, utility, entire Web App, relies for some reason to the DOMContentLoaded event listener, or even the classic window.onload event, in order to initialize anything, such attribute will not guarantee that behavior at all: it's the other way round!
If the script tag is on top of the head of your page, the only place where defer or async make sense in order to not block the download of anything else in the page, it might be executed while the document is still donwloading as well as after everything else, in terms of DOM, has been interpreted already.
This situation is the most common one and not the less probable as you might think, 'cause the moment your script tag is interpreted, is the moment the browser knows already the content of the page.
From that point, to trigger a DOMContentLoaded event takes really nothing, milliseconds speaking.
If your script add that listener after, your script will never be triggered.

fixing the DOMContentLoaded

Long time ago, DOMContentLoaded in Firefox was the revolution for scripting initialization ... today this event looks ugly and unreliable, with its capital letters in the event type description, its past in the verb form compared with load which is not loaded indeed, and at the same time is the most used event ever for anything that would like to operate before the user.
In this universal common case, it's ridiculous that such event, happened in the past as Loaded would suggest, will never trigger again in the document unless somebody manually tries to do so, screwing all libraries, frameworks, or application logic, that forgot to removeEventListener once such event used for initialization has been fired ... you know what I mean?

Once For All: Fixed!

This script has no license on purpose ... I don't really care if you remember me once you used this script on top of your page and inline, I really don't want you to even think about this post once you can sleep well thinking the DOMContentLoaded event triggered your initialization script ... really, just use this script for reliability sake and forget about problems related to asynchronously loaded scripts and libraries.
Anything that will trust such event, will be triggered ... and yes, all CSP can be used as well without problems so ... no excuses, just enjoy!

No comments: