How JavaScript works: Rendering engine and performance tuning tips

Source: Internet
Author: User
Tags setinterval

Translated from: HowJavaScript works:the rendering engine and tips to optimize its performance

This is the 11th of a series on exploring JavaScript and its building components. In the process of identifying and describing core elements, we share some of the rules of thumb used when building sessionstack . Sessionstack is a robust and high-performance JavaScript application that helps users to see and reproduce the flaws of their WEB applications in real time.

When building a WEB application, you're not just writing a piece of JavaScript code that runs independently. The JavaScript you write needs to interact with the environment. Understanding how the environment works and what it is made of, you will be able to build better applications and better handle the potential problems that will manifest after the application is published.

So, let's see what the main components of the browser are:

    • User interface : Includes Address bar, back and Forward buttons, bookmarks menu, and so on. In fact, it includes most of the display in the browser, except for the window you see in the page itself.
    • Browser engine : It handles the interaction between the user interface and the rendering engine.
    • render engine : it is responsible for displaying the Web page. The rendering engine parses the HTML and CSS and displays the parsed content on the screen.
    • Network layer : Network calls such as XHR requests are accomplished by different implementations of different platforms, which are located after a platform-independent interface. We discussed the network layer in more detail in the previous article in this series.
    • UI back-end : It is used to draw core components (widgets), such as check boxes and Windows. This backend exposes a platform-agnostic universal interface. It uses the UI methods provided by the underlying operating system.
    • JavaScript engine : We are in previous post Describes this topic in detail. Basically, this is where JavaScript executes.
    • Data Persistence layer : Your app may need to store all the data locally. Its supported storage mechanisms include localstorage , indexdb , Websql and FileSystem .

In this article, we'll focus on the rendering engine because it handles parsing and visualization of HTML and CSS, which is where most JavaScript applications continue to interact.

Rendering Engine Overview

The primary responsibility of the rendering engine is to display the requested page on the browser screen.

The rendering engine can display html/xml documents and images. If you use another plugin, it can also display different types of documents, such as PDFs.

Different rendering engines

Like the JavaScript engine, different browsers also use different rendering engines. Common to have these:

    • Gecko?—? Firefox
    • WebKit?—? Safari
    • Blink?—? Chrome,opera (after version 15)

The process of rendering

The rendering engine receives the contents of the requested document from the network layer.

Building the DOM Tree

The first step in the rendering engine is to parse the HTML document and convert the parsed elements into the actual Dom nodes in the DOM tree .

Suppose you have the following text input:

The DOM tree for this HTML is as follows:

Basically, each element is the parent of the element it contains, and the structure is recursive.

Build CSSOM

CSSOM refers to the CSS object Model . When the browser builds the DOM of the page, it head encounters a label that references an external theme.css CSS style sheet link . The browser anticipates that it may need the resource to render the page, so it makes a request immediately. Let's assume that theme.css the file contains the following content:

body {   font-size: 16px;}p {   font-weight: bold; }span {   color: red; }p span {   display: none; }img {   float: right; }

Like HTML, the engine needs to convert the CSS into something--cssom the browser can use. Here's what the CSSOM tree looks like:

