探一探現代瀏覽器的內部機制(一)

Gomi發表於2022-02-15
本文翻譯自Inside look at modern web browser (part 1)
原文作者:Mariko Kosaka
翻譯:Gomi

CPU,GPU,記憶體以及多程式架構

在這個系列中,我們將會從高層架構的角度深入到Chrome瀏覽器渲染流程的具體細節。如果你想知道瀏覽器是如何將你的程式碼變成一個可用的網站,亦或者你不清楚為何會建議你使用特定的技術來提高網站的效能,那麼本系列適合你。

作為本系列的第 1 部分,我們將瞭解核心計算術語和 Chrome 的多程式架構。

如果你熟悉CPU/GPU和程式/執行緒,你可以跳到瀏覽器架構

一、計算機的核心:CPU和GPU

為了瞭解瀏覽器的執行環境,我們需要了解一些計算機部件以及它們的作用。

CPU

首先是中央處理器(CPU)。CPU可以看作是計算機的大腦。一顆CPU核心,在此圖中被描繪成一個辦公室員工,當任務出現時,它能一個一個地處理許多不同的任務。它可以處理從數學到藝術的所有事情,同時知道如何回覆客戶的電話。在過去,大多數CPU都是單晶片的。核心就像另一個CPU生活在同一個晶片中。在現代硬體中,你通常會得到多個核心,從而為你的手機和膝上型電腦提供更強的計算能力。
image.png
圖1:4個CPU核心作為辦公室工作人員坐在每張辦公桌前處理進來的任務

GPU

圖形處理器(GPU)是計算機的另一部分。與CPU不同,GPU擅長處理簡單的任務,但可以同時跨多個核心。顧名思義,它最初是為處理圖形而開發的。這就是為什麼在圖形上下文(可能是指電腦的GPU選項)中“使用GPU”或“GPU支援”與快速渲染和流暢互動有關。近年來,隨著GPU加速影像處理技術的發展,越來越多的計算在GPU上成為了可能。
image.png
圖2:許多帶有扳手的GPU核心表明它們只能處理有限的任務

當你在計算機或手機上啟動應用程式時,CPU和GPU是驅動程式的核心。大部分情況下,應用程式會根據作業系統提供的機制執行在CPU和GPU上。
image.png
圖3:三層計算機架構。機器硬體在底層,作業系統在中間,應用程式在頂層

二、在程式和執行緒上執行程式

在深入研究瀏覽器架構之前要掌握的另一個概念是程式和執行緒。程式可以描述為應用程式的執行程式。執行緒是存在於程式內部並執行其程式程式的任何部分的執行緒。

當你啟動應用程式時,計算機會建立一個程式。該程式可能會建立執行緒來幫助它工作,但這是可選的。作業系統為程式提供了一塊可使用的記憶體“平板”,所有應用程式狀態都儲存在該私有記憶體空間中。當你關閉應用程式時,該程式也會消失,並且作業系統會釋放記憶體。
image.png

圖4:程式作為邊界框,執行緒作為抽象的魚在程式內遊動

image.png
圖5:使用記憶體空間和儲存應用程式資料的程式圖

一個程式可以要求作業系統啟動另一個程式來執行不同的任務。發生這種情況時,將為新程式分配記憶體的不同部分。如果兩個程式需要通訊,它們可以使用程式間通訊(IPC)來實現。許多應用程式被設計為以這種方式工作,因此,如果一個程式沒有響應,它不會影響其他執行在不同應用程式上的程式,然後重新啟動。
image.png
圖6:通過IPC進行通訊的獨立程式示意圖

三、瀏覽器架構

那麼如何使用程式和執行緒構建Web瀏覽器呢?好吧,它可能是一個具有許多不同執行緒的程式,也可能是許多不同的程式,其中有幾個執行緒通過IPC進行通訊。
image.png
圖7:程式/執行緒圖中的不同瀏覽器架構

這裡要著重注意的是,圖中這些不同的架構是實現細節,並沒有關於如何構建 Web 瀏覽器的標準規範,一種瀏覽器的構建可能與另一種完全不同。

接下來我們將使用下圖中描述的Chrome的最新架構。

