瀏覽器多進程架構

咱們能夠簡單的認爲 JavaScript 這門語言目前有兩個主要的 runtime,一個是 Node.js,另外一個就是瀏覽器環境。咱們日常所謂的 JavaScript 是單線程的,實際上指的是 JavaScript 運行在 Render process 的 Main thread,什麼是 Render process,看完你就明白了。web

背景知識 - 進程與線程

先來扯一些背景知識,什麼是進程,什麼是線程(JavaScript 其實還有個協程的概念,不扯),這個對咱們後面的講解很重要。面試

chrome-process-thread.jpg

  • A process can be described as an application’s executing program.
  • A thread is the one that lives inside of process and executes any part of its process's program.
  • 多個線程之間共享內存,多個進程之間不共享內存,須要經過 IPC 傳遞信息

chrome-ipc.jpg

🌰 單線程與多線程

好比下面的代碼,理論上來講經過多線程處理要比單線程要快,緣由是由於多線程容許並行處理chrome

const a = 1 + 2;
const b = 20 / 5;
const c = 7 * 8;
console.log(a, b, c);
複製代碼

chrome-single-multi-thread.jpg

下圖展現同一個進程的內存是如何共享的瀏覽器

chrome-multi-thread.jpg

本文重點 - 多進程瀏覽器架構

不扯之前的舊的瀏覽器架構,Chrome 瀏覽器的架構以下圖所示(不必定最新)。須要注意的是,像 UI process, Network process 等等這些進程都有可能會被「降級」爲 Browser process 的線程(UI thread, Network thread)安全

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.網絡

chrome-architecture.jpg

因此當你僅僅打開一個 tab 頁的時候的進程信息多是這樣的多線程

chrome-task-manager.jpg

進程介紹

插件進程(Plugin process)

就是插件運行的進程,每一個插件一個進程,單獨隔離出是爲了防止插件掛了影響用戶架構

chrome-process-plugin.jpg

GPU 進程(GPU process)

主要負責 UI 渲染app

Handles GPU tasks in isolation from other processes. It is separated into different process because GPUs handles requests from multiple apps and draw them in the same surface.dom

網絡進程(Network process)

負責網絡資源加載

瀏覽器主進程(Browser process)

負責界面展現,用戶交互,子進程管理,文件存取等

渲染進程 (Renderer process)

Controls anything inside of the tab where a website is displayed.

主要負責將 HTML, CSS, JavaScript 轉換爲用戶可交互的網頁,排版引擎 Blink 和 JavaScript 引擎 V8 就運行在渲染進程,默認每一個 tab 一個渲染進程(特殊狀況下面的進程模式會講)

chrome-render-process.jpg

Chromium 四種進程模式 (Chromium Process Models)

Ref: www.chromium.org/developers/…

Chromium 提供了四種進程模式,不一樣的進程模式會對 tab 進程作不一樣的處理,好比採用某個模式況會給 tab 分配新進程,而採用另一個模式則不會,下面是四種模式的介紹,Chrome 默認採用第一個模式

  • Process-per-site-instance (default)
    • 同一個 site-instance 使用一個進程
  • Process-per-site
    • 同一個 site 使用一個進程
  • Process-per-tab
    • 每一個 tab 使用一個進程
  • Single process
    • 全部 tab 共用一個進程

