Skip to main content

The Past and Present of Browser Architecture

· 13 min read
Pranjal Kumar
Software Engineer - Bentley

Cover | Pranjal Blogs: pranjal-barnwal | Pranjal Kumar, Hazaribag Jharkhand | SWE Bentley Systems

The front end may be a rapidly changing field, and it is difficult for us to understand all aspects of it. However, front-end systems generally run in browsers, so a better understanding of browsers can help us develop front-end applications more effectively. This is also one of the reasons for this article and serves as an instance analysis of runtime.

The browser architecture has undergone a transition from single-process browsers to multi-process browsers. Emphasizing stability, smoothness, and security, processes have been decomposed into rendering, GPU, network, and plugins, improving the cleanliness of the architecture. To review the browser's architecture, it is necessary to further understand the process of opening pages, the page rendering process, and the browser plugin mechanism. By organizing the timeline of Chrome extension versions, especially the transition from Manifest V1 to Manifest V3, one can gain a relatively comprehensive understanding of how browsers have evolved.

1. Evolution of Browser Architecture

Before 2007, the typical browser architecture was like this:

None | Pranjal Blogs: pranjal-barnwal | Pranjal Kumar, Hazaribag Jharkhand | SWE Bentley Systems

Single-process browser architecture runs the entire web browser in a single operating system process, consolidating tasks such as network processing, plugins, JavaScript runtime, rendering engine, page management, and user interface elements into one execution space. While simplifying resource management, this architectural design has the following main issues:

  • Instability — Plugins and rendering engines handling functions like web video and games run in the same process. Crashes in plugins or rendering engines can lead to the entire browser crashing, with this instability particularly evident when dealing with complex JavaScript code.
  • Lack of smoothness — All modules (including page rendering, JavaScript execution, and plugins) share a single thread. If a script becomes very time-consuming, it can monopolize the entire thread, causing other pages to be unresponsive and resulting in delays across the whole browser.
  • Insecurity — Plugins running on pages can access operating system resources. Malicious plugins can exploit this access to release viruses compromising security and potentially stealing sensitive information like user credentials.

The advantage of a single-process browser is that all browser components operated within one process simplify resource management and coordination. Single-process browsers typically exhibit lower memory usage rates which benefit resource efficiency improvement. Tasks run sequentially within a unified process.

The Chrome process architecture released in 2008 is an example of a multi-process browser as shown in the diagram below:

None | Pranjal Blogs: pranjal-barnwal | Pranjal Kumar, Hazaribag Jharkhand | SWE Bentley Systems

Early browser architectures divided functionality into three main processes: browser, plugins, and rendering. Each page and its plugins run independently in dedicated rendering and plugin processes, communicating through IPC.

Inter-process communication (IPC) is a mechanism that allows processes to communicate and synchronize operations on a computer. It facilitates efficient data exchange and coordination between different programs. Key IPC mechanisms include shared memory, allowing processes to synchronize access to shared public memory areas using semaphores. Named and unnamed pipes provide one-way communication; IPC in Linux typically involves sharing files or shared memory storage with semaphores. Message queues support asynchronous communication, helping separate sender and receiver processes. Additionally, processes can communicate through signals to notify specific events or requests. Sockets extend IPC across different machines using network protocols.

Multi-process browsers enhance stability; isolated processes prevent crashes from affecting the entire browser. Crashes of pages or plugins only affect their specific process, ensuring the stability of other pages and the browser itself. Running JavaScript in a separate rendering process also isolates its impact; if a script blocks the rendering process, it only affects the current page while leaving the rest of the browser unaffected since each page runs scripts in its dedicated rendering process. Furthermore, Chrome places plugins and rendering processes in sandbox environments limiting read/write access to data — even if malicious software executes within these processes it cannot breach the sandbox for system permissions gain — this is an example of a compartmentalized architecture pattern.

A sandbox is a testing environment that allows users to run programs or open files without impacting the entire system's operation. In cybersecurity fields, sandboxes analyze potential malicious code execution detecting threats for mitigation purposes.

In recent versions of Chrome browsers have key components as shown below:

None | Pranjal Blogs: pranjal-barnwal | Pranjal Kumar, Hazaribag Jharkhand | SWE Bentley Systems

The browser process manages the display interface, user interaction, and subprocess coordination, and provides storage functions. It acts as a "scheduler" to coordinate other processes, for example calling the network process when entering a URL. The rendering process converts HTML, CSS, and JavaScript into interactive web pages and runs the V8 engine. For security reasons, Chrome creates a separate rendering process for each tab in sandbox mode.