頂部是瀏覽器程式與處理應用程式不同部分的其他程式協調。對於渲染器程式,會建立多個程式並將其分配給每個網頁。直到最近,Chrome還在可能的情況下為每個網頁提供了一個程式;現在Chrome嘗試為每個站點提供自己的程式,包括iframes([站點隔離]。(https://developers.google.com...))
image.png
圖8:Chrome的多程式架構圖。渲染器程式下顯示了多個圖層,以表示Chrome為每個選項卡執行多個渲染器程式

四、每個程式對應控制的部分

下表描述了每個Chrome程式及其控制的內容:

瀏覽器程式控制“chrome”應用程式部分,包括位址列、書籤、後退和前進按鈕。還處理瀏覽器中不可見的特權部分,例如網路請求和檔案訪問
渲染器程式控制顯示網頁內的任何顯示的內容
外掛(plugin)程式控制網站使用的任何外掛,例如Flash
GPU程式獨立於其他程式,處理GPU任務。它被分成不同的程式,因為GPU處理來自多個應用程式的請求並將它們繪製在同一個表面上。
瀏覽器外掛(Extension)程式控制瀏覽器外掛,比如油猴、Vue Devtools等
實用程式程式控制一些其他實用程式的程式,比如V8代理解析工具,音訊服務等

image.png
圖9:指向瀏覽器 UI 不同部分的不同程式

五、Chrome中多程式架構的好處

之前,我提到Chrome使用多個渲染器程式。在最簡單的情況下,你可以想象每個網頁都有自己的渲染器程式。假設你開啟了3個網頁,每個網頁都由一個獨立的渲染器程式執行。如果一個網頁變得無響應,那麼你可以關閉無響應的網頁並繼續下一步,同時保持其他網頁處於活動狀態。如果所有網頁都在一個程式上執行,則當一個網頁無響應時,所有網頁均無響應,這很悲劇。

image.png
圖10:顯示執行每個選項卡的多個程式的圖表

將瀏覽器的工作劃分成多個程式的另一個好處,是安全性和隔離性。由於作業系統提供了一種限制程式許可權的方法,因此瀏覽器可以從某些功能對某些程式進行沙箱化處理。例如,Chrome瀏覽器對那些處理使用者輸入的程式(如渲染器程式),限制了檔案的訪問許可權。

因為程式有自己的私有記憶體空間,它們通常包含通用基礎設施的副本(例如V8,它是Chrome的 JavaScript引擎)。這意味著更多的記憶體使用,因為它們不能像在同一程式中的執行緒那樣共享。為了節省記憶體,Chrome限制了它可以啟動的程式數。這種限制取決於你的裝置擁有多少記憶體和CPU處理能力,但是當Chrome達到極限時,它會開始在一個程式中執行來自同一站點的多個網頁頁籤。

六、節省更多的記憶體 - Chrome中的服務化

相同的方法適用於瀏覽器程式。 Chrome正在經歷架構更改,以將瀏覽器程式的每個部分作為服務執行,從而可以輕鬆拆分為不同的程式或聚合為一個。

一般的想法是,當Chrome在強大的硬體上執行時,它可能會將每個服務拆分為不同的程式以提供更高的穩定性,但如果它在資源受限的裝置上,Chrome會將服務整合到一個程式中以節省記憶體佔用。在此更改之前,已在Android等平臺上使用了類似的整合流程方法來減少記憶體的使用。

image.png
圖11:Chrome的服務化圖將不同的服務移動到多個程式和單個瀏覽器程式中

七、幀渲染器程式 - 站點隔離

站點隔離是Chrome中最近引入的一項功能,它為每個跨站點iframe執行單獨的渲染器程式。我們一直在討論每個網頁頁籤一個渲染器程式,它允許跨站點iframe在單個渲染器程式中執行,並在不同站點之間共享記憶體空間。在同一個渲染器程式中執行a.com和b.com似乎沒問題。同源策略是網路的核心安全模型;它確保一個站點在未經同意的情況下無法訪問其他站點的資料。繞過此策略是安全攻擊的主要目標。程式隔離是分隔站點的最有效方法。由於Meltdown和Spectre(安全漏洞)的出現,我們更加需要使用不同的程式來隔離站點。自Chrome 67起,預設情況下在桌面上啟用站點隔離,網頁中的每個跨站點iframe都會獲得一個單獨的渲染器程式。
image.png
圖12:站點隔離示意圖;指向站點內 iframe 的多個渲染器程式

啟用站點隔離是一項多年的工程工作。 站點隔離並不像分配不同的渲染器程式那麼簡單; 它從根本上改變了iframe相互通訊的方式。 從不同程式上執行iframe的頁面,開啟devtools,意味著 devtools必須執行後臺任務以使其看起來無縫整合。 即使執行一個簡單的Ctrl+F在頁面中查詢單詞,也意味著在不同的渲染器程式中進行搜尋。 這就是為什麼瀏覽器工程師會將“站點隔離”的釋出稱為重要里程碑的原因!

八、總結

在這篇文章中,我們從一個更高的視角介紹了瀏覽器架構,並介紹了多程式架構的好處。 我們還介紹了與多程式架構密切相關的Chrome中的服務化和站點隔離。 在下一篇文章中,我們將開始深入研究,為了成功展示一個網站,這些程式和執行緒之間發生了哪些事情。

相關文章