Understand the rendering process of HTML pages in preparation for learning front-end performance optimization

Understand the rendering process of HTML pages in preparation for learning front-end performance optimization
I'm currently learning about front-end performance optimization. It's necessary to understand the page rendering process in order to find the right remedy and identify performance bottlenecks. Here are some of the things I saw, shared with you.
Reference: Understanding the renderer
The rendering of the page has the following characteristics :
• Single-threaded event loop
• Well-defined, continuous, and orderly operations (HTML5)
• Tokenization and DOM tree construction
• Request resources and preload them
• Build the render tree and draw the page
Specifically :
When we get the corresponding bytes of HTML from the network, the DOM tree starts to be built. The browser's thread for updating the UI is responsible. The construction of the DOM tree will be blocked when the following situations occur:
• The HTML response stream is blocked on the network
• There are unloaded scripts
•A script node is encountered, but there are still unloaded style files. The rendering tree is built from the DOM tree and will be blocked by the style files.
Because it is based on a single-threaded event loop, even if there is no script or style blocking, when these scripts or styles are parsed, executed and applied, the rendering of the page will be blocked.
Some situations that will not block page rendering :
•Defined defer and async attributes
• No style file matching the media type
• No script nodes or style nodes are inserted by the parser
Below, let's illustrate this with an example (complete code) :

Copy code
The code is as follows:

<html>
<body>
<link rel="stylesheet" href="example.css">
<div>Hi there!</div>
<script>
document.write('<script src="other.js"></scr' + 'ipt>');
</script>
<div>Hi again!</div>
<script src="last.js"></script>
</body>
</html>

The code is easy to understand, and if you open it in a browser, the desired page will be displayed immediately. Next, let's use slow motion playback to see how it is rendered.

Copy code
The code is as follows:

<html>
<body>
<link rel="stylesheet" href="example.css">
<div>Hi there!</div>
<script>...

First, the parser encounters example.css and downloads it from the network. The process of downloading the style sheet is time-consuming, but the parser is not blocked and continues parsing. Next, the parser encounters a script tag, but because the style file has not been loaded, the execution of the script is blocked. The parser is blocked and cannot continue parsing.

The render tree will also be blocked by the style file, so no browser will render the page at this time. In other words, if the example.css file cannot be downloaded, Hi there! will not be displayed.
Next, continue. . .

Copy code
The code is as follows:

<html>
<body>
<link rel="stylesheet" href="example.css">
<div>Hi there!</div>
<script>
document.write('<script src="other.js"></scr' + 'ipt>');
</script>

Once the example.css file is loaded, the render tree is built.
After the inline script is executed, the parser will be immediately blocked by other.js. Once the parser is blocked, the browser receives the paint request and "Hi there!" is displayed on the page.
When other.js is loaded, the parser continues to parse downwards. . .

Copy code
The code is as follows:

<html>
<body>
<link rel="stylesheet" href="example.css">
<div>Hi there!</div>
<script>
document.write('<script src="other.js"></scr' + 'ipt>');
</script>
<div>Hi again!</div>
<script src="last.js"></script>

The parser is blocked when it encounters last.js, and then the browser receives another rendering request, and "Hi again!" is displayed on the page. Finally, last.js will be loaded and executed.
However, to alleviate rendering blocking, modern browsers use speculative loading.

In the above case, scripts and style files will seriously block the rendering of the page. I guess the purpose of preloading is to reduce this blocking time. When rendering is blocked, it does the following:
• A lightweight HTML (or CSS) scanner continues scanning in the document
• Find the URLs of resource files that may be used in the future
• Download them before the renderer uses them. However, guesswork preloading cannot detect resource files loaded via JavaScript (e.g., document.write()).

Note : All "modern" browsers support this method.
Let's look back at the example above and guess how preloading works.

Copy code
The code is as follows:

<html>
<body>
<link rel="stylesheet" href="example.css">
<div>Hi there!</div>
<script>...

The parser returns example.css and gets it from the network. The parser is not blocked and continues parsing. When it encounters an inline script node, it is blocked. Since the style file has not been loaded, the execution of the script is blocked. The render tree is also blocked by the stylesheet, so the browser doesn’t receive the render request and can’t see anything. So far, it's the same approach as just mentioned. But then things changed.

The speculative loader continues to “read” the document, finds last.js and tries to load it. Next:

Copy code
The code is as follows:

<html>
<body>
<link rel="stylesheet" href="example.css">
<div>Hi there!</div>
<script>
document.write('<script src="other.js"></scr' + 'ipt>');
</script>

Once example.css is loaded, the render tree is built and inline scripts can be executed, and then the parser is blocked by other.js again. After the parser is blocked, the browser receives the first render request and “Hi there!” is displayed on the page. This step is the same as the previous one. Then:

Copy code
The code is as follows:

<html>
<body>
<link rel="stylesheet" href="example.css">
<div>Hi there!</div>
<script>
document.write('<script src="other.js"></scr' + 'ipt>');
</script>
<div>Hi again!</div>
<script src="last.js"></script>

The parser finds last.js, but because the preloader has just loaded it and placed it in the browser cache, last.js will be executed immediately. After that, the browser will receive the rendering request and "Hi again" will be displayed on the page.
By comparing the two situations, I hope everyone can have a certain understanding of page rendering, and then make some targeted optimizations. good evening! (End)^_^

<<:  JavaScript basics of this pointing

>>:  A detailed tutorial on how to install Jenkins on Docker for beginners

Recommend

How to use Vue-router routing

Table of contents 1. Description 2. Installation ...

innerHTML Application

Blank's blog: http://www.planabc.net/ The use...

Distributed monitoring system Zabbix uses SNMP and JMX channels to collect data

In the previous article, we learned about the pas...

Linux file/directory permissions and ownership management

1. Overview of file permissions and ownership 1. ...

10 Best Practices for Building and Maintaining Large-Scale Vue.js Projects

Table of contents 1. Use slots to make components...

Solution for Baidu site search not supporting https (tested)

Recently, https has been enabled on the mobile ph...

MySQL Basic Tutorial: Detailed Explanation of DML Statements

Table of contents DML statements 1. Insert record...

Docker Swarm from deployment to basic operations

About Docker Swarm Docker Swarm consists of two p...

How to set focus on HTML elements

Copy code The code is as follows: <body <fo...

Detailed example of database operation object model in Spring jdbc

Detailed example of database operation object mod...

10 very good CSS skills collection and sharing

Here, clever use of CSS techniques allows you to g...

Vendor Prefix: Why do we need a browser engine prefix?

What is the Vendor Prefix? Vendor prefix—Browser ...

How to operate MySQL database with ORM model framework

What is ORM? ORM stands for Object Relational Map...