Blocking rendering falls into two categories:

CSS block rendering

From the browser series – Rendering principle and process can be known in step 3 in the construction of the rendering tree, need a complete DOM tree, CSSOM tree, and CSSOM parsing may block DOM parsing, or CSSOM tree incomplete will block the construction of the rendering tree, this is CSS blocking rendering

JS block rendering

JS can query and modify the DOM and CSSOM, so when the HTML parser encounters a script tag, it pauses building the DOM, handing control to the JS engine, and the HTML parser waits for the JS engine to finish running. This is called JS blocking rendering

CSS block rendering

1. Block DOM parsing (the CSSOM tree is built to block DOM parsing by blocking JS code)

<html>
    <head>
        <style type="text/css" src = "theme.css" />
    </head>
    <body>
        <p>ALKAOUA</p>
        <script>
            let e = document.getElementsByTagName('p') [0]
            e.style.color = 'blue'
        </script>
        <p>Personal blog</p>
    </body>
</html>
Copy the code

When you access the style of an element in JavaScript, you have to wait for the style to be downloaded before you can proceed, so CSS also blocks DOM parsing in this case (at some point)

2. Block the construction of the render tree (CSSOM tree construction blocks the construction of the render tree)

<body>
    <h1>red1</h1>
    <link rel="stylesheet" href="https://www.youtube.com/file.css"><! -- This will be stuck for a while -->
    <h1>red2</h1>
</body>
Copy the code
  1. You can see that the page is still blank
  2. Click the browser’s stop load button and the red1 content will be rendered. Look at the Dom tree and it won’t be<h1>red2</h1>Of this node
  3. When the resource download fails,<h1>red2</h1>The DOM node is then parsed and rendered

How to solve CSS blocking rendering

1. CSS introduced location – for blocking DOM parsing

We usually put

2. Media query method — for blocking render tree construction

Some CSS resources may not be used in the first rendering, but only for user interaction (such as page size changes), so we use media queries to determine if they need to be loaded in the first rendering. This will reduce the first screen load time somewhat

<! -- Applies to all cases, always block rendering -->
<link href="style.css" rel="stylesheet">

<! -- When the page is first loaded, only when the content is printed -->
<link href="print.css" rel="stylesheet" media="print">
<! -- This stylesheet does not block rendering unless it is printing content -->

<! The browser will block rendering until the stylesheet is downloaded and processed.
<link href="other.css" rel="stylesheet" media="(max-width: 400px)">
<! If the conditions are not met, the render will not be blocked, but the resource will still be downloaded.
Copy the code

JS block rendering

The biggest difference between JS blocking rendering and CSS blocking rendering is that CSS parsing is predictable, whereas JS blocking rendering is unpredictable, because JS may modify DOM nodes at any time, or even load dynamically

1. Inline script blocks rendering

<body>
    <h1>AAA</h1>
    <script>
        let d = Date.now()
        while (Date.now() < d + 1000 * 3) {}</script>
    <h2>BBB</h2>
</body>
Copy the code
  • When I first got to loadPage hangIt takes 3 seconds for the content to render
  • Note That inline JS blocks DOM parsing and rendering, and always blocks

2. The external synchronization script blocks rendering

<body>
    <h1>AAA</h1>
    <script src="./test.js"></script>
    <h2>BBB</h2>
</body>
Copy the code
// test.js
let d = Date.now()
while (Date.now() < d + 1000 * 3) {}Copy the code
  • And you can see it’s going to render at the beginningAAA.3sAfter rendering outBBB
  • Note The external script also blocks DOM parsing and rendering, butBecause you can't be sureContent in the script, so it willRender the built DOM firstMake sure that the loaded script gets the latest DOM

How to solve JS blocking rendering

1. <script>Position of introduction

  • If the page rendering content is<script>The tag requests the content of the<script>Labels generally need to be placed<head>inside
  • If the page renders content with<script>It doesn’t matter what the label says, for exampleDOM events, load other (not yet seen) content, then<script>Labels are usually placed<body>The last position in the tag

2. Defer and async properties

  • If you need a piece of JavaScript code that needs to be loaded ahead of time, you might put it in<head>Inside or in front of some DOM nodes<script>Tag add defer or async properties:
    • If I’m done loadingimmediatelyUse theasyncProperties;
    • If you do not need to execute immediately after loading, you want to execute the page structure after loading (window.onload) if executed immediately, usedeferProperties;

It is worth noting:

  • Without either of these attributes, JavaScript loads and runs block rendering;
  • If either of these attributes is used, the JavaScriptLoading does not block rendering, but the run still blocks rendering
<body>
    <h1>AAA</h1>
    <script defer/async src="./test.js"></script>
    <h2>BBB</h2>
</body>
Copy the code

The difference between defer and Async

We see that visually in a picture

  • The green lineOn behalf ofThe DOM parsing
  • Gray lineOn behalf ofDuring DOM parsing is blocked
  • Purple lineOn behalf ofJS script network read
  • The red lineOn behalf ofThe execution time of the JS script

It is obvious that the difference between defer and Async is as follows:

  • asyncAfter loadingImmediate execution, blocking DOM parsing
  • deferAfter loadingWaiting for DOM parsingExecute after completion

You can summarize the difference between defer and Async application scenarios:

  • If your script codeDepends on theDOM elements in a page (Whether the document has been parsed), or by other script filesRely on, use thedeferattribute

Examples: comment boxes, code syntax highlighting

  • If your script doesn’tDon't care aboutDOM elements in a page (Whether the document has been parsed) and alsoDoes not produceData required by other scripts is usedasyncattribute

For example: Baidu statistics

Additional questions

Difference between DOMContentLoaded and onLoad

  • DOMContentLoaded: This event is triggered after the initial HTML document has been fully loaded and parsed, without waiting for the CSS stylesheets, images, and subframes to be fully loaded
  • OnLoad: Trigger only after HTML documents, CSS stylesheets, JavaScript code, images, subframes, and so on are fully loaded

How to solve CSS blocking rendering?

  • For blocking DOM parsing — CSS introduces location
  • Construction of blocking CSSOM trees – media queries

How to solve JS blocking rendering?

  • JS entry position
  • Defer and async properties

The difference between defer and Async

  • Principle: Whether loading and execution are separated
  • In application: Whether the script needs DOM parsing to complete before execution