preface

As shown in the figure, the rendering process of the WebKit kernel browser (parsing HTML, building a DOM tree, parsing CSS, building a CSSOM tree, building a Render tree, layout layout, painting) may seem abstract to understand, Today we will use chrome developer tools to intuitively understand the browser rendering process.

Page rendering process

The Performance tools

We will analyze the page rendering process using the Performance tool. First open DevTools by pressing Command+ Option+ I (Mac) or Control+ Shift+ I (Windows, Linux). Then open the Performance tool’s interface.

We can see the default boot page for Performance:

  • The operation corresponding to the first prompt is to immediately start recording all events that occur on the current page. Click the stop button to stop recording.
  • Reload the page and log the event. The tool automatically stops logging when the page is ready for interaction.

Both eventually generate reports (which are computationally intensive and take some time). Taking a real front-end project (VUE project) as an example, click the refresh button to reload the page and record the event, resulting in the following report.

Network request

Here mentioned network request, because the browser renders the page cannot leave a network request, began to receive HTML browser rendering process data, is actually received the confirmation information browser navigation, browser navigation process is mainly in the network layer, involving a DNS lookup, strong browser cache cache/consultation, TCP three-way handshake to establish a connection, The performance tool can be used to understand the network request part before the browser renders the page:

In the figure above, you can see that there are different color requests in the Network module, which respectively represent the resource request of blue-HTML, yellow-JS and green-image. If there is a request for CSS file, it will be identified as purple. Another detail is that each resource request in the figure has a small square in the upper left corner. Dark blue squares represent higher priority requests, light blue represents lower priority requests, It is obvious that preferentially requested resources (HTML, Webpack-packaged manifest, Vendor, app main file request) are all identified in dark blue squares.

Let’s look at the browser activity in the Event log:

  • Request the HTML
  • Receiving response header
  • The browser receives the document and begins parsing
  • HTML response data has been received
  • Network Request completion

In addition, you can see that the browser does a number of things before sending the request. This is because we chose to reload the page to record the event, so the browser’s default event behavior is triggered before sending Requerst the Html request: Webkitvisibilitychange unloadEventStart, unloadEventEnd, etc.

Parse HTML

Inside the browser rendering engine, there is a module called HTMLParser that converts HTML byte streams into DOM structures. The HTML Standard specification defines how browsers render HTML into the DOM.

  • Instead of waiting for the entire document to load, the HTML parser parses as much data as the network process loads.

After the browser receives the response, let’s take a look at the HTML text the browser gets

<! DOCTYPE html><html><head> <meta charset=utf-8> <title></title> <link rel=dns-prefetch href=//s1.zhuanstatic.com> ... <meta name=description content= around > <meta name=viewport content="width=device-width,viewport-fit=cover,initial-scale=1,maximum-scale=1,user-scalable=no"> <meta content="telephone=no,email=no" name=format-detection> <meta name=apple-mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-status-bar-style content=default></head><body> <div id=app></div> <script type=text/javascript  src=https://s1.zhuanstatic.com/u/bmmain/static/js/manifest.f741ad8a3e48f84ad413.js></script> <script type=text/javascript src=https://s1.zhuanstatic.com/u/bmmain/static/js/vendor.6858ed31f5c34c2f6f8e.js></script> <script type=text/javascript src=https://s1.zhuanstatic.com/u/bmmain/static/js/app.9ff176b78d7af021c2b0.js></script></body></html>Copy the code

Again to watch the Event Log in first parsing HTML browser activity: parsing HTML text, in the < body > of < script > tag, sent three request, request the manifest respectively. Js, vendor, js, app. Js file

JS download and execution

As shown in the figure above, when the

Load the sub-priority resource

HTML pages have additional resources such as CSS, JS, fonts, etc. These resources also need to be retrieved from the web or from the browser cache. The main process can request them one by one as it builds the DOM. To speed things up, the browser’s preload scanner runs at the same time. If tags such as < IMG > are present in the HTML, the preload scanner passes these requests to the web thread in the browser process to download the related resources.

Build a DOM tree

Why do browsers build DOM trees? This is because the browser cannot understand and use HTML text directly, and you need to transform the HTML into a structure that the browser can understand – a DOM tree. To get a more intuitive view of the DOM tree, open Chrome’s Developer Tools, select the “Console” TAB to open the Console, type “Document” in the Console, and press Enter to see a complete DOM tree structure, as shown below:

DOM is almost identical to HTML content, but unlike HTML, DOM is stored in an in-memory tree structure that can be queried or modified using JavaScript.

