How Web Browsers Work — Behind the scene Architecture, Technologies, and Internal Working
By: Upender Bhardwaj
Tags: Browsers, Web Development, JavaScript, Architecture, HTML

A web browser is a software that allows us to surf the internet by loading various resources from web servers and then present the resources in an orderly manner. You might have heard of popular names such as Chrome, Firefox, Safari, the mighty Internet Explorer(mostly used to download other browsers), Opera, Avant, Microsoft Edge, Maxthon, UC Browser, Android Browser, Epic(Privacy Browser), Tor(Dark web proxy browser).

What are Browsers really?

To be honest, Browsers are hundreds of thousands of line of complicated C, C++ code. Browsers are just like other software which run on different Operating system to do a particular job. Just like we have video players like VLC, window media player which are used to run videos. We have Torrent which connects to the internet and downloads various files. We have tons of software(like Calculator, Paint, Calendar etc) which are written in various system programming languages( based on the type of operating system they are going to run on). In the same manner, we have Browsers, software written in C, C++(or other system programming languages) which reads(parses) HTML and shows the visual representation of code in the form of a web page. It is just a simple software just like any other software. But wait, is it really simple?

Many times a question pops up in mind how browsers work internally. How do they show pages from HTML, CSS, Javascript? How do they handle interaction between all of them internally? How do they interact with the OS or Machine? How do they make use of CPU and GPU? How do they make use of process and threads? How do they handle interprocess communication?

There are so many HOW and when we know HOW we ask WHY?

Browser process doing IPC(Interprocess communication)

But why should I care? Why should I learn how browsers work?

Because if you are a web developer you should know the internal working of the software your job depends on. Also, Browsers are not like other software, they are special. What makes them really special is their popularity. They are the most widely used software right now in the world.

A Course through the history of Web Browsers

To truly understand what web browsers are and why are they what they are at present, we need to travel to the beginning of the time. A time where there was no software known as browser and the web we know today was just a little kid.

In 1980, Tim Berners-Lee a contractor at CERN proposed and prototyped ENQUIRE, a system for CERN researchers to use and share documents (Everybody was looking an effective way to share documents at that time. Imagine doing this without a browser in today’s world. Could you?).

In 1989, Berners-Lee proposed Internet-based hypertext system. He then specified HTML and created both first web browser, named WorldWideWeb and first web server in 1990. Later, he renamed WorldWideWeb to Nexus. It was a very simple browser which couldn’t do much other than showing simple webpages by parsing HTML tags.

The first HTML specification comprised of just 18 tags, out of which 11 still exist in HTML 4. These tags were highly influenced by SGMLguid, a standardized SGML used at CERN.

In 1993, Mark Andreessen created Mosaic(later Netscape), a graphical browser which eventually ran on several popular offices and home computers. It was the first web browser to introduce images and text on the same page. This Browser promoted the boom of the internet in the early '90s.

Mark Andreessen established the company in 1994, that released Netscape Navigator and which resulted in, the browser wars.

In 1994, Tim Berners-Lee founded The World Wide Web Consortium (W3C) with the support of the European Commission and the Defense Advanced Research Projects Agency DARPA. W3C primary purpose was to foster the compatibility and agreement among industry members in the adoption of new standards defined by the W3C. It promoted open standards for the World Wide Web, pulled Netscape and Microsoft together with other companies to develop a standard for browser and later also for scripting languages called “ECMAScript”.

In 1995, Microsoft released Internet Explorer which competed with Netscape Navigator. Both browsers tried to gain an edge over the other by releasing a lot of unique features. One of such unique feature was Javascript(by Netscape) which is the most popular programming language today.

In 1997, W3C published the first version of the standard “ECMAScript” trying to pull various browsers together.

There were many versions of style sheets at that time like CSS and Javascript style sheets(by Netscape). We all know how it ended. Microsoft’s Internet Explorer won the browser wars as Microsoft integrated its browser with its operating system and therefore, gaining 99% of market share by 1999.

Unable to commercially sustain its product, Netscape open-sourced its product, creating Mozilla.

