简体   繁体   中英

How defer attribute should work when loading several js files?

I have the following example:

<script >
    console.log('first');
</script>
<script defer>
    console.log('last');
</script>
<script>
    console.log('second');
</script>

right in the head of my html, and I expect the console to print them in the asc order (first-second-third), however, what I actually see follows the order in which those scripts where placed (first - last - second).

I thought the 'defer' attribute will load the script, but will execute is until the DOM has been completely loaded. Dunno why this is not happening.

Regards,

The defer attribute applies to scripts that are loaded via a src attribute with a URL, not for inline scripts.

You can see the whole HTML5 specification logic of the defer and async attributes here: Load and execute order of scripts .

If you go through all the HTML5 rules in that above post, you will find that none of them match the situation you have because there is no src attribute on the <script> tag. As such, it hits the last situation:

Otherwise The user agent must immediately execute the script block, even if other scripts are already executing.

The end result is that the defer attribute has no effect on script tags that are inline and do not have a src attribute.


If you want to execute that middle <script> after the other two, then you will need to either change it's order, insert it dynamically at the appropriate time or put the code into a separate script file so you can use a src attribute on the <script> tag.

You may need to use a different solution

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script

Since this feature hasn't yet been implemented by all other major browsers, authors should not assume that the script's execution will actually be deferred. The defer attribute shouldn't be used on scripts that don't have the src attribute. Since Gecko 1.9.2, the defer attribute is ignored on scripts that don't have the src attribute. However, in Gecko 1.9.1 even inline scripts are deferred if the defer attribute is set.

I would suggest using a module loader like SystemJS to ensure modules are loaded synchronously. https://github.com/systemjs/systemjs

System.import('./script1.js').then(function(m) {
    System.import('./script2.js').then(function(n) {
        console.log(m, n);
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM