“This is the fifth day of my participation in the First Challenge 2022. For details: First Challenge 2022.”

I have written two articles before, involving some analysis of the whole process of page access, such as the introduction of page life cycle and the relationship between HTML and JS in the rendering process of page access. The first two articles only focused on JS, did not include CSS, and did not explicitly provide tools for reproduction. This article will use Chrome’s Network and Performance tools to analyze the entire page loading process

  1. Network: analyzes requests, which is used in this paper to analyze the timing relation of sending requests
  2. Performance: analyzes page loading Performance, which is used to view the time sequence of HTML, CSS, and JS parsing

As suggested in the front row, when using the above two tools for analysis, please turn on the traceless mode and close the plug-in allowed to run in the traceless mode, in order to avoid the influence of plug-in script loading on later analysis

CSS

As for the current similar articles, are in the header import adopted delay to simulate CSS may block DOM parsing effect, for static resources such as CSS, they are downloaded by a dedicated download thread, will not block GUI thread (HTML parsing thread), and

To make sense of these two points, I set up two simulation methods, delay and large CSS file respectively, as shown below

<! DOCTYPEhtml>
<html>
  <head>
    <link rel="stylesheet" href="http://localhost:8000/500.css" />
  </head>

  <body>
    <p id="test">When on earth will I be resolved?</p>
  </body>
</html>
Copy the code
<! DOCTYPEhtml>
<html>
  <head>
    <link rel="stylesheet" href="http://localhost:8000/big.css" />
  </head>

  <body>
    <p id="test">When on earth will I be resolved?</p>
  </body>
</html>
Copy the code

In delay mode

In large file mode

If you look closely at the two blue dotted lines above, where the DCL is, it’s all done a little bit before the CSS loads, for the assumption above

  1. Synchronous request blocking
  2. Large file blocking

Does not affect the parsing of HTML (note: the request for an external style CSS actually occurs before Parse HTML)

We can also see from the above that delayed blocking and large file blocking work in the same way, so the following demo will use the delayed solution

CSS in the header blocks page rendering

Read HTML page load is actually in the process of asm, so the content of the page is a little bit of print/rendering out, so there is the emergence of the First Plain meaning for the page is loaded into the page content from the start, any part of the time to finish the apply colours to a drawing on the screen, in today’s headlines access, for example, when the page is still in the circle, In fact, most of the page content can already be seen. The reason why it is still spinning is that the images and other resources have not been downloaded. According to the definition of the white screen time, it is the time before First Plain.

CSS blocks page rendering to avoid repeated page rendering (e.g. Red -> green -> white ->…) In the two pictures, the red part is LOAD, and the green part is First Plain, that is, the page renders for the First time. It can be seen that the CSS in the head blocks the page rendering and does not block the DOM

Exceptions to the rule

When is placed in the middle of some elements, it blocks dom parsing, as shown in the following example

<! DOCTYPEhtml>
<html>
  <body>
    <p>When on earth will I be resolved?</p>
  </body>
  <! Send CSS files after 500ms -->
  <link rel="stylesheet" href="http://localhost:8000/500.css" />
</html>
Copy the code

The results are as follows

Shock!!! DOMContentLoaded comes after Load (red line is Load, blue line is DOMContentLoaded), at least in Chrome’s Performance

What about parsing HTML? See below

The time interval between HTML parsing has been interrupted, that is, the loading of CSS has blocked the parsing of HTML, that is, THE parsing of DOM. Unlike in the case of tags, DOMContentLoaded needs to wait for the full loading of CSS. CSS does not block DOM parsing, which is incorrect in this case

That is, there is a special case where an inline style at the end of a DOM element blocks parsing of the HTML immediately after

JS and CSS

JS does block DOM parsing, detailed content can see this article, page access rendering process in HTML, JS relationship, that if JS and CSS together? The above analysis gives the external style CSS in the head and tail are different situations, and without CSS, put JS in any part of HTML will block DOM parsing, then CSS mixed JS can have the following four situations

  1. Introduce an outbound style in the header<head>... <link />... </head>
    1. JS in front of the CSS<head>... <script></script>... <link />... </head>
    2. JS after the CSS
      1. <head>... <link />... <script></script>... </head>
      2. <head>... <link />... </head>...... <script></script>
  2. Add an inline style to the tail<body></body>... <link />
    1. JS in front of the CSS<body></body>... <link />... <script></script>
    2. JS in front of the CSS<body></body>... <script></script>... <link />

Examples are as follows

<! 1 - - - >
<! DOCTYPEhtml>
<html>
  <head>
    <script>
      console.log(document.querySelector("p"));
    </script>
    <link rel="stylesheet" href="http://localhost:8000/big.css" />
  </head>

  <body>
    <p id="test">When on earth will I be resolved?</p>
  </body>
</html>
Copy the code

In the first case, JS blocks DOM parsing and executes

without waiting for CSS to load

<! -- -- -- > 2
<! DOCTYPEhtml>
<html>
  <head>
    <link rel="stylesheet" href="http://localhost:8000/big.css" />
    <script>
      console.log(document.querySelector("p"));
    </script>
  </head>

  <body>
    <p id="test">When on earth will I be resolved?</p>
  </body>
</html>
Copy the code

In the second case, the JS needs to wait for the CSS to finish loading before it can be executed, because the JS may need to get the style properties set in the CSS, such as width and height, and then the DOM behind it cannot be parsed. So CSS load -> JS waits for CSS load -> JS to block DOM

Notice, to add a little detail, look at this example

<! DOCTYPEhtml>
<html>
  <head>
    <link rel="stylesheet" href="http://localhost:8000/big.css" />
  </head>
  <body>
    <p id="test">When on earth will I be resolved?</p>
  </body>
  <script>
    console.log(document.querySelector("p"));
  </script>
</html>
Copy the code

The same CSS before JS, head of JS is to get less than < p >, but the < body > below is to be able to obtain, proved that although the DOM parsing is blocked, but the DOM has been parsed out is not affect operation

<!-- 3 -->
<! DOCTYPEhtml>
<html>
  <body>
    <p id="test">When on earth will I be resolved?</p>
  </body>
  <script>
    console.log(document.querySelector("p"));
  </script>
  <link rel="stylesheet" href="http://localhost:8000/500.css" />
</html>
Copy the code

The third case, like the first case, doesn’t wait for the CSS to load, but DOMCOntentLoaded does wait for the CSS to load

<! 4 - - - >
<! DOCTYPEhtml>
<html>
  <body>
    <p id="test">When on earth will I be resolved?</p>
  </body>
  <link rel="stylesheet" href="http://localhost:8000/500.css" />
  <script>
    console.log(document.querySelector("p"));
  </script>
</html>
Copy the code

The fourth case, the same as the second case, waits for the CSS to load, but DOMCOntentLoaded waits for the CSS to load

conclusion

For JS, in terms of interaction, if you want to operate DOM correctly, put JS at the end of HTML. When parsing into JS, DOMCOntentLoaded is not triggered, but DOM can be correctly manipulated to reduce loading time and asynchronize JS. For external JS, Use the add defer attribute or async import

CSS does not block DOM parsing in the header, but JS cannot manipulate the DOM while the CSS is loaded