In 2002, Mozilla released Firefox. Firefox’s business model, unlike the business model of 1990s Netscape, primarily consists of doing deals with search engines such as Google to direct users towards them.

Apple’s Safari, the default browser on Mac OS X from version 10.3 onwards, has grown to dominate browsing on Mac OS X.

In 2008, Google release Chrome for windows which was destined to become the most popular browser of the next decade. Most of Chrome’s source code comes from Google’s open-source Chromium project, but Chrome is licensed as proprietary freeware. Chrome was assembled from 25 different code libraries from Google and third parties such as Mozilla’s Netscape Portable Runtime, Network Security Services, NPAPI(dropped as of version 45), Skia Graphics Engine, SQLite, and a number of other open-source projects.

So what do we learn from History of Browsers?

There are a number of things which we can note from History. Firstly, Browsers are the software that runs on multiple OS and thus utilizes many OS API’s to interact with hardware and software of OS such as the keyboard, mouse, sound, the internet/network, memory etc. Secondly, Browsers are like parsing software(like Tuning machines) which reads its code in HTML, paints its picture, read the CSS, apply the design, read the JS and apply the changes. Browsers evolved over a period of time, gaining complexity. They access the internet from a computer and can ping various web servers requesting various resources. Thirdly, there are many browsers and all behave in almost the same way. They all follow “ECMAScript” standard but still have few cross-browser compatibility issues. As sometimes it is very difficult for the developers of a Browser to implement a standard as easily as done by developers of another browser because of vastly different architecture and technologies used in their product.

In Conclusion, Browsers are a package of various software.

But you still haven’t explained how does browser work internally?

Okay, I admit, I have been procrastinating about the internal working as it is complex to explain and the reader should have a top-level understanding of what they are dwelling into. It is the time we dig into the advanced concepts.

The Browser Architecture — Simple

It simply explains the inputs from keyboards via OS API’s and then making calls to HTTP client using network interface. Then parsing HTML pages(rendering engine) and showing results to the display. Optional client refers to the CDN’s and images as Browser get them via a separate TCP connection. Optional Interpreter is the JS engine.

The Browser Architecture — Medium

Browser broad level Architecture

The browser’s consist of the above component where

User Interface is the top bar in the browser, where control lies. It includes space where we type the URL, have back/forward buttons, space where tabs and setting options are.

User Interface

2. Browser engine is the bridge between User Interface and the Rendering engine. Based on the inputs from a user it queries and manipulates the rendering engine.

3. Rendering engine is responsible for parsing HTML/CSS/XML and displaying it into the empty space below User-Interface. Based on the plugins and support it can display other types of media also(like pdf/word). There are two major rendering engines in market Webkit and Gecko. Basic functionality is that it parses HTML by looking for <,/,> and related symbols and attributes, then it parses CSS and finally scripts. A point to be noted is that all the parsing goes in parallel. Some are halted when others are working like HTML parsing is halted when CSS parsing is in process. Parsing preference highly depends on how and where script/link tags are placed (in <head> or in <body>). HTML parsing uses a tokenizing algorithm while CSS and script parsing takes place via popular top-down or bottom-up parsers. HTML parsing makes DOM while CSS parsing results in CSSOM. Both of which combine to make a render tree. This render tree has ‘document’ as its head and is exposed to JS as JS cannot directly use the DOM tree made by HTML parsers. Then the layout of elements is decided based on the CSS box model and position defined in CSS properties. This is finally painted. For all the async operations Browser uses the event loop.

Various browsers use various kinds of a rendering engine.

Chrome & Opera 15+: Blink (A fork of Webkit)

Internet Explorer: Trident

EdgeHTML: Microsoft Edge

Firefox & other Mozilla browsers: Gecko

Chrome (iPhone) & Safari: Webkit

A rendering engine is the heart of a Browser and we will discuss it in more details later.

4. Networking is fetching resources and handling everything related to the internet. Below is how resources are fetched when we type a URL in a browser:

The moment when we type the first letter, it will starts looking into bookmarks and history and give you meaningful suggestions.