Do you know why CSSOM is a tree-like structure? When the final style set of an object on a page is computed, the browser starts with the most general rule applicable to that node (for example, if it is a child of the BODY element, all of the body's styles are applied), then recursively thinning, and the style is calculated by applying more specific rules.

Let's take a look at concrete examples. Any text in a label contained within an element has a body span font size of 16 pixels and is red. These styles are body inherited from elements. If an span element is a p child of an element, its contents are not displayed because it is applied to a more specific style ( display: none ).

Also note that the tree above is not a complete CSSOM tree, but only shows the styles we have decided to override in the style sheet. Each browser provides a default set of styles, also known as user-agent styles, that we see when we don't explicitly specify any style. Our styles override these default values.

Build a render Tree

The view directives in HTML are combined with the style data in the CSSOM tree to create a render tree .

You might ask what a render tree is. A rendering tree is a tree structure that is composed of visual elements in the order in which they appear on the screen. It is a visual representation of HTML and the corresponding CSS. The purpose of this tree is to draw the content in the correct order.

The nodes in the render tree are called renderers or render objects in Webkit.

This is what the shader tree looks like for the DOM and CSSOM trees above:

In order to build the render tree, the browser has done roughly the following:

    • Starting from the root of the DOM tree, the browser iterates through each visible node. Some nodes are not visible (such as script, meta, etc.) and are ignored because they do not require rendering. Some nodes that are hidden through CSS are also omitted from the render tree. For example, a span node-in the above example, it does not exist in the render tree because we explicitly set the property on it display: none .
    • For each visible node, the browser finds the appropriate CSSOM rules and applies them.
    • The browser outputs a visible node with content and its computed style

Here you can see the source code for RenderObject (in WebKit):https://github.com/WebKit/webkit/blob/ Fde57e46b1f8d7dde4b2006aaf7ebe5a09a6984b/source/webcore/rendering/renderobject.h

Let's take a look at some of the core elements of this class:

class RenderObject : public CachedImageClient {  // Repaint the entire object.  Called when, e.g., the color of a border changes, or when a border  // style changes.  Node* node() const { ... }  RenderStyle* style;  // the computed style  const RenderStyle& style() const;  ...}

Each renderer represents a rectangular area, usually corresponding to a node's CSS box model. It contains geometry information, such as width, height, and position.

Layout of the Render tree

When the renderer is created and added to the tree, it does not have a location or size. The process of calculating these values is called layout.

HTML uses a flow-based layout model, which means that it can calculate the layout for most of the time in one traversal (single pass). The coordinate system is relative to the root renderer, using the upper-left origin coordinates.

A layout is a recursive process-it starts with the root renderer, corresponds to an element of an HTML document , and recursively calculates layout information for each renderer that needs a layout through a hierarchy of parts or the entire renderer.

The location of the root renderer is the size of the 0,0 visible part of the browser window (also known as a viewport).

Starting the layout process means giving each node exactly the coordinates it should appear on the screen.

Draw a render tree

At this stage, the browser traverses the renderer tree and invokes the renderer's method to display the content on the paint() screen.

The drawing can be global or incremental (similar to layout):

    • Global --the whole tree is redrawn
    • Incremental -only some renderers change in a way that does not affect the entire tree. The renderer marks its rectangular area on the screen as invalid, which causes the operating system to treat it as paint an area where the event needs to be redrawn and generated. The operating system completes the drawing by merging several areas into a single area of intelligent mode.

In general, it is important to understand that drawing is a gradual process. For a better user experience, the rendering engine tries to display content on the screen as soon as possible. It won't wait until all the HTML is parsed to start building and laying out the render tree. A small portion of the content is parsed and displayed, while progressively rendering the rest of the content from the network.

Order of processing scripts and style sheets

When the parser arrives at <script> the tag, the script is parsed and executed immediately. The parsing of the document will be paused until the script finishes executing. This means that the process is synchronous .

If the script is external, it must first be fetched from the network (also synchronized). All parsing stops until the network request is complete.

HTML5 adds an option to mark the script as asynchronous, when the script is parsed and executed by another thread.

Optimize rendering Performance

If you want to optimize your app, then you need to focus on five main areas. These are the places you can control:

    1. JavaScript -In previous articles, we covered topics on writing high-performance code that did not block the UI, and that memory efficiency was high, and so on. When it comes to rendering, we need to consider how JavaScript code interacts with DOM elements on the page. JavaScript can generate a lot of updates in the UI, especially in the SPA.
    2. style Calculations -This is the process of determining which CSS rule applies to which element, based on the matching selector. Once a rule is defined, the rules are applied and the final style of each element is calculated.
    3. Layout -Once the browser knows which rules apply to the element, it can begin to calculate the space occupied by the latter and where it is located on the browser screen. The layout model of the WEB defines an element that can affect other elements. For example, <body> the width affects the width of child elements, and so on. All this means that the layout process is computationally intensive. The drawing is done on multiple layers.
    4. Draw --This starts to populate the actual pixel. The process includes drawing text, colors, images, borders, shadows, and so on-each visual part of each element.
    5. compositing -because page parts are divided into multiple layers, they need to be drawn to the screen in the correct order to render the page correctly. This is important, especially for overlapping elements.

Optimize your JavaScript

JavaScript often triggers visual changes in the browser, especially when building a SPA.

Here are some tips on what parts of JavaScript can be optimized to improve rendering performance:

    • Avoid using setTimeout or setInterval making view updates. These will be called at an indeterminate point in time in the frame callback , possibly at the end. What we want to do is to trigger a visual change at the beginning of the frame rather than miss it.
    • Move long-running JavaScript computing tasks to the Web Workers, as we discussed earlier
    • Use a micro task to change the DOM in multiple frames. This is to handle the case where the task in the Web worker requires access to the DOM, and the Web worker does not allow access to the DOM. That means you can break a big task into small tasks and requestAnimationFrame run them in, or, depending on the nature of the task setTimeout setInterval .

Optimize your CSS

Modifying the DOM by adding and removing elements, changing properties, and so on can cause the browser to recalculate element styles and, in many cases, re-layout the entire page or at least part of it.

To optimize rendering performance, consider the following methods:

    • Reduce the complexity of selectors. Rather than building the style itself, a complex selector can increase the time it takes to calculate an element's style by 50%.
    • Reduce the number of elements that must be calculated for the style. In essence, style changes are made directly to several elements, rather than making the entire page invalid.

Optimizing layouts

The recalculation of the layout can be very stressful for the browser. Please consider the following optimizations:

    • Reduce the number of layouts as much as possible. When you change the style, the browser checks to see if the layout needs to be recalculated. Changes to properties, such as width, height, left, top, and other geometry-related properties, require a re-layout. So try to avoid changing them.
    • Try flexbox to use rather than the old layout model. It runs faster and can create huge performance benefits for your application.
    • Avoid forcing a synchronized layout. It is important to note that all old layout values in the previous frame are known and can be queried while JavaScript is running. If you query box.offsetHeight is not a problem. However, if you change the style of the element before querying the element (for example, adding some CSS classes to the element dynamically), the browser must first apply the style changes and perform the layout procedure. This can be time-consuming and resource-intensive, so avoid it as much as possible.

Optimize your drawing

This is usually the longest running time in all tasks, so it is important to avoid this as much as possible. Here are the things we can do:

    • In addition to transformations (transform) and transparency, changing any other property triggers a re-drawing, so use caution.
    • If the layout is triggered, the drawing will also be triggered because changing the layout will cause the element's visual effect to change.
    • Reduce redraw areas with layer elevation and animation orchestration.

Rendering is one of the key points of Sessionstack operation. When users navigate through your Web app, Sessionstack must re-build a video of the problems they encounter. To do this, Sessionstack only uses our library to collect data: User events, DOM changes, network requests, exceptions, debug messages, and so on. Our players are highly optimized to render and use all the data collected in sequence, from both visual and technical aspects to provide you with a perfect pixel-level simulation of everything the user has done in the browser.

If you want to try it, you can try Sessionstackfor free.

Resources
    • Https://developers.google.com/web/fundamentals/performance/critical-rendering-path/constructing-the-object-model
    • Https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations
    • https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/#The_parsing_algorithm

This article from the NetEase cloud community, by the author Xu Zihai authorized release.

Original address: How JavaScript works: Rendering engine and performance tuning tips

More NetEase research and development, product, operation experience Sharing please visit NetEase Cloud community.

How JavaScript works: Rendering engine and performance tuning tips

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.