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

Analysis and solution of MySQL connection throwing Authentication Failed error

[Problem description] On the application side, th...

In-depth analysis of Nginx virtual host

Table of contents 1. Virtual Host 1.1 Virtual Hos...

The difference between animation and transition

The difference between CSS3 animation and JS anim...

Discussion on horizontal and vertical centering of elements in HTML

When we design a page, we often need to center th...

JavaScript implements large file upload processing

Many times when we process file uploads, such as ...

Analysis of mysql view functions and usage examples

This article uses examples to illustrate the func...

js regular expression lookahead and lookbehind and non-capturing grouping

Table of contents Combining lookahead and lookbeh...

Detailed explanation of JSONObject usage

JSONObject is just a data structure, which can be...

Sample code for implementing rolling updates of services using Docker Swarm

1. What is Docker Swarm? Docker Swarm is a cluste...

JS+Canvas draws a lucky draw wheel

This article shares the specific code of JS+Canva...

About the garbled problem caused by HTML encoding

Today a junior student asked a question. The HTML...

Sitemesh tutorial - page decoration technology principles and applications

1. Basic Concepts 1. Sitemesh is a page decoratio...