Parse URL and retrieve protocol.

Conversion of NON-ASCII happens, using encoding to convert the URL.

Browser checks HSTS (HTTP Strict Transport Security) list, append HTTPS if URL found in the list, otherwise send via HTTP.

DNS Lookup: whom to lookup, 1. Browser DNS cache 2. OS cache 3. Call DNS server which local router/ ISP router.

Get the IP address of DNS(domain name server) server/default gateway using ARP (Address Resolution Protocol).

Opens port 53 and raises a UDP( User Datagram Protocol ) to DNS server (TCP/UDP depends on response size), If it is the default gateway it will recursively follow this procedure.

If DNS says that it does not know about an address. Browser searches it in the default search engine and shows up top 10 results.

Otherwise, once it has the IP address of destination server, it starts HTTP (port 80)/ HTTPS(port 443) request and it will request for TCP socket connection.

Request reaches to Network layer for filling TCP header, Transport layer for filling IP header, data link layer for Ethernet frame header.

Packet flows in the network in digital or cellular.

3-way handshake between server and client and data is sent to the client on request.

Transport layer security handshake happens and finally, the Browser gets the data in chunks.

5. Javascript interpreter is JS engine which reads and executes the js code and handles the result to the rendering engine.

Google Chrome: V8 ( Developed in-house by Google as part of The Chromium Project). It is used in Node.js!

( Developed in-house by Google as part of The Chromium Project). It is used in Node.js! Mozilla Firefox: SpiderMonkey( The first JavaScript engine in history.) Developed by Brendan Eich, the creator of JavaScript, while he was at Netscape.

The first JavaScript engine in history.) Developed by Brendan Eich, the creator of JavaScript, while he was at Netscape. Safari: Nitro (formerly SquirrelFish)

(formerly SquirrelFish) Edge: Chakra( Open-sourced as ChakraCore. In 2016, Microsoft created a PR in the Node.js GitHub repo to use ChakraCore instead of V8. This PR was expanded out into its own project and now lives here as a project of the node organization.)

Open-sourced as ChakraCore. In 2016, Microsoft created a PR in the Node.js GitHub repo to use ChakraCore instead of V8. This PR was expanded out into its own project and now lives here as a project of the node organization.) Opera: V8 ( If something works on Google Chrome, you can expect it to work on Opera due to the identical rendering engine + JavaScript engine used.)

If something works on Google Chrome, you can expect it to work on Opera due to the identical rendering engine + JavaScript engine used.) IE: Chakra

Because various browsers use different JS engine we can say that support for various features of ESNext differs in browser support. Internal implementation of JS also differs in some respect. For example, Array.sort in Mozilla uses merge sort whereas in Chrome it uses QuickSort and InsertionSort, for smaller arrays.

6. UI backend is used for drawing basic widgets like combo boxes and windows. This backend exposes a generic interface that is not platform specific. It underneath uses operating system user interface methods.

7. Data Persistence is support for storage mechanisms such as localStorage, IndexedDB, WebSQL, and FileSystem. It is a small database created on the local drive of the computer where the browser is installed. It manages user data such as cache, cookies, bookmarks, and preferences.

The Architecture of Various Browsers —Truth (it’s complicated)

Chrome(Derived from chromium)

Render Engine Architecture (WEBKIT)

Webkit internal working

Chrome’s multiprocess architecture.

Chrome was the first browser with a multi-process architecture. Put simply, it encapsulates all logical functions in separate processes. More specifically:

One main (browser) process

(browser) process One GPU process

process Each tab : dedicated process

: dedicated process Each extension: dedicated process

Chrome gave each tab a process when it could; now it tries to give each site its own process, including iframes

Diagram of Chrome’s multi-process architecture. Multiple layers are shown under Renderer Process to represent Chrome running multiple Renderer Processes for each tab.

The benefit of multi-process architecture in Chrome

Even if one tab hangs, a user can simply close it and work on other tabs without any impact.

Saving more memory — Servicification in Chrome