The GPU process was initially designed for 3D CSS effects but later expanded to drawing web pages and the Chrome UI interface. Introduced in Chrome's multi-process architecture to meet common browser needs. The network process independently loads page network resources; originally a module within the browser process, it now runs as a separate process. The plugin process manages plugins to prevent crashes affecting browsers and pages due to the inherent instability of plugins.

The modern browser architecture is shown in the diagram below:

None | Pranjal Blogs: pranjal-barnwal | Pranjal Kumar, Hazaribag Jharkhand | SWE Bentley Systems

2. Behind the browser page opening

  1. Adding a tab initiates the creation of basic processes: system browser, rendering, GPU, and network processes.
  2. User input triggers the browser process to check, assemble protocols, and form a complete URL.
  3. The browser process sends the URL request to the network process through inter-process communication.
  4. The network process checks the local cache for requested resources. If found in the cache, it returns them to the browser process.
  5. If not in the cache, the network process sends an HTTP request to the web server.
  6. The network process parses responses and checks status codes; non-200 status codes prompt specific handling logic.
  7. For a 200 response, the browser process checks Content-Type. A byte stream triggers a download manager while HTML signals readiness for rendering.
  8. The browser process verifies if the current URL matches the root domain of existing rendering processes. If different, it starts a new rendering process.
  9. The browser sends a "submit document" message to the rendering process establishing the data transfer pipeline with the network process.
  10. After receiving data, the rendering process confirms back to the browser. Browser updates interface state including security indicators, address bar URL, browsing history, and webpage content.

3. Rendering process

Modern browsers use strategies such as lazy loading and caching to prioritize performance. Browsers display web content through rendering processes. Key stages include HTML parsing, CSS styling, layout creation, and drawing, with specific steps as follows:

  1. User input — Enter the URL in the browser's address bar.
  2. URL parsing — Parse the URL to identify the protocol, host, port, and path.
  3. DNS lookup — Convert the hostname into an IP address through DNS lookup.
  4. Socket connection — Establish a connection between the user and server IP.
  5. HTTP request — Send an HTTP request to the server specifying the protocol.
  6. Server processing — The server evaluates requests and determines handling plugins (e.g., PHP, Java).
  7. Processing via plugins — Access databases or other resources as part of an HTTP response.
  8. Browser response — Send back the HTTP response to the browser.
  9. Response analysis — Analyze HTML data from the response in browsers.
  10. DOM tree creation — Build a Document Object Model (DOM) tree from parsed HTML.
  11. Stylesheet parsing — Parse stylesheets linking presentation data to DOM nodes.
  12. JavaScript execution — Execute JavaScript code to modify DOM elements.
  13. Page rendering — Display web pages using DOM and style data.

3.1 HTML Parsing

The browser reads HTML character by character, identifying elements, attributes, and text, then constructs the DOM tree representing the structure of the webpage to ensure the correct display of HTML code.

3.2 CSS Object Model

The CSS Object Model expresses the styles applied to HTML elements, similar to the structured hierarchy of the DOM tree, taking into account the specificity and cascading nature of styles, allowing access, manipulation, and computation of styles.

3.3 Layout Manager

Layout managers combine the DOM and CSS object model to form a rendering tree, determine the size of the Box based on content, padding, etc., and use various methods to build specific positions. At the same time, stacking contexts and Z-index are used to handle overlapping elements and batch processing techniques are used to optimize layout changes. Finally, elements are drawn on the screen and continuously updated during user interaction.

4 Plugin Mechanism

When using plugins, the browser's operation is simpler than regular web pages. The rendering process is responsible for running the webpage. When a page is opened, contentscript.js is loaded and injected into the webpage environment, operating similar to JavaScript by manipulating the DOM tree and altering display. The GPU process supports hardware functions for rendering plugin interfaces, while the network process manages external resource requests within plugins, such as dependencies on external JS resources. Simultaneously, the storage process provides local storage functionality for plugins using chrome.storage.local to store and retrieve data in Chrome extensions. The browser process acts as a bridge facilitating communication between Extension Page and contentscript.js.

4.1 Development History of Plugins

The development process of the plugin mechanism is as follows:

