Influence of JS, CSS, and img on the DOMContentLoaded event, domcontentloaded
The pure front-end technology is the cognition of norms.
What is a DOMContentLoaded event?
The first thing that comes to mind is to check the W3C HTML5 specification. When will the DOMContentLoaded event be 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 will execute when the document has finished parsing is not empty, run these substeps:
2.1 Spin the event loop until the first script in the list of scripts that will execute when the document has finished parsing has its "ready to be parser-executed" flag set and the parser's document has no style sheet that is blocking scripts.
2.2 Execute the first script in the list of scripts that will execute when the document has finished parsing.
2.3 Remove the first script element from the list of scripts that will execute when the document has finished parsing (I. e. shift out the first entry in the list ).
2.4 If the list of scripts that will execute when the document has finished parsing is still not empty, repeat these substeps again from substep 1.
3. Queue a task to fire a simple event that bubbles namedDOMContentLoadedAt the Document.
The specifications are always so obscure, but at least one thing can be clarified is that the DOMContentLoaded event will be triggered after JavaScript (excluding dynamically inserted JS) is executed.
Next, let's take a look at the DOMContentLoaded event documentation on the MDN:
The DOMContentLoaded event is fired when the document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading
Note: Stylesheet loads block script execution, so if you have<script>After<link rel="stylesheet" ...>, The page will not finish parsing-and DOMContentLoaded will not fire-until the stylesheet is loaded.
In this case, we can come up with at least one theory: the DOMContentLoaded event will not wait for the loading of CSS files, images, and iframe.
The trigger time is: after loading the page, parse all the labels (excluding executing CSS and JS), and set as described in the specification.interactiveAnd execute JS in each static script tag, and then trigger.
The execution of JS needs to wait for the CSS loading at the front of it (if it is external), and the execution is completed, because JS may depend on the CSS calculation style at the front of it.
Practice is the only criterion for testing truth
Experiment 1: The DOMContentLoaded event does not directly wait until the loading of CSS files and images is complete.
Index.html:
<!DOCTYPE html>
Figure 1
If no script tag exists on the page, the DOMContentLoaded event does not wait until the CSS file or image loading is complete.
The Timeline panel of Chrome developer tools can help us record every action of the browser. The blue line in the red box in Figure 1 represents the DOMContentLoaded event, and the red lines and green lines on the right represent the load event and First paint respectively, when the mouse hover exposes a small part of the gray box under these lines, there will be a tips with instructions (this interaction is anti-human, right !).
Experiment 2: The DOMContentLoaded event must be triggered only after JS execution.
Index.html:
<!DOCTYPE html>
Main. js:
Console. timeStamp ('external script after link in body ');
Figure 2
If the script tag is written statically on the page, the DOMContentLoaded event must be triggered only after the JavaScript code is executed.
The JS in the script tag needs to wait for the loading of CSS located above it to complete.
Console. timeStamp () can be used to add a record to Timeline and correspond to a yellow line above it.
The worker can be executed only after it is loaded. The DOMContentLoaded event is triggered only after JS execution. Slide the slider of the display area in the Timeline panel. 3. zoom in to see the blue line of the DOMContentLoaded event (the Blue Line was too close to the Yellow Line and the Green Line). Of course, you can use the console. the record added by timeStamp () to TimeLine can also prove its trigger time.
Figure 3
Modern browsers will concurrently pre-load CSS and JS, that is, request these resources at the beginning. However, the execution sequence of CSS and JS is still in the original dependent Order (the execution of JS is waiting for the loading and execution of CSS and JS located before it ). Resources loaded first. If the dependencies are not loaded or executed, they can only wait.
Experiment 3: When does img start decoding and rendering?
From figure 3, we can find an interesting point: the img request has been sent for a long time, but it is delayed for a while before decoding starts. 2. As shown in the red box in Figure 3, only a part of the decoded records are displayed. In fact, the decoded records continue until the img loading ends, as shown in figure 4, img is decoded while loading:
Figure 3
Modern browsers will concurrently pre-load CSS and JS, that is, request these resources at the beginning. However, the execution sequence of CSS and JS is still in the original dependent Order (the execution of JS is waiting for the loading and execution of CSS and JS located before it ). Resources loaded first. If the dependencies are not loaded or executed, they can only wait.
Experiment 3: When does img start decoding and rendering?
From figure 3, we can find an interesting point: the img request has been sent for a long time, but it is delayed for a while before decoding starts. 2. As shown in the red box in Figure 3, only a part of the decoded records are displayed. In fact, the decoded records continue until the img loading ends, as shown in figure 4, img is decoded while loading:
Figure 4
With the idea of "conjecture-Verification", I guess this is because the img resource needs to be presented and waited.All JS and CSS operations are complete.Because main. js may execute some DOM operations, such as deleting the img element or modifying its src attribute, CSS maydisplay: none.
Figure 5
Figure 6
Figure 7
No JS or CSS is shown in Figure 5. the img data is decoded as soon as it is received.
No JS is shown in Figure 6, but img does not start decoding until the CSS is loaded.
The only difference between the code in Figure 7 and the code in Figure 6 is that CSS gives the imgdisplay: none;This makes the img request, but it is not decoded at all.
This shows whether img needs to be decoded and painted. It does need to be known after CSS loading and execution. That is to say, CSS will block the display of img! What about JS?
Figure 8
Figure 8 code:
<!DOCTYPE html>
Surprisingly, on pages without CSS, img can decode and draw (paint) immediately after receiving the data. That is to say, JS does not block the display of img! This is not the same as the traditional idea that JavaScript will block img resources we previously understood. It seems that Chrome has made new Optimizations to img loading and expansion.
$ (Document) of jQuery ). the ready () method is to listen to the DOMContentLoaded event (of course, it also provides a degradation solution by simulating the DOMContentLoaded event and listening to the onload event ). We recommend that you register an event for the DOM element when the DOMContentLoaded event is triggered. Therefore, triggering the DOMContentLoaded event as soon as possible means that the page can be interacted as soon as possible:
Reduce the volume of CSS files, divide a single CSS file into several files for parallel loading, and reduce the blocking time of CSS on JS.
The secondary JS file is loaded by dynamically inserting the script tag (the dynamically inserted script tag does not block the triggering of the DOMContentLoaded event)
The sprite used in CSS can be preloaded to img and loaded together with the CSS file in html.
During the experiment, I felt that the Timeline Panel of the Chrome developer tool was very powerful, and all the changes made by the browser were recorded. In the past, we wanted to understand and explore the internal behavior of browsers in front-end development, or conduct a black box test by feeling the stones, or to study the source code of browsers, the only efficient way is to learn from others' research experience and read foreign articles, but the development of browsers is changing with each passing day (for example, the JS found in this experiment does not block img display ), the experience of others is never the latest and most suitable. The key is to make targeted Analysis and Optimization Based on your own business and demand scenarios.
PS.
The above test environment is windows/chrome and uses Fiddler to simulate a slow network
Img and css
Img must be written in one line
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<Meta name = "Generator" CONTENT = "EditPlus">
<Meta name = "Author" CONTENT = "">
<Meta name = "Keywords" CONTENT = "">
<Meta name = "Description" CONTENT = "">
<Style type = "text/css">
*{
Margin: 0;
Padding: 0;
}
Img {
Width: 120px;
Height: 350px;
Border: solid black 1px;
}
</Style>
</HEAD>
<BODY>
<Div>
</Div>
</BODY>
</HTML>
How can I use JS to change CSS attributes?
Onmouseover = "this. style. borderColor = 'red'" onmouseout = "this. style. borderColor = 'Gray '"