The pure technology of the front end is the cognition of the norm
What is a domcontentloaded event?
The first thought was to view the HTML5 specification for the domcontentloaded, and when the event was triggered:
Once The user agent stops parsing the document, the user agent must run the following steps:
1. Set the current document readiness to "interactive" and the insertion point to undefined.
Pop all the nodes off the stack of open elements.
2. If the list of scripts that would execute when the document has finished parsing are not empty, run these substeps:
2.1 Spin The event loop until the "the" the "the" the "the" of scripts that would execute when the document has finished par Sing has its "ready to be parser-executed" flag set and the parser ' s Document has no style sheet this is blocking scripts.
2.2 Execute the "in the" list of scripts that would execute when the document has finished parsing.
2.3 Remove the ' the ' ' The ' list of scripts that would execute when the document has finished parsing (i.e . Shift out of the entry in the list.
2.4 If The list of scripts that would execute when the document has finished parsing are still not empty, repeat EPS again from Substep 1.
3. Queue a task to fire a simple event that bubbles nameddomcontentloadedAt the Document.
Specifications are always so obscure, but at least one thing is clear, that is, when JS (excluding dynamically inserted JS) after execution, will trigger the domcontentloaded event.
Next look at the documentation on the Domcontentloaded event on MDN:
The Domcontentloaded event is fired then the document has been completely loaded and parsed, without waiting for Styleshee TS, images, and subframes to finish loading
Note:stylesheet loads block script execution, so if you are have a after <script>
a <link rel="stylesheet" ...>
, the page would not finish Parsing–an D domcontentloaded won't fire–until the stylesheet is loaded.
So, at least you can come up with a theory: The domcontentloaded event itself will not wait for CSS files, pictures, and IFRAME loads to complete.
Its trigger time is: Load the page, parse all the tags (excluding the execution of CSS and JS), and as described in the specification of the Setup interactive
and execution of each static script tags in the JS, and then trigger.
And the implementation of JS, you need to wait for it in front of the CSS load (if it is out of the words), execution completed, because JS may rely on the CSS in front of it to calculate the style.
Practice is the only standard to test truth
Experimental 1:domcontentloaded events do not directly wait for CSS file, picture loading complete
Index.html:
Figure I
If there is no script tag on the page, the Domcontentloaded event does not wait for the CSS file or picture to finish loading.
The timeline panel of the Chrome developer tool can help us document the browser's movements. The Blue Line in the small red box in Figure one indicates the domcontentloaded event, and the red and green lines on the right indicate the Load event and first paint, respectively. Mouse hover A small portion of the line below the gray box will appear with tips on the text (this is an interactive enough against human beings, right!). )。
Experimental 2:domcontentloaded events need to wait for JS execution before triggering
Index.html:
Main.js:
Console.timestamp (' External script after link in the body ');
Figure II
If the page is statically written with a script tag, the domcontentloaded event needs to wait for JS to execute before triggering.
and the script label JS needs to wait for the CSS in front of the load complete.
Console.timestamp () can add a record to the timeline and correspond to a yellow line above it.
From figure II can be seen in the CSS before the JS was immediately implemented, and in the CSS after the JS, you need to wait for the CSS to be loaded after the implementation, it is obvious that the main.js has been loaded, but still have to wait until the MAIN.CSS load can be carried out. The domcontentloaded event is triggered after JS is executed. The slider in the sliding timeline panel that represents the display area, such as figure three, can be magnified to see the blue line that represents the Domcontentloaded event (before being too close to the yellow and green lines), of course, through console.timestamp () The record added to the timeline can also prove its trigger time.
Figure Three
Modern browsers will be concurrent preload CSS, JS, that is, the beginning of the concurrent request for these resources, but, the implementation of the Order of CSS and JS or the original dependent order (JS execution to wait at its front of the CSS and JS loading, execution finished). Load the completed resource first, if its dependencies have not been loaded, finished, you can only wait.
When will the experimental 3:img begin to decode and draw?
From figure three we can find an interesting place: the IMG request has been sent out long ago, but it has been delayed for some time to begin decoding. As shown in Figure two, the red box in Figure three, the screenshot shows only a portion of the record that represents the decoding, and in fact, the records that represent the decoding continue until the end of the IMG load, as shown in Figure Four, where the IMG is decoded while loading:
Figure Three
Modern browsers will be concurrent preload CSS, JS, that is, the beginning of the concurrent request for these resources, but, the implementation of the Order of CSS and JS or the original dependent order (JS execution to wait at its front of the CSS and JS loading, execution finished). Load the completed resource first, if its dependencies have not been loaded, finished, you can only wait.
When will the experimental 3:img begin to decode and draw?
From figure three we can find an interesting place: the IMG request has been sent out long ago, but it has been delayed for some time to begin decoding. As shown in Figure two, the red box in Figure three, the screenshot shows only a portion of the record that represents the decoding, and in fact, the records that represent the decoding continue until the end of the IMG load, as shown in Figure Four, where the IMG is decoded while loading:
Figure Four
With the idea of "guessing--verification", I guess this is because the resources of IMG need to be displayed, need to wait for all the JS and CSS execution before you know, Because Main.js may perform some DOM operations, such as removing the IMG element, or modifying its src attribute, CSS may have it display: none
.
Figure Five
Figure Six
Figure Seven
Figure v No JS and css,img data as soon as it was received began to decode.
There is no JS in Figure VI, but the IMG will not start decoding until the CSS is loaded.
The only difference between the code in Figure seven and the code in figure six is that CSS gives the IMG display: none;
, which makes the IMG request, but does not decode it at all.
This shows that the IMG need to decode, drawing (paint) out, really need to wait for CSS loading, execution to know. In other words, CSS will block the display of IMG! What about JS?
Figure Eight
Figure eight corresponds to the code:
Very surprising, in the page with JS and no CSS, IMG Incredibly able to receive data immediately after the start decoding, drawing (paint), that is, JS does not block the display of IMG! This is not quite the same as the traditional notion that JS will clog up the IMG resources as we previously understood it, and it appears that Chrome has made new optimizations for the loading and presentation of IMG.
Our common jquery $ (document). Ready () method is the monitoring of the Domcontentloaded event (and, of course, it also provides a demotion scheme by simulating the domcontentloaded event and listening to the OnLoad event). It is often recommended that you register events for DOM elements when the domcontentloaded event is triggered. So as soon as the domcontentloaded event is triggered, it means that the page can interact as quickly as possible:
Reduce the size of the CSS file, a single CSS file into several files to load in parallel, reduce the blocking time of CSS to JS
Secondary JS files, dynamically inserted script tags to load (dynamically inserted script tags do not block the trigger of the domcontentloaded event)
The wizard diagram used in CSS can be loaded with the CSS file in HTML using preload on img
In the course of doing the experiment, the timeline panel of the Chrome developer tool is very powerful and the browser's every move is recorded. Before our front-end development to understand, explore the browser's internal behavior, or stones to do black-box testing, or less than the research browser source, the only efficient way is to learn from other people's research experience, look at the foreigner's article, But the rapid development of the browser (such as the experiment found that JS does not block the display of IMG), other people's experience is not the latest, the most suitable, the key is to combine their business, demand scenarios, targeted analysis and optimization.
Ps.
The above test environment is Windows/chrome, and using fiddler to simulate slow-speed network