j_d
j_d

Reputation: 3082

How to load webpack bundles async, but execute in order?

I have two webpack bundles, main.js and vendor.js. Obviously, the main.js script has many dependencies inside vendor.js, and vendor must be loaded first.

Currently, at the end of my html doc, I am just doing:

<script src={assets.javascript.vendor} charSet='UTF-8' />
<script src={assets.javascript.main} async defer charSet='UTF-8' />

This way, at least the main.js bundle is loaded async. But if I set both bundles to async, pageload will randomly fail depending on the order of download/execution.

Basically every pagespeed tool complains about vendor.js being "render blocking", even though it's at the very end of my html doc. I don't know how seriously to take this, but is there a way to set both bundles to load async, but ensure execution happens in the right order, without doing stuff like writing script tags from other JavaScript files etc?

This must be a common use case with webpack?

Upvotes: 4

Views: 5087

Answers (2)

Frank Wallis
Frank Wallis

Reputation: 591

If you need DOMContentLoaded to fire before the scripts are executed, but the scripts to execute in order then you could try this approach:

<script>
    function loadScript(scriptPath) {
       var se = document.createElement("script");
       se.src = scriptPath;
       se.async = false;
       document.getElementsByTagName("head")[0].appendChild(se);
    }

    loadScript({assets.javascript.vendor});
    loadScript({assets.javascript.main});
</script>

It relies on the fact that dynamically created elements do not block rendering and setting them to async: false means they will load in order. I'm not sure what the browser compatibility is but it works in Chrome.

Upvotes: 0

Michael Jungo
Michael Jungo

Reputation: 32972

You should use defer for both of them. With defer they will be downloaded asynchronously but executed in the order they appear in the document. For more information see async vs. defer.

<script src={assets.javascript.vendor} defer charSet='UTF-8' />
<script src={assets.javascript.main} defer charSet='UTF-8' />

If you specify both async and defer they will be async if the browser supports it and fallback to defer if not (as mentioned in Can you use both the async and defer attributes on a HTML script tag? ).

Upvotes: 3

Related Questions