How to Improve Web Front End Performance from Request, Transmission and Rendering

  Front-end optimization, Render, web

What is WEB Front End? Is everything the browser of the user’s computer does. Let’s look at what the browser has done when users visit the website:

Enter web address-> resolve domain name-> request page-> resolve page and send resource request in page-> render resource-> output page-> monitor user action-> re-render.

From the above path, it can be seen that the browser is divided into three parts: request, transmission and rendering to achieve user access. This paper analyzes how to improve the performance of the WEB front end from these three parts.

I. requests

In order to reduce request transmission, the browser has implemented its own caching mechanism. Browser cache is to store a copy of a requested Web resource in the browser. when requesting the same URL again, first check the cache. if there is a local cache, the browser cache mechanism will determine whether to use the cache or transfer the resource file from the server according to the authentication mechanism (Etag) and expiration mechanism (Last-Modified). The specific flow is shown in the following figure:

Some browser requests are concurrent and some are blocked. For example, requests for pictures, CSS and interfaces are concurrent. JS files are blocked. When requesting JS, the browser will interrupt the rendering process and wait for the JS file to be loaded and parsed before rendering again. Therefore, JS files should be placed at the end of the page.

JS can also change from blocking to parallelism in two ways: one is to create script tags and insert them into DOM; The other is to add the async attribute to the Script tag.

Each browser has a limit on the concurrent number of the same domain name, IE6/7 is 2, IE9 is 10, and other common browsers are 6, so reducing the number of resource requests and using multiple domain name configuration resource files can greatly improve the performance of the website.

There are roughly the following ways to reduce the number of resource requests:

1. Consolidate resources and reduce the number of resources through packaging tools. The development version is a lot of resource files, which are merged into several files by class to output when deployed. At the same time of realizing module management, unified output is realized.

2. In CSS, css sprite is used to reduce the number of picture requests.

3. Request resources without users’ awareness through delayed loading technology.

4. Through server configuration, realize one request and return multiple resource files, such as Taobao CDN.

In addition to reducing the number of requests, CDN images can also be used to reduce network nodes and achieve fast response. The request using CDN will find the nearest CDN node according to the geographical location of the user. If the request is new, it will be copied from the resource server to the node and then returned to the client. If the request already exists, it is returned directly from the node to the client.

Through the caching mechanism we know above, if we deploy online, we need to refresh the cache. Ordinary cache can be changed by strong brushing, while CDN cache needs to be realized by changing URL. At the same time, we can’t require users to press Ctrl to refresh, so through the packaging tool, when deploying, changing URL uniformly is the most effective way. However, library files that do not change very often, such as echart and jquery, are not recommended to change.

II. Transmission

When transmitting from server to client, gzip compression can be turned on to improve transmission efficiency.

Gzip has ten grades from 1 to 10. The higher the compression, the smaller, but the more server hardware resources the compression uses. According to practice, when the grade is 5, it is the most balanced. At this time, the compression effect is 100k can be compressed to 20k.

III. Rendering

After the browser loads html, it will parse and request resources based on the parsed results and generate DOM tree. The loaded CSS is used by the rendering engine to generate the rendering tree according to the generated DOM tree. After all resources are analyzed and layout is calculated, draw to the browser interface. As the user operates, JS will modify DOM nodes or styles, redraw and rearrange them. Repainting refers to drawing rendering nodes corresponding to DOM nodes, and rearranging refers to recalculating the positions of these nodes in the browser interface. Obviously, rearrangement is very performance-consuming. What we have to do is to reduce the number of rearrangements.

When generating DOM trees, we can optimize performance by reducing DOM nodes. At first, table layout was used. the depth and number of nodes were quite complex and the performance was very poor. Similarly, as cascading style sheets, CSS should not be too deep in hierarchy, otherwise the cost of traversal is very high. In addition, the expression attribute of CSS is quite performance-consuming, and it can be used without it. Animation effects that can be written in CSS need not be written in JS, rendering engines are different, and performance loss is also different.

The above mentioned is the process of parsing and rendering, and then we will talk about the process of user interaction. User’s operation will cause redrawing and rearranging, rearranging will definitely cause redrawing, but redrawing will not necessarily cause rearranging. How can this cause rearrangement? Simple definitions, changes in DOM structure, and changes in geometric attributes in DOM styles will lead to rearrangement. Geometric attributes, as the name implies, are commonly known as box model attributes such as width, height, border, outer patch, inner patch, etc. There are also margin attributes such as offset.

Rearrangement is the most energy consuming, and the ways to reduce rearrangement are:

1. If you need to change the DOM several times, first change it in memory and then insert it into the DOM once.

2. Same as above. If you change the style several times, synthesize one and insert it into DOM.

3. Since the values of position are absoute and fixed, they are separated from the document flow. Operating such DOM nodes will not cause whole page rearrangement. Therefore, the animation element sets position to separate it from the document stream.

4. When the DOM node’s display is equal to none, it will not exist in the rendering tree, so if there are more complicated operations, first make its display equal to none, wait until all operations are completed, then set the display to block, thus rearranging only twice.

5. When acquiring the attribute value that will cause rearrangement, the variable is stored and will not be rearranged again when used again. Obtaining these attributes will cause rearrangement: offsetTop, offsetLeft, offsetWidth, offsetHeight, scrollTop, scrollLeft, scrollWidth, scrollHeight, clientTop, clientLeft, clientWidth, clientHeight

This is how the browser turns resources into pages visible to the naked eye. In addition to the performance optimization summarized according to the browser process, we also need to look at javascript as a program and the optimization needed. Let’s look at javascript’s garbage collection mechanism first.

Javascript’s engine will log off local variables that are no longer in use at regular intervals, freeing up the memory it occupies. However, the existence of closures will make references exist all the time and cannot be released. The life cycle of a global variable does not end until the browser unloads the page. So generally speaking, memory overflow is caused by the non-release and closure of global variables. In order to prevent memory overflow, we can do the following:

1. The business code is placed in the anonymous immediate execution function and will be released immediately after execution.

2. Use less global variables and manually cancel out the variables that are used up at the same time.

3. Use callbacks instead of closures to access internal attributes

4. When closures are unavoidable, treat the details carefully. Write it off when not in use.

5, through the browser’s own tools profiles, to check the memory activity. If it is wavy, it is normal. If the increase is gradual and inclined, it means that some memory will not be released and the corresponding function needs to be checked.

Last but not least, the value returned asynchronously in the function is often the same:

Var getList = function(){ $.ajax().then(function(data){

  Return data;

}) };

Var users = getList();

There is no doubt that because the return within the function is asynchronous, the return can only be undefined, not the desired data. Therefore, in order to return data, the async property of ajax is set to false, and asynchronous is changed to synchronous to obtain data. However, the biggest problem is that synchronization will interrupt the rendering process, that is, the entire page is stuck while waiting for the request to return, and the user operation will not respond. The real solution to this problem is to return the promise object instead of changing asynchronous to synchronous.

Author: Ma Zongze

Expand reading:Data in Taiwan: Construction Practice of Yixin Agile Data in Taiwan | Record of Sharing