The same approach is applied to the browser process. Chrome is undergoing architecture changes to run each part of the browser program as a service allowing to easily split into different processes or aggregate into one.

General idea is that when Chrome is running on powerful hardware, it may split each service into different processes giving more stability, but if it is on a resource-constraint device, Chrome consolidates services into one process saving memory footprint. A similar approach of consolidating processes for less memory usage has been used on a platform like Android before this change.

Per-frame renderer processes — Site Isolation

Site Isolation is a recently introduced feature in Chrome that runs a separate renderer process for each cross-site iframe. We’ve been talking about one renderer process per tab model which allowed cross-site iframes to run in a single renderer process with sharing memory space between different sites.

2. Firefox

Render Engine Architecture (Gecko)

Firefox’s multiprocess architecture

Mozilla started project Electrolysis as a gradual move to a multi-process architecture. This took 9 versions, from Firefox 48 to 56. The current architecture looks like this:

One main process

process One GPU process

process One extension process

process Up to 4 content (tab) processes

Note: Firefox introduced web assembly in version 52 which will change the way web developers work. Also, in version 57 Firefox introduced a completely new browser engine which made it fastest and most memory efficient browser in the market. With some code migration from c++ to Rust, Firefox is already set to change the trends of the market.

3. Safari

Safari’s Multiprocess Architecture

Safari, as of version 5.1 is also using multiprocess architecture but when it comes to performance it is behind Chrome and Firefox. One of many reasons for this is because Safari primarily focuses its functionality on IOS and Mac OS X. Introduction of MPA also led to a lot of issues(temporarily hanging of tabs) as was not fully compatible with Webkit and it was the real reason why chrome forked WebKit to blink and started to use it instead. This was solved with changes in MPA and WebKit in version 7.

Multiprocess Architecture increases the RAM usage of an OS which often upsets the Users. Firefox gives the option of toggling between 2 cores and 4 cores

Memory Comparison between all Major browsers.

4. Mosaic

A Traditional Browser architecture (Mosaic)

This Architecture is shown for curious users who wonder how old browsers looked like. Remember when you have to open an entire new browser window to open a website in parallel(there were no tabs).

Main working part of any browser is Rendering engine. Though there are many rendering engines used in the market, they are more or less the same in working. Companies often fork the popular rendering engine as per their own requirement.

Let’s Talk about the heart of Browser — Rendering Engine

The process of Rendering HTML is as follows

Rendering process

In reality, the browser receives data in a chunk of 8kb and does not wait for the whole HTML page to load. It starts rendering bit by bit

Image for the actual rendering process

Steps in parsing

Parsing

HTML Parsing

CSS Parsing

Parsing Scripts and Stylesheets

Parsing Scripts and Stylesheets

Parsing HTML

HTML cannot be parsed using the regular top-down or bottom-up parsers.

Reasons being

The forgiving nature of the language. The fact that browsers have traditional error tolerance to support well-known cases of invalid HTML. The parsing process in a reentrant. Usually, the source doesn’t change during parsing, but in HTML, script tags containing “document.write” can add extra tokens, so the parsing process actually modifies the input.

Unable to use the regular parsing techniques, browsers create custom parsers for parsing HTML. The algorithm consists of two stages — tokenization and tree construction.

Tokenization is the lexical analysis, parsing the input into tokens. Among HTML tokens are start tags, end tags, attribute names, and attribute values.

The tokenizer recognizes the token, gives it to the tree constructor and consumes the next character for recognizing the next token and so on until the end of the input.

HTML parsing flow

Basic example:

<html>

<body>

Hello world

</body>

</html>

The initial state is the “Data state”. When the “<” character is encountered, the state is changed to “Tag open state”. Consuming an “a-z” character causes the creation of a “Start tag token”, the state is changed to “Tag name state”. We stay in this state until the “>” character is consumed. Each character is appended to the new token name. In our case, the created token is an “HTML” token.

When the “>” tag is reached, the current token is emitted and the state changes back to the “Data state”. Consuming the “H” character of “Hello world” will cause creation and emitting of a character token, this goes on until the “<” or “</body>” is reached. We will emit a character token for each character of “Hello world”.

