4

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?

j_d
  • 2,818
  • 9
  • 50
  • 91

2 Answers2

3

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? ).

Community
  • 1
  • 1
Michael Jungo
  • 31,583
  • 3
  • 91
  • 84
0

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.

Frank Wallis
  • 581
  • 7
  • 12