1. What the hell

Today, when I was doing a small need, I suddenly saw a code from my predecessor

    <script src="#link("xxxx/xx/home/home.js")" type="text/javascript" async defer></script>Copy the code

Oh, my God, there were async and defer attributes at the same time. I thought it must be some black technology of the old driver, and there would be some magical chemical reaction between the two. So I quickly went to the books and documents with reverence and reviewed their definitions first.

Do some research

Let’s take a look at the respective definitions of Async and defer, as described in the little Red Book telescope

2.1 the defer

The purpose of this property is to indicate that the script will execute without affecting the construction of the page. That is, the script is delayed until the entire page has been parsed. Therefore, setting the defer attribute in the

The HTML5 specification requires scripts to be executed in the order in which they appear, so the first deferred script will be executed before the second, and the two scripts will be executed before the DOMContentLoaded event. In reality, deferred scripts do not necessarily execute sequentially or before the DOMContentLoad time triggers, so it is best to include only one deferred script.

2.2 async

This property is similar to defer in that it changes the behavior of the processing script. Also like defer, Async only applies to external script files and tells the browser to download the file immediately. Unlike defer, however, the scripts labeled async are not guaranteed to be executed in their order.

The second script file may be executed before the first. So it’s important to make sure they don’t depend on each other. The purpose of specifying the async property is to prevent the page from waiting for two scripts to download and execute, thus asynchronously loading the rest of the page.

In summary, both attributes cause script tags to load asynchronously, but at different times. referencesegmentfaultAn image from one of the answers onThe blue line represents network reads, and the red line represents execution time, both of which are for scripting; The green line represents HTML parsing.

That means async is out of order and defer executes sequentially, which makes Async more suitable for libraries like Baidu Analytics or Google Analytics that don’t rely on other scripts. As you can see from the diagram, a normal

2.3 really?

However, this graph (almost the only answer baidu found) is not rigorous, it is a standard situation, and most browsers will make optimizations when implementing it.

What does Chrome do

WebKit Tech Insider:

  1. When a user enters a web URL, WebKit invokes its resource loader to load the corresponding web page.

  2. The loader relies on the network module to establish a connection, send a request, and receive a reply.

  3. WebKit receives data from various web pages or resources, some of which may be retrieved synchronously or asynchronously.

  4. Web pages are turned into a series of tokens by an HTML interpreter.

  5. The interpreter builds nodes from the words to form a DOM tree.

  6. If the node is JavaScript code, call the JavaScript engine to interpret and execute it.

  7. JavaScript code may modify the structure of the DOM tree.

  8. If nodes need to rely on other resources, such as images, CSS, videos, etc., call resource loaders to load them, but they are asynchronous and do not prevent the creation of the current DOM tree. If it is a JavaScript resource URL (not marked asynchronously), you need to stop the creation of the current DOM tree until the JavaScript resource is loaded and executed by the JavaScript engine.

So, in layman’s terms, Chrome will first request an HTML document, then call the corresponding resource loader to make asynchronous network requests for various resources in it, and render DOM at the same time. When the

3. Experiment One

3.1 the demo

To verify this, let’s take a test

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link Href = "http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.css" rel = "stylesheet" > < link Href = "http://cdn.staticfile.org/foundation/6.0.1/css/foundation.css" rel = "stylesheet" > < script SRC = "http://lib.sinaapp.com/js/angular.js/angular-1.2.19/angular.js" > < / script > < script SRC = "http://libs.baidu.com/backbone/0.9.2/backbone.js" > < / script > < script SRC = "http://libs.baidu.com/jquery/2.0.0/jquery.js" > < / script > < / head > < body > ul > li {this is the first $node} * 1000 < / body > < / HTML >Copy the code

A simple demo that references 2 CSSS and 3 JS from each CDN and creates 1000 Li’s in the body. Verify using Chrome Timeline by adjusting the location of external reference resources and adding relevant attributes.

3.2 placed in the<head>Within the



Load resources asynchronously, but block<body>The render will appear white, and the script will be executed immediately in that order

3.3 placed in the<body>At the bottom of the



Load resources asynchronously, etc<body>Execute JS sequentially after the content is rendered and loaded

3.3 placed in the<head>Header and useasync



Load resources asynchronously, and execute JS resources immediately after loading, not in order, who is the fastest on the first

3.4 placed in the<head>Header and usedefer



Load resources asynchronously and execute JS sequentially after DOM rendering

3.5 placed in the<head>The header is used simultaneouslyasyncanddefer



Performance andasyncConsistent, open an imagination, the two attributes swap positions, to see if there will be coverage effect, the result is consistent = =,

To sum up, under webKit engine, the recommended way is still to write

4. The compatibility

So, what is the reason for trying to figure out the psychology of seniors and writing at the same time? Compatibility?

Caniuse, async not supported in IE<=9, other browsers OK; Defer is supported but buggy when IE<=9 and OK in other browsers; The phenomenon is described in this issue, which is why “Telescope” suggests only one defer. So both properties are specified to enable defer when async doesn’t support it, but defer is still buggy in some cases.

The defer attribute may be specified even if the async attribute is specified, to cause legacy Web browsers that only support defer (and not async) to fall back to the defer behavior instead of the synchronous blocking behavior that is the default.

Conclusion 5.

In fact, the safest way is to write

At present, only Chrome webKit rendering mechanism is studied, Firefox and IE still need to be studied, images and CSS and other external resources rendering to be studied.

More information is available here

reference

  • JavaScript advanced programming

  • Inside WebKit technology

  • The difference between defer and Async

  • www.w3.org