Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

<script type="module"> loading performance

I imagine a popular use case for <script type="module"> will be for loading a "main module," from which all of a project's dependencies are resolved through a tree of import statements. However, on the web, it seems like this would create a loading bottleneck, as the browser could not know which scripts to download until it parsed their dependents for import. Contrast this to a situation where all of a project's scripts are referenced in separate <script> elements in the initially-delivered HTML file. The scripts could all download in parallel, while and after the HTML is parsed.

Will <script type="module"> create a loading bottleneck? Can multiple <script type="module"> elements on a page provide dependencies for each other, so the browser doesn't necessarily need to download and parse JavaScript to figure out what to download next?

I suppose this would be a use case for HTTP/2 PUSH_PROMISE? The server would need to statically analyze the JavaScript files and determine their dependencies ahead of time. But even if the browser could be told to download the modules early, I wonder if the pushed modules would still not execute until import was parsed. At least with <script>, I know they would execute at the first opportunity.

like image 347
Jackson Avatar asked May 12 '16 19:05

Jackson


1 Answers

<script type="module"> can probably load modules just as efficiently as <script> + a dynamic module loader.

Multiple <script type="module"> can provide dependencies for each other. Source (via IRC):

Me: If I have a <script type="module" src="a.js">, where "a.js" will export a module, and I also have <script type="module" src="b.js">, and "b.js" will import "./a.js";, will the same instance of the module created by the former <script type="module" src="a.js"> be used?

annevk: if they're in the same document, yes

This is because repeated imports draw from a per-Window "module map" (see the spec):

If module map contains an entry with key url, asynchronously complete this algorithm with that entry's value, and abort these steps.

By creating multiple <script type="module"> elements, we can avoid the "dependency tree bottleneck" by making the browser aware of the scripts it needs to download at the first opportunity.

"Module scripts" defer the evaluation of a module until all its dependencies are fetched; whereas "classic scripts" just execute, so a dynamic module loader could theoretically be faster. But if that dynamic module loader also blocks execution on dependencies, its task will probably take just as long to complete as it would with import. Also, the real threat to performance is probably networking; evaluation is likely so fast in comparison that it'd be trivial.

like image 71
Jackson Avatar answered Oct 05 '22 09:10

Jackson