這裏須要給出 site 和 site-instance 的定義

  • site 指的是相同的 registered domain name (e.g., google.com or bbc.co.uk) 和 scheme (e.g., https://) 。好比 z.baidu.comb.baidu.com 就能夠理解爲同一個 site(注意這裏要和 Same-origin policy 區分開來,同源策略還涉及到子域名和端口)
  • site-instance 指的是一組 connected pages from the same site,這裏 connected 的定義是 can obtain references to each other in script code 怎麼理解這段話呢。知足下面兩中狀況而且打開的新頁面和舊頁面屬於上面定義的同一個 site,就屬於同一個 site-instance
    1. 用戶經過 <a target="_blank"> 這種方式點擊打開的新頁面
    2. JavaScript code 打開的新頁面(好比 window.open)

理解了這兩個關鍵字就能夠仔細說下上面的四種進程模式

Single processProcess-per-tab 就不用說了,意如其名。 若是使用 Process-per-site 模式,當你打開了一個 tab 訪問 a.baidu.com,而後再打開一個 tab 訪問 b.baidu.com,這兩個 tab 其實用的是同一個進程,由於這兩個 tab 被分在同一個 group。這就意味着,你在其中一個 tab 寫一個死循環,這兩個 tab 都會 hang

Process-per-site-instance 是最重要的,由於這個是 Chrome 默認使用的模式,也就是幾乎全部的用戶都在用的模式。當你打開一個 tab 訪問 a.baidu.com,而後再打開一個 tab 訪問 b.baidu.com,這兩個 tab 會使用兩個進程。若是 b.baidu.com 是經過 a.baidu.com 頁面的 JavaScript 代碼打開的,這兩個 tab 會使用同一個進程,好比下圖的例子,能夠看到兩個 tab 的 processId 是相同的

chrome-same-process-id.jpg

爲何使用 Process-per-site-instance 這種進程模式

由於這種模型兼顧了性能與易用性,是一個比較中庸通用的模式

  • 相較於 Process-per-tab,可以少開不少進程,就意味着更少的內存佔用
  • 相較於 Process-per-site,可以更好的隔離相同域名下毫無關聯的 tab,更加安全

同時這麼作也知足了 different subdomains or ports of a site to access each other via Javascript 這種需求。

咱們一開始的時候說過,同一個進程的多個線程是共享內存的。因此當兩個 tab 使用同一個進程的時候,這兩個 tab 就是「通的」。好比 A 頁面使用 JavaScript 打開 B 頁面,那麼 B 頁面能夠經過 window.opener 訪問 A 頁面的 window 對象。

多進程如何協做完成任務

🌰 - 從輸入 URL 到頁面展現

這個問題大概是面試出現機率最高的題目之一了,這整個流程其實有個名字叫 Navigation,咱們從進程線程的角度來梳理一下。

UI 和網絡

首先,在輸入框輸入 www.mysite.com 而後輸入 Enter 這些都是由瀏覽器進程的 UI thread 來負責處理的,其中還有個額外的處理就是判斷輸入是一個 URL 仍是個 Query,不管是哪一個都要經過 IPC 通知網絡進程發送請求,只不過請求的目標不同(輸入的 URL / 搜索引擎)。

chrome-check-url-query.jpg

通知網絡進程後,UI thread 展現 Spinner,Network process 會負責後續網絡相關的處理好比 DNS lookup 和 establishing TLS Connection。Network process 有可能會收到 redirect response 好比 HTTP 301,這種狀況 Network 會通知 UI thread 對輸入框的 URL 作修改。

chrome-loading-spinner.jpg

解析返回數據

網絡進程會根據 Content-Type(HTTP Header) 和文件的 MIME type 來對不一樣的返回作不一樣的處理。好比,若是是 HTML 會交給 Renderer process, 若是是 zip 會交給 Download manager。

同時這裏會作一些安全檢查,好比 SafeBrowsingCross Origin Read Blocking (CORB)

chrome-safe-browsing.jpg

提交導航

Network process 完成解析文件類型和安全檢查後,會通知 Browser process,而後 browser process 經過 IPC 通知指定的渲染進程提交導航(commit the navigation),同時將網絡進程的 data stream 傳給渲染進程 so the renderer process can keep receiving HTML data。渲染進程在開始接收 HTML 後,會返回確認信息(confirm message),而後瀏覽器進程這邊就會對 UI 作一些修改,好比 HTTPS 的小鎖頭,前進後退按鈕等等

chrome-commit-navigation.jpg

渲染進程內部

就像上面說的,Renderer process 收到 commit navigation 的信息後會返回 confirm message 給瀏覽器主進程,同時接收 HTML 並渲染的過程就開始了,具體細節不講太複雜,咱們只關心進程間通信。渲染進程結束後而且全部 onload 事件觸發後,會發送 IPC 給瀏覽器進程,而後 tab 頁的 spinner 會中止,頁面加載完成。

chrome-page-loaded.jpg

Ref

相關文章
相關標籤/搜索