Home > Article > Web Front-end > JavaScript non-blocking loading and defer, async
Non-blocking loading
Put js in the head, how does the browser execute it, is it loaded sequentially or in parallel? Under old browsers, they are loaded in order, which ensures that there will be no problems with the loaded js dependencies. However, a small number of new browsers have begun to allow parallel loading of js, which means that js files can be downloaded at the same time, but the files are still executed in sequence.
No problem if the download is asynchronous, but each javascript is still synchronous when executed. That is, the script tag that appears first must be executed first. Even if it is downloaded in parallel, it will be the last download to complete, unless it is marked with defer script tag. Any javascript will interrupt the parsing of the current HTML document when executed, which will naturally prevent the page from rendering.
Javascript loading will not affect the rendered page, but will interrupt the HTML document parsing. The browser will decide whether the current document needs to be re-rendered or the document rearranged after the JavaScript is executed. Therefore, even if the JavaScript is placed at the end, the browser will be paused, but it will not affect the previously parsed DOM document, which is operable for the user at this time.
Javascript will be executed immediately after downloading. All javascript execution will block other behaviors of the browser, such as blocking the execution of other javascript, the execution of other http requests, and the parsing and rendering of the page. (The downloading of external js in the HTML document will also block the browser's behavior, but the download of dynamic js by creating a script element will not. It may be that the dynamic js will not change the page effect, so parallel downloading of resources is allowed.)
Image dynamic script download
The UI thread will load resources according to the order in which the resources on the page (resources refer to css files, pictures, etc.) are written. Loading resources means using http requests to obtain resources. When the http request for resources such as css external files, html files, and pictures is processed, it means that the resource loading is completed. However, the loading of external javascript files is different. Its loading process is divided into It is a two-step process. The first step is the same as loading css files and images. It is to execute an http request to download an external js file. However, after JavaScript completes the http operation, it does not mean that the operation is completed. The UI thread will then execute it. The downloading and execution of js script must be a complete operation and cannot be separated. The download of dynamic js will not be blocked, but the execution will definitely be.
In order to improve the user experience, the browser speeds up the execution of the UI thread is an unavoidable problem, but splitting the download and execution of js is not feasible. If the browser changes its method, this method will also That is, multiple resources can be downloaded at the same time.
Put commonly used and stable static resources on a static resource server and provide them to the outside world through a unified domain name. This domain name must be different from the domain name requested by the subject. The principle is because the browser only uses the domain name to Limit the number of connections. If there are two different domains in a page, the number of parallel http requests will also be doubled. There is some overhead in DNS resolution, so 2 are the best.
Divide all external js code into UI initialization code and other codes. UI initialization code is the code that is executed when the page is loaded. Let the loading and execution of js code that will not be used for page initialization display be triggered through the onload event after the browser busy indication ends, that is, let those js scripts that have nothing to do with page loading be executed in the onload method
The core technology of non-blocking script loading is to dynamically create the DOM node of the script, and it can be accessed across domains.
var script=document.createElement("script"); script.type="text/javascript"; script.src="file.js"; document.getElementsByTagName("head")[0].appendChild(script);
Dynamic script elements, that is, the <script> tag is not hard-coded in HTML, but generated by an existing script, because < The ;script> tag is also a type of DOM element, and JavaScript can operate DOM through the DOM API. Dynamic scripts only start downloading when the new script element is added to the HTML document, and are executed immediately after downloading. </script>
The advantage of non-blocking scripts is that they will not block the execution of the UI, nor will they affect the execution of other synchronous js codes. Non-blocking scripts change the loading order of the scripts, so be sure to use them when using non-blocking scripts. Pay more attention to the dependencies between scripts to ensure that scripts on the entire page can be executed normally.
With non-blocking scripts, it doesn’t matter whether the code is placed in the head tag or at the bottom of the html document.
The total page loading time is not a measure of page loading speed. The page synchronous blocking loading time is an accurate measure of page loading efficiency. Non-blocking script loading may increase the entire page loading time, but it It can reduce page blocking loading time.
The asynchronous execution of scripts will cause dependency problems. After the script is loaded and executed, non-IE browsers will trigger the onload event of the <script> element. There is an onreadystatechange event under IE browsers, and we can put the callback in this event for processing. </script>
Whenever the browser parses the <script> tag (whether inline or external link), the browser will prioritize downloading, parsing and executing the javaScript code in the tag, and blocking the downloading and downloading of all subsequent page content. render. (That is to say, the downloading of external js will also block other threads. Currently, a small number of browsers support parallel downloading of js) </script>
The core of non-blocking script loading technology is: when dynamically downloading js scripts, no Blocks the execution of the UI thread. Why don't dynamic scripts block the ui thread? It may be because the browser thinks that dynamic resources will not affect page rendering.
Two attributes that make script delayed and asynchronous: defer and async
js script will change the content of the document input stream, so the rendering of the page will be paused when executing js . There is no problem with inline scripts because the script and html document are loaded at the same time. But for externally introduced scripts, the download of the script (depending on the network speed) will also block the parsing and rendering of browser documents, and even block some browsers from downloading other resources (some browsers have already implemented parallel downloading). Therefore, defer and async attributes appear to optimize the display of the page.
defer (delay) is defined in HTML4.0. This attribute allows the browser to delay the downloading of scripts. After the document document is loaded and parsed, it will be downloaded and parsed in the order in which they appear in the document. . In other words, the <script> of the defer attribute is similar to the effect of placing <script> at the bottom of the body, and will be executed before the DOMContentLoaded event of the document. </script>
It is better to place the script at the bottom of the body than to add the defer attribute to the script to lazy load the script.
async (asynchronous) is a new attribute of HTML5. The function of this attribute is to allow the browser to download scripts in parallel without blocking the browser's document parsing and rendering. After the download is completed, the script is executed immediately and may be out of order. Execution, depending on the time when the download is completed)
If the browser supports both the above attributes and the script tag has both attributes, the async attribute will take effect better than defer.
In browsers that do not support the async attribute, you can dynamically create a script element and insert it into the document to achieve asynchronous loading and execution of the script:
requirejs is implemented using this method.
For more articles related to JavaScript non-blocking loading, defer and async, please pay attention to the PHP Chinese website!