YearVersionDescription
August 2012Manifest V1Chrome plugins were initially based on Manifest V1, defining basic functions and permissions.
April 2013Chrome26 StableIncluding support for Manifest V1 plugins.
May 2014Chrome35 StableIncremental updates of the browser continue to support Manifest V1 plugins.
September 2014Chrome 37 StableFurther improvements and bug fixes for Manifest V1 plugins.
May 2015Chrome43 StableContinued support for Manifest V1.
December 2015Manifest V2Introduced Manifest V2, bringing better security and additional features.
June 2016Chrome51 StableManifest V2 became the standard for plugin development.
September 2016Chrome53 StableContinuous improvement and optimization of Manifest V2.
January 2019Manifest V3 BirthedFocuses on security, performance, and development flexibility.
March 2020Chrome80 StableWhile manifest v2 remains the standard for plugins. manifest v3 is available for testing but not mandatory yet.
March 2021Chrome89 stableManifest v2 still default but attention shifting towards manifest v3.
October 2021Chrome94 stableManifestv3 starts enforcing some features with migration guides & tools provided to developers.
March 2022Chrome98 stableManifestv3 becomes the default new plugin version while continuing to support manifestv2.
August 2022Chrome104 stableAll plugins fully transitioned to manifestv3 officially announcing no more support for manifestv2.
March 2023Chrome108 stableMaintained full support for manifestv3 ensuring smooth transition for all plugins.
July 2023ManifestV3 PreviewAllowing developers to explore upcoming changes and provide valuable feedback.
October 2023Chrome versionFurther improved support for ManifestV3 in Chrome Stable Version addressing all issues reported during the preview stage.
January 2024Pre-stable releaseEncouraging developers to migrate their extensions to Manifest V3 and providing comprehensive documentation and migration guidance.
January 2024Manifest V3 pre-stable version releasedManifest V3 has reached a stable state, encouraging developers to migrate their extensions to V3 and providing comprehensive documentation and migration guides.
March 2024Chrome116 stableFully supports Manifest V3, developers update their plugins to ensure compatibility with the latest standards.

Overall, Chrome extensions (also known as add-ons) have gone through the development of 3 major versions: Manifest V1, Manifest V2, and Manifest V3.

Manifest V1 (MV1) was the initial version of the Chrome extension manifest and has been deprecated. Manifest V2 (MV2) is the mainstream version widely used in current Chrome extensions, providing a robust framework for building extensions with enhanced browser functionality features. Manifest V3 is the latest version gradually replacing MV2. The introduction of MV3 aims to address security and performance issues by strengthening security measures and promoting better performance in extension development. Starting from Chrome 127 (June 2024), Google will begin disabling Manifest V2 extensions in pre-stable versions of Chrome, encouraging developers to transition to MV3.

4.2 Features and Version Migration of Manifest

Features of Manifest V2:

  • Use script-src 'self'; object-src 'self'; Content-Security-Policy (CSP) to set the default content security policy.
  • Plugin package resources are no longer available externally; the whitelist is listed through the web_access_resources property in the manifest.
  • Changes have been made to browser operation APIs and page operation APIs, which chrome.extension replaces chrome.self pointing to the plugin itself, chrome.tension.getTabContentses is replaced by tension.getView, Port.tab is replaced by runtime.Port, etc.

Features of Manifest V3:

  • Manifest V3 introduces Service worker, replacing background pages.
  • Network request modifications use the new Declarative Net Request API instead of the deprecated webRequest API.
  • Remote code execution is not allowed; only JS in extension packages can run.
  • Promises have been added to many methods and callbacks are still supported.
  • Browser Action API and Page Action API are unified into a single Action API.
  • Web-accessible resources are limited to specified sites and extensions.
  • Content Security Policy (CSP) allows specifying separate CSPs for different execution contexts, where executeScript can only run script files and functions, not arbitrary strings.

Manifest V3 represents a significant shift from V1 and V2, driven by Chrome's commitment to improving privacy, security, and overall extension performance. Unlike previous versions, Manifest V3 prioritizes resource efficiency, addressing concerns about Chrome's historically high resource usage. Its core goal is to optimize browser performance by limiting system resource consumption through extensions. While imposing additional restrictions, Manifest V3 introduces significant benefits. The ServiceWorker feature allows extensions to operate without constantly residing in the background, enabling the recycling of extension resources and effectively reducing overall browser overhead. Restrictions on rule calculations serve as a control mechanism to ensure that individual extensions do not excessively consume resources. These changes collectively contribute to a smoother browsing experience in Chrome, meeting users' expectations for improved browser efficiency.

When migrating from V2 to V3, due to the absence of background.html for configuring page backgrounds, XMLHttpRequest on the Windows object is no longer applicable for constructing AJAX requests in background.html as it was in the V2 version. Instead, data must be retrieved using extraction methods.

