📜 ⬆️ ⬇️

What are you, Rendering Engine? Or how does the browser display module work?

The most important for the Frontend developer is the display module in the browser, also known as the Rendering Engine (hereinafter referred to as RE).

In this article, I want to take a simple page and go through all the steps together with the RE from receiving the first byte and before drawing the content onto the screen. I will use, as always, the Chrome browser.

To begin with, let's look at what other modules the browser consists of in order to understand what RE interacts with.

Consider the scheme:
')

Picture 1

User Interface, User Interface (hereinafter UI) - external browser API for the user: address bar, navigation, menu, bookmarks, 'refresh' and 'home' buttons.

The mechanism of the browser, the Browser Engine (hereinafter BE) layer between the user interface and the display module.

Rendering Engine Rendering Engine . We will analyze it in more detail later.

Network components, Network responsible for requests over the network. RE receives data from the Network. Data is received in portions of 8Kb and RE does not wait until all the data arrives, it starts processing it as it is received.

The JS Interpreter module is responsible for interpreting the script and executing it.

The UI backend is used to draw basic graphic elements and widgets, such as windows and combo boxes. A simple example is the alert or prompt window.

Data storage is cookies, indexDB and other browser storages.

Now that we know at a basic level what the browser consists of, we can go to the component of interest to us - the Rendering Engine.

Understand easier and faster on a specific example, so let's take a simple html-page with one external css-and js-file (the script is connected with the async attribute, then we analyze why). And let's see how RE handles them and what steps are performed before we see the content we need on the screen.

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="./style.css"></link> <title>Document</title> </head> <body> <div>Hello Habr!</div> <div>I'am Rendering Engine</div> <script async src="./script.js"></script> </body> </html> 

 (function() { window.addEventListener('load', () => { console.log('all resources were loaded'); }); })(); 

 * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Helvetica, sans-serif; line-height: 1.5; background-color: #9BD4F4; padding: 16px; } 

To do this, go to Chrome DevTools, open the perfomance tab and start the process. After reloading the page and analyzing what happened, we see the following picture:


Figure 2

In the Network tab - the sequence of loading data over the network (blue rectangle - index.html).

In the Timings tab - marks when DCL events occurred (DOM Content Loaded, FP - first paint, FCP - first contentful paint, FMP - first meaningful paint, L - load). Let's see what these events are.

DOMContentLoaded - the browser loaded HTML, parsed it and built a DOM tree. This event is triggered by the document, you can easily subscribe to it and work with the DOM via JavaScript (in our script we will not be able to subscribe to the DOMContentLoaded event, as it happened before the script parted, see picture ).
Also DOMContentLoaded has several nuances:



Figure 3

First paint - the browser rendered the first pixel on the page.

First contentful paint - the browser rendered the first content on the page.

First meaningful paint - the event works after the RE determines that the rendered content may be useful to the user.

Load the entire page and resources on it, including iframe.

About FP, FCP, FMP is perfectly written in the official documentation of Google for developers .

Now that we have understood what events have taken place, we can go to the Call tree (see Figure 1 ) and analyze in more detail when and why these events occur.

Parse HTML - HTML parsing. About this you can write a separate article. Better yet, read the spec We just need to understand that the HTML-based browser creates an object model of the document - DOM. And when it is ready and nothing can affect it anymore, it executes the DOMContentLoaded event.

Composite layers are the combination of visual elements from separate sources into single images to create the illusion that all these elements are parts of the same scene.

Recalculate style. Any changes to the DOM, whether adding or removing elements, changing attributes, classes or using animation tools, cause the browser to recalculate the styles of the elements and in many cases the layout of the entire page or its parts. This process is called style calculation. Google for developers

Parse Style sheet. If, after parsing, RE sees that css is enabled in HTML, it starts downloading and parsing it in advance. After the Parsin RE builds the CSS Object Model - the CSS object model.

PS Since the browser parses CSS selectors from right to left, it is not recommended to use complex nested selectors such as div div div, .class div a, etc. This can put a heavy load on the browser. The simpler the selector, the better. Ideally, just .class.

Next comes the attachment phase, in which the RE maps the OM and DOM CSS, and we get the Render Tree.

Update layer tree (Layout) - layout of the layer tree or just layout. After we mapped the CSS OM and DOM, we can find out the location of the elements and their sizes.

Most often, the elements that go lower in the stream cannot influence the positioning of the elements above, so the layout is often performed sequentially, from top to bottom and from left to right. Therefore, the HTML standard provides a flow model for document layout.

Paint - drawing content on the screen. And only after all these steps, we see the site content on our screen: D

Here is a brief outline of all phases of RE:


Figure 4

We summarize:

The data in the RE comes from the network module in chunks. Receiving this data, RE begins to work with them, namely - parse HTML.

When RE sees that an external resource is found in HTML, he talks about this to the Network, and he starts downloading it and then gives it to RE again.

Meeting the <script> tag according to the RE standard, stops parsing and waits until this script is downloaded and executed, and only then continues the parsing and building of the DOM tree. This is solved by the attributes async / defer. You can read more about their differences here. The main thing to understand is that they make it possible to continue parsing HTML without waiting for the script to be processed.
Also, browsers (in our case, Chrome) can block the execution of the script if it tries to work (via JavaScript) with the css element whose styles are currently being processed.

After RE realizes that all synchronous scripts have been downloaded and completed, HTML is completely parsed and does not interfere with anything else, it raises the DOMContentLoaded event, and we get an #document object in the browser that we can work with.

Further, after completing CSS parsing and constructing the CSS Object Model, an attachment stage occurs, where the Render Tree is built and the Layout occurs (the layout of the block sizes and positions). Well, after Layout there is a drawing on the screen - Paint. Rendering Engine makes such a long way so that we can see it:


Figure 5

That's all!

I hope this article was useful to you and now you understand how the Rendering Engine works.

Bye everyone :) And until we meet again. If you like, put likes and subscribe to my channel :)

Source: https://habr.com/ru/post/459814/


All Articles