Why do we need to know how browsers work?
Write better code and provide a better user experience
Browser architecture
- The user interface
- Browser engine
- Rendering engine (the core of a browser, or what we call the browser kernel)
The following uses Chrome as an example to describe how the browser works
A browser is an application running on an operating system. Each application enables at least one process to perform its functions. Each process usually performs many tasks, and the process creates threads to perform small tasks
- Process is the operating system for resource allocation and scheduling of the basic unit, can apply for and have computer resources, process is the basic implementation of the program entity
- A thread is the smallest unit that an operating system can schedule. A process can have multiple concurrent threads, each of which performs different tasks in parallel
- When we start a program, a process is created to execute the task code, and the process is allocated memory, where the state of the application is stored. When the application is closed, the memory space is reclaimed.
- A process can start more processes to perform tasks. Since the memory space allocated by each process is independent, if some data needs to be transmitted between two processes, it needs to be transmitted through the inter-process communication channel IPC.
- Many applications have a multi-process structure, which is designed to prevent one process from getting stuck, and because the processes are independent of each other, the entire application is not affected.
- Threads in the same process can directly communicate with each other and share data.
Modern browsers adopt a multi-process browser architecture
-
The browser process is responsible for coordinating with other browser processes
-
The web process is responsible for initiating and receiving web requests, the GPU process is responsible for rendering graphics, and the plug-in process is responsible for controlling all plug-ins used by the site, such as Flash
-
The renderer process controls the display of all contents within a TAB, and the browser creates a process for each TAB by default
How browsers render
-
When you type an address into the address bar, the UI thread of the browser process captures what you’re typing, and if you’re visiting a web address, the UI thread starts a network thread that requests DNS for domain resolution and then starts connecting to the server for data.
-
If you type a list of keywords instead of a web address, the browser knows you’re searching and will use your default search engine.
-
When a network thread obtains data, it uses SafeBrowsing to check whether the site is a malicious one. If so, a warning page will be displayed telling you that the site has a security problem and that the browser will block your access. Of course, you can continue the visit by force. SafeBrowsing is a site-security system within Google that checks the data on a site to determine whether it is secure. For example, by checking to see if the IP address of the site is on their blacklist.
-
When the returned data is ready and the security checks pass, the network thread notifies the UI thread, which then creates a renderer process to render the page. The browser process passes the data to the renderer process through the IPC pipeline to formally enter the rendering process.
-
The core task of the renderer process is to render HTML, JS, CSS, IMG and other resources into web pages that users can interact with.
-
The main thread of the renderer process parses the HTML to construct the DOM data structure. The DOM document object model is the internal representation of a page by the browser. HTML is first Tokeniser tokenization, through lexical analysis, the input HTML content is parsed into multiple tags, DOM tree construction is carried out according to the identified tags, Document object is created in the DOM tree construction process, and then the DOM tree with Document as the root node is constantly modified. Add various elements to it.
-
HTML code often introduces additional resources such as images, CSS and JS scripts. Images and CSS resources need to be downloaded from the network or loaded directly from the cache. These resources do not block HTML parsing because they do not affect DOM generation, but when script tags are encountered during HTML parsing, the HTML parsing process is stopped and the browser does not know if js execution changes the HTML structure of the current page. If the JS code calls the document.write method to modify the HTML, the previous PARSING of the HTML is meaningless. That’s why we’ve been talking about putting the script tag in place, or using the Async or defer properties to asynchronously load the executing JS.
-
After the HTML parsing is complete, we get a DOM tree. The main thread generates a Layout tree by traversing the DOM and calculating the style. Each node in the layout tree records the X, Y coordinates and border size. Display: None does not appear in the layout Tree. The content element is added to the before pseudo-class. The content content will appear in the Layout tree, not in the DOM tree. This is because DOM is obtained through HTML parsing and does not care about style. The Layout tree is generated according to the DOM Tree and the calculated style, and the layout tree is corresponding to the node displayed on the screen at last.
-
With constant refinement, Chrome now uses a more complex rasterization process called Compositing. Compositing is a technique for dividing sections of a page into layers, rasterizing them separately and Compositing the page in separate threads of the Compositor thread. In simple terms, all the elements of the page are layered according to certain rules, rasterized layers, and then only need to combine the contents of the viewable area into a frame for the user to display.
-
The network thread of the browser process requests to obtain THE HTML data and sends the data to the main thread of the renderer process through IPC. The main thread interprets THE HTML to construct a DOM Tree, calculates the style, generates a layout Tree according to the DOM Tree and the style, and generates a drawing sequence table by traversing the layout Tree. Then the main thread will layout Tree and draw sequence information together to the synthesizer thread, synthesizer thread according to the rules of the process of layer, and the layer is divided into smaller blocks to the raster thread for rasterization, rasterization, synthesizer thread will get the raster thread from the “Draw Quads” block information, according to these information, The synthesizer thread synthesizes a frame, and then passes that composite frame back via IPC to the browser process, which then passes it to the GPU for rendering, and finally displays it on your screen.
-
When we change a size position attribute, we redo the style calculation, layout, drawing, and everything else. This behavior is called rearrangement. When we change the color properties of an element, the layout is not retriggered, but the style calculation and drawing are still triggered, which is redrawn. We can see that rearrangements and redraws occupy the main thread, and js runs on the main thread.
-
If you’re writing an animation that constantly redraws and rearranges, the browser needs to do style calculation, layout and drawing at every frame, and we know that pages need to refresh at more than 60 frames per second to keep the user from feeling stuck.
-
If you’re running animation, there are a lot of js tasks need to be performed, because the layout drawing and the execution of js is run in the main thread, when in a frame of time, after the layout and drawing, and the rest of the time, js will get access to the main thread, if js execution time is too long can lead to the next frame at the beginning, js not promptly returned to the main thread, When the next frame of animation is not rendered on time, the page animation freezes.
-
The requestAnimationFrame API can help solve this problem. The requestAnimationFrame method is called every frame. Using the API’s callback parameters, we can know how much is currently left in each frame. We can divide the JS running tasks into smaller pieces and return them to the main thread before time runs out
-
CSS has an animation property called transform. Animations implemented by this property do not go through layout and drawing, but run directly in the Compositor and Rasterizing threads, so they are not affected by js execution in the main thread. More importantly, the transform animation saves a lot of computation time because it doesn’t need to go through layout drawing style calculations. Can make complex animations smoother.
The resources
How does a browser work?