Script-injected "async scripts" considered harmful
igvita.com
igvita.com
[1]: https://developers.facebook.com/docs/javascript/quickstart/v...
Problem is, of course, that the technologies used by a common page nowadays go far beyond the stuff present in H5B.
One commonly used variant I missed in the article and I'd be interested what it's positive/negative aspects are (if there are differences at all):
<script>
var script = document.createElement('script');
script.src = "http://example.com/awesome-widget.js";
script.async = true;
document.getElementsByTagName('head')[0].appendChild(script);
</script>
(Note the additional async param)At least, in Chrome.
<iframe src="/file.js" style="display:none">
And then at the very end of the body tag: <script src="/file.js"></script>
Wont that allow us to start a non-blocking fetch of the script early, but then execute it later? I assume it wont be fetched twice. Especially if you send future Expires headers.If you are including jQuery or similar, there is the option of having your code hook into the "document ready" events. If you are not using something like that then you could pull out what they use and implement that part yourself.
Another option, which is less clean but might be useful if you don't want to wait for all of a load DOM to transfer for instance, is to check for the parts you do need and if they are not yet present set a timer for a few 10s of ms time to check again.
> doesn't work in IE9 or below
I don't suggest holding back on using features because of old IE. Instead make sure your code works in everything but can take advantage of the extra feature in newer browsers. PEople using old IE might get a less than optimal experience, but it'll work, and those using something better get the optimal behaviour.
Of course, this falls down when maintaining backwards compatibility requires noticeable code changes rather than just accepting old browsers won't display things as nicely and/or responsively.
Deleted comment
Now, that doesn't necessarily help for this kind of "top level" code, but wouldn't it be cool if you could say: "Load this <script> tag asynchronously, but only run it once the following other <script> tags finish"? (You can give <script> tags HTML IDs just like anything else, right?)
http://stackoverflow.com/a/10731231/480033
However, browser implementation isn't consistent so there's no guarantees really.
As for why the browser doesn't download the script-injected scripts: they're hidden inside of the inline script blocks. In order to figure out what you intend to do inside of that block, the browser would have to execute the JavaScript. The behavior that you want (download wait for CSSOM) is exactly what you get when you use regular blocking tags - those are discovered by the preloader and requests are dispatched. That's what the first and second diagram in the blog post illustrate.
Quick test in FF: seems it blocks either way, but at least schedules the fetch in the async=true case http://i.imgur.com/AmNjhgz.png
yepnope will load your script as an image away from the DOM so that it's already cached by your browser.
Why isn't defer more popular?
Also, if you need to wait for DOM/CSSOM, then you can still use an async script and just install an event listener for DomContentLoaded / DomInteractive / etc., when it loads.
However, that problem is complex to workaround.
Using the async flag doesn't fix that problem, and the async flag also means that you need to make sure your scripts can run in any order (which will cause problems unless you are very careful e.g. use a loader that manages dependencies asynchronously).
A. At onDOMContentLoaded and B. Inside a setTimeout(func, 0) block
Then the browser's loading indicator will stop before the script has been loaded, executed and all its assets loaded.
Useful for social media widgets, etc.
Which is to say: if it were that harmful, then maybe you could try fixing them yourself and tell us how it goes? It would be great to provide some advice on how to convert a few popular script-injected async scripts from third parties (especially Google Analytics) into non-"harmful" ones.
I understand that async also enables quicker execution of the script. What I don't understand however is why anyone would use script injection when you can just put the script tag at the bottom of the page to avoid DOM blocking.
What am I missing?
I suppose you could argue that this approach helps with CDNs, but therein lies another issue of whether or not serving a library from a CDN really buys you anything over just including it with your site's script payload.
(A well written article none the less!)
Well, it does hurt conversion and retention rates, if it causes the page to be rendered slowly. Given how many sites don't load anything until javascript has executed, this could have a meaningful impact on someone's bottom line. And that does hurt businesses and their employees.
It can come off a little arrogant, but he's really just following tradition.