Build CSSOM

Why do browsers build CSSOM trees? For the same reason that browsers build DOM trees, they can’t directly understand the CSS styles of plain text, so when the rendering engine receives CSS text, it performs a conversion operation to convert the CSS text into a structure that browsers can understand — styleSheets. You can view the structure in the Chrome console by typing Document.stylesheets into the console and seeing the structure shown below

Style calculation

The renderer main thread calculates the final style value for each element node, and the browser will have a default style for each element, even without any CSS styles. We can also view the computed style of the browser through Chrome

Generate layout tree

To build the Render tree, the browser basically does the following

  • Traverses all visible nodes in the DOM tree and adds them to the Layout.
  • Invisible nodes are ignored by the layout tree, such as everything under the head tag, or the body.p.pan element, which is not included in the layout tree because its attribute contains dispaly: None.

Return to the Event Log for further observation and analysis. As shown in the figure below, after the js engine has completed the complete loading and execution of Vendor.js, manifest.js and app.js, the rendering engine returns and begins to parse Html for the third time, starting the first style calculation and layout. And dynamically loaded the app-async.js and other resources in the MANIFEST map (the product of the project Webpack after the split chunk optimization) and the homepage correlate -hplan.js resources.

draw

Even with the location and style information of the different elements, the browser needs to know the order in which the different elements were drawn in order to correctly draw the entire page. During the draw phase, the main thread traverses the layout tree to create a list to draw. Open the Layers TAB in Developer Tools and select the Document layer to actually experience drawing lists

The drawing process can decompose elements in a layout tree into layers.

Back in the Performance panel, check Enable Advanced Paint Instrumentation in the control panel to record the details of the render event: Select a piece of Frames to display information about page layering in the new Layers TAB next to the Event Log TAB.

Promoting content to a layer on the GPU (rather than the main thread on the CPU) improves drawing and redrawing performance. There are specific properties and elements that can instantiate a layer, including

Layers do improve performance, but they come at the expense of memory management and should not be overused as part of a Web performance optimization strategy.

Continue to observe the activities of the Event Log at this stage, just analyzed that the browser parsed HTML for the third time, dynamically loaded the chunk separated by Webpack and the home PAGE JS, and the JS engine executed the Event load Event. Then triggered domInteractive events also identifies the end of the HTML parsing, HTML parser trigger docmument after work. Readystatechange event, followed by the trigger DomContentLoaded event, update the layout tree, drawn for the first time.

Now let’s understand the difference between the DomContentLoaded event and the Load event

The life cycle of an HTML page consists of three important events:

  • DOMContentLoaded — The browser has fully loaded the HTML and built the DOM tree, but external resources such as and style sheets may not have finished loading.
  • Load – The browser loads not only the HTML, but all external resources: images, styles, etc.
  • Beforeunload /unload – when the user is leaving the page.

If we look at the Timings module, we can see the abbreviations of DCL, FP, FCP, L and LCP, which are closely related to page performance optimization. Here we only understand DCL (DOMContentLoaded) and L(Load). The load event fires significantly later than DOMContentLoaded

Composition and display

Once the layer tree is created and the drawing list is determined, the main thread notifies the synthesizer thread, which rasterizes each layer. Some layers can be as large as an entire page, so a synthesizer thread divides them into tiles and sends each tile to a raster thread, which rasterizes each tile and stores it in GPU memory. The composite thread sends the DrawQuad command to the browser process. The browser process generates the page from the DrawQuad message and displays it on the monitor.

Back to the Performance tool, here we slide down the selected area of the overview module to the middle of the skeleton screen and the first rendered page. If we select Painting only in the Event Log, it will automatically filter out the drawing Event Log within the range. You can see that the browser has done multiple drawing and composition operations.

Performance issues to be optimized

Well, this part was not originally planned 🙃, there are two main problems that Chrome ⚠️ :

  • Multiple main tasks take a Long time to be warned, mainly due to the large size of js packages
  • You’re about to click on a link or button, but just before your finger touches the screen, the link moves and you click somewhere else

conclusion

Through the Event Log module of performance tool, I analyzed the rendering process of SPA single page application page of some actual VUE project in the browser. There may be some misunderstanding in the process, welcome to point out more.

reference

[1]. Blog. Poetries. Top/browser – wor…

[2]. Developers.google.com/web/tools/c…

[3]. Developer.mozilla.org/zh-CN/docs/…

[4]. Developers.google.com/web/updates…

[5].zhuanlan.zhihu.com/p/41017888