Furthermore, the short lifespan of service workers and their termination during periods of inactivity leading to occasional startups, runs, and terminations throughout the plugin lifecycle introduce instability. In MV2 global variables were used directly for storing data; therefore modifications are required in backound.js logic to enhance stability and functionality under these circumstances. Additionally transitioning from webRequest API to statativeNetRequest API necessitates substantial code refactoring.

4.3 Main Components of Chrome Extensions

4.3.1 manifest file

The manifest.json file is very important for Chrome extensions located in the root directory. It is used to configure all plugin settings, with basic parameters such as Manif_version, name, and version.

An example of Manifest V2 is as follows:

<button class="hljs-copy p-1 bg-gray-300 dark:bg-black">Copy</button><merlin-component id="merlin-code-summarizer" class="merlin-code-summarizer"></merlin-component><code class="overflow-x-auto mt-1 language-json bg-gray-100 dark:bg-gray-900 hljs"><span class="hljs-punctuation">{</span>
<span class="hljs-attr">"manifest_version"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">2</span><span class="hljs-punctuation">,</span>
<span class="hljs-comment">// Plugin name</span>
<span class="hljs-attr">"name"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"..."</span><span class="hljs-punctuation">,</span>
<span class="hljs-comment">// Plugin version</span>
<span class="hljs-attr">"version"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"1.0.0"</span><span class="hljs-punctuation">,</span>
<span class="hljs-comment">// Plugin description</span>
<span class="hljs-attr">"description"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"..."</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"icons"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"16"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"img/icon16.png"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"48"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"img/icon48.png"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"128"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"img/icon128.png"</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-comment">// Persistent background JS or background page</span>
<span class="hljs-attr">"background"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"scripts"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">"js/background.js"</span><span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-comment">// Browser icon settings :browser_action, page_action, app</span>
<span class="hljs-attr">"browser_action"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"default_icon"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"img/icon.png"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"default_title"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"..."</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"default_popup"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"popup.html"</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-comment">// Icon displayed only when specific pages are open</span>
<span class="hljs-attr">"page_action"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"default_icon"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"img/icon.png"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"default_title"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"..."</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"default_popup"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"popup.html"</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-comment">// JS directly injected into pages</span>
<span class="hljs-attr">"content_scripts"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span>
<span class="hljs-attr">"matches"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">"&lt;all_urls&gt;"</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"js"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">"js/content-script.js"</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"css"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">"css/custom.css"</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-comment">// Code injection timing, default is document_idle</span>
<span class="hljs-attr">"run_at"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"document_start"</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-comment">// Permissions requested</span>
<span class="hljs-attr">"permissions"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-string">"contextMenus"</span><span class="hljs-punctuation">,</span> <span class="hljs-comment">// Right-click menu</span>
<span class="hljs-string">"tabs"</span><span class="hljs-punctuation">,</span> <span class="hljs-comment">// Tabs</span>
<span class="hljs-string">"notifications"</span><span class="hljs-punctuation">,</span> <span class="hljs-comment">// Notifications</span>
<span class="hljs-string">"webRequest"</span><span class="hljs-punctuation">,</span> <span class="hljs-comment">// Web requests</span>
<span class="hljs-string">"webRequestBlocking"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"storage"</span><span class="hljs-punctuation">,</span> <span class="hljs-comment">// Plugin local storage</span>
<span class="hljs-string">"https://*/*"</span> <span class="hljs-comment">// Websites accessible via executeScript or insertCSS</span>
<span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-comment">// List of plugin resources directly accessible by normal pages "web_accessible_resources": ["js/inject.js"],</span>
<span class="hljs-attr">"homepage_url"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"..."</span><span class="hljs-punctuation">,</span> <span class="hljs-comment">// Plugin homepage</span>
<span class="hljs-attr">"chrome_url_overrides"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-comment">// Override browser default pages</span>
<span class="hljs-attr">"newtab"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"newtab.html"</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"options_ui"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-comment">// Plugin options page</span>
<span class="hljs-attr">"page"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"options.html"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"chrome_style"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"omnibox"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"keyword"</span> <span class="hljs-punctuation">:</span> <span class="hljs-string">"..."</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span> <span class="hljs-comment">// Register a keyword in the address bar for search suggestions, only one keyword can be set</span>
<span class="hljs-attr">"default_locale"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"en"</span><span class="hljs-punctuation">,</span> <span class="hljs-comment">// Default language</span>
<span class="hljs-attr">"devtools_page"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"devtools.html"</span><span class="hljs-punctuation">,</span> <span class="hljs-comment">// Devtools page entry, can only point to an HTML file "content_security_policy": "...", // Security policy</span>
<span class="hljs-attr">"web_accessible_resources"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span> <span class="hljs-comment">// Loadable resources</span>
<span class="hljs-string">"RESOURCE_PATHS"</span>
<span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span></code>

An example of Manifest V3 is as follows:

<button class="hljs-copy p-1 bg-gray-300 dark:bg-black">Copy</button><merlin-component id="merlin-code-summarizer" class="merlin-code-summarizer"></merlin-component><code class="overflow-x-auto mt-1 language-json bg-gray-100 dark:bg-gray-900 hljs"><span class="hljs-punctuation">{</span>
<span class="hljs-attr">"manifest_version"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">3</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"name"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"..."</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"version"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"1.0.0"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"description"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"..."</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"icons"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"16"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"img/icon16.png"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"48"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"img/icon48.png"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"128"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"img/icon128.png"</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"background"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"service_worker"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"js/background.js"</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"action"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"default_icon"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"img/icon.png"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"default_title"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"..."</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"default_popup"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"popup.html"</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"content_security_policy"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"extension_pages"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"..."</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"sandbox"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"..."</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"web_accessible_resources"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-punctuation">{</span>
<span class="hljs-attr">"resources"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">"RESOURCE_PATHS"</span><span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"permissions"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-string">"contextMenus"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"tabs"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"notifications"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"webRequest"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"webRequestBlocking"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"storage"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"https://*/*"</span>
<span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"web_accessible_resources"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">"js/inject.js"</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"homepage_url"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"..."</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"chrome_url_overrides"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"newtab"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"newtab.html"</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"options_ui"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"page"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"options.html"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"chrome_style"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"omnibox"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"keyword"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"..."</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"default_locale"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"zh_CN"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"devtools_page"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"devtools.html"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"content_security_policy"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"..."</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"web_accessible_resources"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">"RESOURCE_PATHS"</span><span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span></code>

4.3.2 Content Script

Content scripts in Chrome extensions inject JS and CSS into specified pages through configuration. They share the DOM with the original page but not JavaScript. Accessing page JS variables requires injecting JS. Content scripts cannot access most Chrome APIs, except for:

  • chrome. extension
  • chrome.i18n
  • chrome. runtime
  • chrome.storage

For other APIs, communication needs to be done with the background or service worker.

4.3.3 Background Script

The background scripts in Chrome extensions have the longest lifespan and run continuously when the browser is open. They have extensive permissions, allowing access to most Chrome extension APIs and cross-origin requests without CORS restrictions. In Manifest V3, background pages are replaced by service workers with shorter lifespans and event-based execution, making them unsuitable for storing global variables.

4.3.4 Pop-up window

A pop-up window is a small window on a webpage that appears when clicking on an icon in the top right corner. It quickly closes when the user interacts outside of the webpage. Typically used for temporary interactions, its permission level is similar to the background but with a shorter lifespan.

4.3.5 Inject Script

Developers coined the term "injection script" during Chrome extension development. It refers to JavaScript injected into a page through DOM manipulation. Although content scripts can manipulate the DOM, they cannot be directly accessed due to access restrictions. This limitation is particularly evident in event binding. To meet the common requirement of adding a button to trigger the plugin on a web page, developers have adopted script insertion.

4.4 Communication Mechanism of Chrome Extensions

In Chrome extensions, communication relies on five types of scripts:

  1. Injection script, representing a script dynamically injected into the webpage, usually relying on window.postMessage.
  2. Content script, a script executed in a specific webpage context, utilizing window.postMessage, chrome.runtime.sendMessage and chrome.runtime.connect for inter-script communication.
  3. Popup script, associated with the plugin's pop-up interface, typically using chrome.tabs.sendMessage and chrome.tabs.connect for communication.
  4. Background script, a standalone script running in the background involving various methods such as "chrome.tabs.sendMessage", chrome.tabs.connect, chrome.extension.getBackgroundPage and chrome.extension.getViews.
  5. DevTools, additional functionalities of development tools that interact using specific APIs like chrome.devtools.inspectedWindow.eval and chrome.runtime.sendMessage.

Each script has different permissions emphasizing the importance of their communication. This interaction is crucial for enabling extensive plugin functionality.

Written at end

Reviewing the past to learn new things, browser architecture, as the cornerstone of the modern Internet, has gone through multiple iterations and innovations, always serving as a bridge between users and web content. Looking back at its development history, from the early days of single rendering engines to today's multi-process, multi-threaded architecture, each change has brought about a smoother and more secure browsing experience. Looking ahead, browser architecture will continue to deepen its performance optimization and security enhancement to bring users an even better web browsing experience.