We are now back at the “Tag open state”. Consuming the next input “/” will cause the creation of an “end tag token” and a move to the “Tag name state”. Again we stay in this state until we reach “>”.Then the new tag token will be emitted and we go back to the “Data state”. The “</html>” input will be treated as the previous case.

Tree construction algorithm

When the parser is created the Document object is created. During the tree construction stage, the DOM tree with the Document in its root will be modified and elements will be added to it. Each node emitted by the tokenizer will be processed by the tree constructor. For each token, the specification defines which DOM element is relevant to it and will be created for this token.

Let’s see the tree construction process for the example input:

<html>

<body>

Hello world

</body>

</html>

Tree Construction of example

But wait, isn’t HTML forgiving in nature so what if I didn’t supply the end tag.

As per the Webkit documentation



1. The element being added is explicitly forbidden inside some outer tag.

In this case, we should close all tags up to the one, which forbids the element, and add it afterward.



2. We are not allowed to add the element directly.

It could be that the person writing the document forgot some tag in between (or that the tag in between is optional).

This could be the case with the following tags: HTML HEAD BODY TBODY TR TD LI (did I forget any?).



3. We want to add a block element inside to an inline element. Close all inline elements up to the next higher block element.



4. If this doesn’t help, close elements until we are allowed to add the element or ignore the tag.

CSS PARSING

Compared to HTML parsing CSS parsing can be done with top-down or bottom-up parsers as CSS does not have forgiving nature.

Lexicon

Here is the lexicon of CSS, taken from the W3C’s CSS2 Level 2 specification.

Syntax

Here is the syntax of CSS Level 2, taken from the W3C’s CSS Level 2 specification.

The parse tree of CSS is not exactly the CSSOM tree. The CSSOM tree is a CSS parse tree that is reformatted for consumption in the browser.

Stylesheets

The rendering engine parses HTML documents from the top-down.

When the rendering engine encounters a <style> element, it immediately parses the CSS within it; it ceases parsing of the HTML document, and focuses its attention to parsing the CSS rulesets. After it finishes parsing the CSS, it will return to parsing the main HTML document.

Scripts

If it is an inline script, the JS Engine component immediately executes the JavaScript. Once that is complete, the rendering engine returns to parsing the HTML document.

If it is an external script, the Networking component requests the given script. Once it arrives, the JS Engine executes it.

The reason that the rendering engine ceases parsing the HTML/CSS past the <script> is because <script> could potentially modify the HTML/CSS past the <script> . If the modification is major, there is no point in parsing past the <script> since so much will change anyway.

It’s worth noting at this point that stylesheets can block the execution of JS. Browsers block scripts from executing if there are any stylesheets still loading/being parsed/undiscovered.

Render Tree Construction

DOM + CSSOM = Render Tree

While the DOM tree is being constructed, the browser constructs another tree, the render tree. This tree is the visual representation in which the elements will be displayed. The purpose of this tree is to enable painting the contents in their correct order.

The render tree relation to the DOM tree

The renderers correspond to the DOM elements, but the relation is not one to one. Non-visual DOM elements will not be inserted in the render tree. An example is the “head” element. Also, elements whose display attribute was assigned to “none” will not appear in the tree (elements with “hidden” visibility attribute will appear in the tree).

Now you truly know the diff between Display: none and Visibility: hidden;

Difficulties

There are several difficulties with style computation:

Style data is huge. It consumes a lot of memory. Matching elements to CSS selectors can exhibit poor performance if not optimized well. Applying the correct styles can be complex, given the cascading nature of CSS and multiple, conflicting CSS declarations.

Difficulty #1: Lots of Style Data

WebKit and Gecko address this issue in different ways.

WebKit — Shared Style Data

WebKit’s Render Objects hold references to RenderStyle objects, which hold the computed visual information for the given render object.

RenderStyle objects are shared by Render Objects under certain conditions, to save space & increase performance.

Gecko’s Rule Tree+Style Context Tree

Gecko creates 2 additional trees to improve style computation: the Rule Tree and the Style Context Tree.

