preface

The script tag is used to load scripts and execute scripts, and is a very important tag in front-end development. Using a script script directly, HTML loads and executes the script sequentially, blocking subsequent DOM rendering while the script is loading and executing.

Nowadays, we are used to referencing various third-party scripts in the page. If the third-party service provider has some minor problems, such as delay, the page will go blank. For the above situation, the script tag provides two ways to solve the problem, that is, adding properties async and defer. These two properties allow script tag loading to occur without blocking DOM rendering.

And the existence of the above two attributes, that means that there must be differences between the two attributes.

defer

If the script tag sets the defer property, the browser downloads the file asynchronously without affecting subsequent DOM rendering. If multiple Script tags exist with the defer property set, all of the scripts are executed in sequence, and the defer script is executed after the document has been rendered and before the DOMContentLoaded event is called.

In response to the above theory, we wrote a test case where the page contained two script tags loaded with the defer tag on both of them, adding 1s delay to script1.js and 2s delay to script2.js.

The following figure shows the page loading process and the output order of script scripts. It is not hard to see that the loading time of script1.js is shorter than script2.js, but due to the restriction of defer, script1.js can only be executed after the preceding script is finished.


async

The async property causes scripts to be loaded asynchronously and executed when allowed. Async execution does not follow the order in which script tags are placed on the page, but rather who finishes loading first.

Modify the above case code as follows:

The following figure shows the page loading process and the output order of script scripts. Although there is no change in page loading time, one detail that can be noticed is that the DOMContentLoaded event is not affected by async script loading and is triggered before the script is loaded.


conclusion

Here’s a gantt chart for loading multiple scripts, with four different colors to indicate what each represents:

Regular script

If a script script is encountered in the process of document parsing, it will stop the page parsing and download, and Chrome will perform an optimization. If a script script is encountered, it will quickly check whether there are other resources that need to be downloaded. If there are, it will download those resources first, and then download the corresponding resources of the script. This will save some of the download time.

Resources are downloaded in the process of parsing. Although script1.js will be loaded quickly, script2.js before it is not loaded and executed, so it can only be in a suspended state, waiting for script2.js to be executed after it is executed. Continue parsing the page when both scripts are finished.

defer

When a script with the defer attribute is encountered during document parsing, it will be downloaded in the background, but the rendering of the document will not be prevented. When the page is parsed, all defer scripts will be loaded and executed in sequence, and the DOMContentLoaded event will be triggered when the script is executed.

If your script code depends on DOM elements in the page (whether the document has been parsed) or is dependent on other script files, use the defer attribute.

async

The async script will be executed after loading, and the loading of async script is not counted in the DOMContentLoaded event statistics. Both cases in the following figure are possible.

Use the async property if your script doesn’t care about DOM elements in the page (whether the document has been parsed or not) and doesn’t produce data that other scripts need.


data

Code link: github.com/Wutongjiaoj…

After clone, run NPM start.