Do front-end performance optimization, from the idea is to make the page rendering faster, more smooth, so which links will affect the page rendering? Let’s start with a common front end test: what is the process from entering the URL to displaying the page?
I. Browser rendering process
There are two main parts, one is resource loading and parsing (first rendering), and the other is user interaction (running).
1. Resource loading and parsing (first rendering)
Simple demonstration with a flow chart.
Graph LR enter URL, initiate HTTP request, get resource, parse HTML:DOM tree, parse CSS:StyleSheets, Layout tree, Generate Layer, redraw, mix bitmap, display
So what performance tuning can we do in the first part?
-
HTTP part
1.1 DNS Resolution: Generally, the URL we enter in the address bar is a domain name, such as Baidu.com. However, in the world of computers, domain names cannot be understood and need to be converted into IP addresses for communication. Therefore, DNS resolution is required, that is, domain names are resolved into corresponding IP addresses. From this point of view, the fewer domain names that need to be converted, the less time you need to do DNS. So you can appropriately reduce the resources placed domain name.
1.2 Cache, (1) If the browser detects that HTTP has a cache and has not expired, it directly uses the cache resource. The response header cache-control: max-age can be set on the server to set the cache time of resources. (2) Extract common code and reuse it.
1.3 TCP Connection: Common browsers limit the number of concurrent connections to the same domain name. For example, Chrome limits the number of concurrent connections to six. If the number exceeds six, a queue is required. Therefore, different resources should be placed under different domain names to increase the number of parallel TCP connections. This conflict with the optimization policy of DNS resolution, and a balance needs to be struck.
1.4 Resource compression, (1) The browser and server can specify the resource compression method, request header set accept-encoding:gzip, deflate, br; Response header set Content-encoding :gzip. The browser supports GZIP, Deflate, and BR compression. (2) Through the construction tool, the front-end code is compressed, delete Spaces and so on.
-
Apply colours to a drawing part
2.1 HTML parsing, (1) File parsing is performed from the top down, if the CSS file is placed at the bottom, the CSS will be parsed again after parsing the DOM structure, which causes backflow and redraw, so the CSS should be placed in the header. (2) When script tags are encountered, HTML and CSS parsing will be suspended and javaScript will be executed, which hinders the time for users to see the first screen. Try to place unnecessary javaScript codes at the bottom of the body. There is another processing method. You can add defer or async properties to the script tag and the javascript will be loaded asynchronously without blocking HTML and CSS parsing.
2.2 CSS Parsing: The order in which the CSS is written is also important. If the CSS attributes, such as color and font, are first resolved, the CSS layout needs to be calculated again when the attributes are located. Therefore, it is recommended to write the CSS in the following order:
- Position, display, float, left, top, right, bottom, overflow, clear, z-index
- (2) Its attributes: width, height, padding, border, margin, background
- (3) Text style: font-size, font-size, font-style, font-weight, color
- (4) Text attribute: text-align, text-indent
- Css3: content, box-shadow, border-radius, transform…
2.3 Pre-rendering, in coordination with the skeleton screen, before the interface request is returned, the content can be occupied to reduce user anxiety.
2.4 JS parsing, multiple script tags will create multiple JS parsing environment, can merge small JS logic code, improve the speed of parsing.
2. User interaction (run)
-
DOM manipulation consumes a lot of performance and will cause backflow and redrawing. You can cache query objects and merge multiple updates. For example, Vue adopts an asynchronous update strategy to update multiple DOM operations at once to improve performance.
-
Animation, which is also a common feature, can also cause backflow and redraw if the element position changes with each frame. (1) CSS adopts will-change to inform which attributes will be changed in advance. For example, opacity and transform will layer elements, and GPU will be used to accelerate animation, deform the current elements and perform bitmap synthesis. (2) JS uses requestAnimationFrame instead of timer to synchronize frame changes with display updates to avoid frame loss and delay.
Ii. Browser principle
The second part is a brief introduction to the principles of the browser, which is multi-process architecture. We usually say JS is single threaded, so what exactly does that mean? With that in mind, let’s move on.
1. Processes and threads
- Process is the smallest unit of CPU resource allocation. When starting a program, the operating system will create a piece of memory for the program, which is used to store code, running data and a main thread to execute tasks. We call such a running environment process.
- Thread is the minimum scheduling of CPU tasks, thread is attached to the process, and the use of multi-thread parallel processing in the process can improve computing efficiency.
2.Chrome multi-process architecture
Take Chrome as an example. The multi-process architecture of modern browsers consists of the main browser process, GPU process, network process, rendering process and plug-in process.
- Browser process. It is mainly responsible for interface display, user interaction, sub-process management, and storage.
- Render process. The core task is to turn HTML, CSS, and JavaScript into web pages that users can interact with. Both the typography engine Blink and JavaScript engine V8 run in this process. By default, Chrome creates a rendering process for each Tab Tab. For security reasons, renderers are run in sandbox mode.
- Process of GPU. In fact, Chrome didn’t have a GPU process when it was first released. The original intention of using GPU was to achieve 3D CSS effect, but later the UI interface of web page and Chrome were drawn on GPU, which made GPU become a common requirement of browser. Finally, Chrome has introduced GPU processes on top of its multi-process architecture.
- Network process. It is responsible for loading web resources on the page. It used to run as a module in the browser process until recently, when it became a separate process.
- Plug-in process. It is mainly responsible for the running of plug-ins. Plug-ins are prone to crash. Therefore, plug-ins need to be isolated through the plug-in process to ensure that the plug-in process crash does not affect the browser and page.
Review the rendering process from a process perspective again
- First, the browser process receives the URL request entered by the user, and the browser process forwards the URL to the network process. The actual URL request is then made in the network process.
- The network process then receives the response header data, parses it, and forwards it to the browser process.
- After receiving the response header data from the network process, the browser process sends a “CommitNavigation” message to the renderer process.
- After receiving the “submit navigation” message, the renderer process is ready to receive THE HTML data by directly establishing a data pipeline with the network process.
- Finally, the renderer process “confirms submission” to the browser process, which tells the browser process that it is ready to accept and parse the page data.
- When the browser process receives a “submit document” message from the renderer, it removes the old document and updates the page state in the browser process.
So, to solve our initial question, why JS is single threaded means that the JavaScript engine is a thread in the rendering process. This is why network requests don’t block JS code.