The Rule Tree is a tree of CSS rulesets. Its branch’s nodes consist of CSS rulesets with overlapping CSS selectors. Deeper nodes have more specific selectors/are subsets of higher nodes.

Difficulty #2: Matching Elements to Selectors

There are 3 sources for CSS styles:

CSS Rules (external via <link> or internal via <style> ) Inline Style Attributes ( <div style="background-color: goldenrod;"> ) Specific Style Attributes ( bgcolor="red" , valign="baseline" , etc.)

(These are deprecated. Don’t use them.)

But how to match elements is the hard part. If you match elements naively, you would have some major performance problems.

Example of Naive Solution: For every CSS ruleset, loop through every element to determine which ones it should apply to.

This would yield awful performance.

Before the browser begins parsing CSS rules, 4 hashmaps are created. These hashmaps will store the CSS rules. Each hashmap stores a different category of CSS rules, based on their selectors.

ID-selector CSS Rules

Class-selector CSS Rules

Type-selector CSS Rules

Miscellaneous-selector CSS Rules

This drastically improves the performance of element-selector matching.

You simply look-up an element’s corresponding CSS rulesets by using its ID/Class/Type/etc. as keys.

Webkit and Gecko both implement this optimization.

Difficulty #3: Applying Styles in the Correct Order

Very frequently, an element’s style property is declared more than once.

div p {

color: goldenrod;

} p {

color: red;

}

The order of style-application is known as the cascading order. It is fundamental to CSS’s nature. It’s even in the name!

According to the CSS2 Specification, § 6.4.1 Cascading Order, the cascading order is (in ascending priority):

User Agent Declarations (Browser Defaults) User Normal Declarations

(Browser users can actually set custom styles for themselves. For example, a vision-impaired user might set a default of font-size: 30px for all the websites they visit. This is what a “User” declaration is. Don’t confuse this with “User Agent” declarations. “User Agent” means browser.) Author Normal Declarations

(The styles that you, a page author/web developer, set.) Author !important Declarations User !important Declarations

(This is to provide the user with ultimate control over presentation. This is especially useful for people with accessibility demands.)

If two declarations fit the same order, (E.g. they are both User Normal Declarations), then sort by SPECIFICITY.

If two declarations fit the same order AND specificity, then sort by position in the stylesheet(s). The declaration that occurs later in the stylesheet(s) shall apply.

Gradual Process

If a given DOM node’s styles haven’t loaded (due to network latency) by the time <DOM node>.attach() is called, default placeholder-styles are used. The DOM node is flagged and its styles will update when they load.

Layout

Dirty Bit System

Global & Local Layout

Asynchronous & Synchronous Layout

The Layout Process

Upon creating a render object, it does not have a position or dimensions.

Layout is the calculation of these values.

HTML uses an intuitive flow-based layout model by default. This means that elements are laid out in the order that they appear: left-to-right, top-to-bottom.

Typically, elements “later” in the flow don’t affect elements “earlier” in the flow. So, for simple situations, only a single pass is necessary to lay out all elements. Some layout models such as display: table (and I think display: flex and display: grid ) may require multiple passes.

For positioning, the coordinate system is relative to the root render object. Typically, this is the HTMLDocument 's render object. ( HTMLDocument is the parent node of HTMLHtmlElement , the DOM node for <html> . It always wraps the HTMLHtmlElement .)

A render object’s position is the position of its top-left corner.

The root render object’s position is (0,0) , and its dimensions are the viewport’s dimensions. (The viewport is the portion of the browser window that displays webpages.)

Layout is a recursive process.

Each render object has a layout() method. So first, the root render object is laid-out. Then, it lays out its children by calling their layout() methods. Its children layout their children (RRO’s grandchildren). So on and so forth.

DIRTY BIT SYSTEM

Consider a webpage in the middle of its lifecycle — after its initial layout.

Suppose a DOM node’s style is changed. This change will affect layout. How do you handle this? Do you perform a Global relayout? Or do you perform a local relayout on the relevant render objects?

Ideally, you’d just perform a local layout. (But sometimes, you need to perform a global layout, because the change affects neighbor render objects).

To perform a local layout, you need the ability to distinguish dirty render objects from clean ones.

To attain this ability, browsers flag specific render objects as dirty if they require layout due to some change.

Actually, there are 2 types of dirty flags: dirty self & dirty children.

A dirty-self flag indicates that the render object itself requires layout.

A dirty-children flag indicates that 1+ of the render object’s children require layout. The render object itself may be clean.

GLOBAL & LOCAL LAYOUT

Global layout is required when changes affect all render objects.

Examples:

A global style change, like changing all font-family or font-size values.

or values. Resizing the screen.

(Bolded b/c it’s not obvious that a non-stylistic change could force global layout.)

Local layout only targets dirty render objects. It’s performed asynchronously by the rendering engine, which is single-threaded.

ASYNCHRONOUS & SYNCHRONOUS LAYOUT

Global layouts are almost always synchronous.

Local layouts are performed asynchronously and in batches by default. The rendering engine will attempt to group several pending layouts, then apply them asynchronously in 1 sweep. This is to improve performance. Applying many individual layout + paint procedures would yield poor performance. Whereas applying all the layouts, then painting once is better.

However, there is a situation that forces local layouts to perform synchronously:

scripts demanding style information, like clientWidth .

In such situations, the script must immediately know style information that is up-to-date. The pending layout cannot be performed asynchronously at a later time. It must be performed now because a <script> is waiting for it, in order to obtain up-to-date style information.

Therefore, because the rendering engine and the JS engine share the same thread, the demanding script will immediately halt, wait for the layout to apply, then resume.

Poorly written scripts can cause many synchronous, individual local layouts. This is known as layout thrashing. Avoid this when possible.

THE LAYOUT PROCESS

Layout is typically performed as such. For each render object:

The given render object determines its width.

(This derives from the containing block’s width, the render object’s width style-property, and the render object’s margin and borders.) For each of its child render objects,

1. Position the child render object.

2. Layout the child render object if needed.

Often, when the webpage is en media res, child render objects are clean; their dimensions don’t need to be recalculated. But if they are dirty, or if a global layout is occurring, they will need re-layout. Sum the child render objects’ heights. Set the parent render object’s height to this cumulative height. Flag the given render object as clean.

Painting

Global & Local Painting

The Painting Order

Webkit’s Bitmap Deltas

The Rendering Engine’s Threads

Event Loop

GLOBAL & LOCAL PAINTING

Similar to the rendering process, painting can either be global or local. Regions of the content are flagged as dirty to enable local paints. Then, the rendering engine invokes the UI Backend component of the browser to actually repaint the dirty regions. Recall that the UI Backend relies on the host OS’s API to paint content onto the screen.

THE PAINTING ORDER

Render objects have many layers on the z-axis. Their painting order (from back to front) is:

Background Color Background Image Border Children Render Objects Outline

WEBKIT’S BITMAP DELTAS

For a given painting-region, WebKit will record it as a bitmap. When the painting-region becomes dirty, WebKit won’t repaint the entire region. It will only paint the deltas from the old bitmap to the new bitmap. This provides some optimization.

THE RENDERING ENGINE’S THREADS

As I mentioned earlier, the rendering engine is single-threaded. Also, it shared the same thread as the JS Engine of a browser. This godlike thread is known as the browser’s main thread. Networking occurs in a separate thread.

Relevant section from https://www.chromium.org/developers/the-rendering-critical-path#TOC-Browser-Thread-Architecture

EVENT LOOP

The browser’s main thread uses an event loop to handle asynchrony. It’s an infinite loop that pulls tasks such as layout, painting, and JS execution from a message queue and processes them.

// The End !!

References (What is copied from Where :))

History of Web Browsers

Overall Idea and original article to display the working on browsers

Last part of CSS parsing, Layout parsing, Painting is entirely taken from

Multiprocess Architecture

Memory consumption of Multiprocess Architecture

Diagrams of various Architectures

High-level understanding of Browser working