[譯] 現代瀏覽器內部揭祕(第一部分)

CPU、GPU、內存和多進程體系結構

這一博客系列由四部分組成,將從高級體系結構到渲染流程的細節來窺探 Chrome 瀏覽器的內部。若是你曾對瀏覽器是如何將代碼轉化爲具備功能的網站,或者你並不肯定爲什麼建議使用某一技術來提高性能,那麼本系列就是爲你準備的。前端

本文做爲此係列的第一部分,將介紹核心計算術語與 Chrome 的多進程體系架構。android

提示: 若是你已熟悉 CPU/GPU,進程/線程的相關概念,能夠直接跳到瀏覽器架構部分開始閱讀。ios

計算機的核心是 CPU 與 GPU

爲了瞭解瀏覽器運行的環境,咱們須要瞭解幾個計算機部件以及它們的做用。git

CPU

CPU

圖 1:4 個 CPU 核心做爲辦公人員,坐在辦公桌前處理各自的工做github

第一個須要瞭解的計算機部件是 中央處理器(Central Processing Unit),或簡稱爲 CPU。CPU 能夠看做是計算機的大腦。一個 CPU 核心如圖中的辦公人員,能夠逐一解決不少不一樣任務。它能夠在解決從數學到藝術一切任務的同時還知道如何響應客戶要求。過去 CPU 大可能是單芯片的,一個核心就像存在於同芯片的另外一個 CPU。隨着現代硬件發展,你常常會有不止一個內核,爲你的手機和筆記本電腦提供更多的計算能力。web

GPU

GPU

圖 2:許多帶特定扳手的 GPU 內核意味着它們只能處理有限任務後端

圖形處理器Graphics Processing Unit,簡稱爲 GPU)是計算機的另外一部件。與 CPU 不一樣,GPU 擅長同時處理跨內核的簡單任務。顧名思義,它最初是爲解決圖形而開發的。這就是爲何在圖形環境中「使用 GPU」 或 「GPU 支持」都與快速渲染和順滑交互有關。近年來隨着 GPU 加速計算的普及,僅靠 GPU 一己之力也使得愈來愈多的計算成爲可能。瀏覽器

當你在電腦或手機上啓動應用時,是 CPU 和 GPU 爲應用供能。一般狀況下應用是經過操做系統提供的機制在 CPU 和 GPU 上運行。安全

硬件,操做系統,應用

圖 3:三層計算機體系結構。底部是機器硬件,中間是操做系統,頂部是應用程序。網絡

在進程和線程上執行程序

進程與線程

圖四:進程做爲邊界框,線程做爲抽象魚在進程中游動

在深刻學習瀏覽器架構以前須要瞭解的另外一個理論是進程與線程。進程能夠被描述爲是一個應用的執行程序。線程存在於進程並執行程序任意部分。

啓動應用時會建立一個進程。程序也許會建立一個或多個線程來幫助它工做,這是可選的。操做系統爲進程提供了一個可使用的「一塊」內存,全部應用程序狀態都保存在該私有內存空間中。關閉應用程序時,相應的進程也會消失,操做系統會釋放內存。

進程與內存

圖 5 :進程使用內存空間和存儲應用數據的示意圖

進程能夠請求操做系統啓動另外一個進程來執行不一樣的任務。此時,內存中的不一樣部分會分給新進程。若是兩個進程須要對話,他們能夠經過進程間通訊IPC)來進行。許多應用都是這樣設計的,因此若是一個工做進程失去響應,該進程就能夠在不中止應用程序不一樣部分的其餘進程運行的狀況下從新啓動。

工做進程與 IPC

圖 6:獨立進程經過 IPC 通訊示意圖

瀏覽器架構

那麼如何經過進程和線程構建 web 瀏覽器呢?它可能由一個擁有不少線程的進程,或是一些經過 IPC 通訊的不一樣線程的進程。

瀏覽器架構

圖 7:不一樣瀏覽器架構的進程/線程示意圖

這裏須要注意的重要一點是,這些不一樣的架構是實現細節。關於如何構建 web 瀏覽器並不存在標準規範。一個瀏覽器的構建方法可能與另外一個迥然不一樣。

在本博客系列中,咱們使用下圖所示的 Chrome 近期架構進行闡述。

頂部是瀏覽器線程,它與處理應用其它模塊任務的進程進行協調。對於渲染進程來講,建立了多個渲染進程並分配給了每一個標籤頁。直到最近,Chrome 在可能的狀況下給每一個標籤頁分配一個進程。而如今它試圖給每一個站點分配一個進程,包括 iframe(參見站點隔離)。

瀏覽器架構

圖 8:Chrome 的多進程架構示意圖。渲染進程下顯示了多個層,代表 Chrome 爲每一個標籤頁運行多個渲染進程。

進程各自控制什麼?

下表展現每一個 Chrome 進程與各自控制的內容:

進程 控制
瀏覽器 控制應用中的 「Chrome」 部分,包括地址欄,書籤,回退與前進按鈕。以及處理 web 瀏覽器不可見的特權部分,如網絡請求與文件訪問。
渲染 控制標籤頁內網站展現。
插件 控制站點使用的任意插件,如 Flash。
GPU 處理獨立於其它進程的 GPU 任務。GPU 被分紅不一樣進程,由於 GPU 處理來自多個不一樣應用的請求並繪製在相同表面。

Chrome 進程

圖 9:不一樣進程指向瀏覽器 UI 的不一樣部分

還有更多進程如擴展進程與應用進程。若是你想要了解有多少進程運行在你的 Chrome 瀏覽器中,能夠點擊右上角的選項菜單圖標,選擇更多工具,而後選擇任務管理器。而後會打開一個窗口,其中列出了當前正在運行的進程以及它們當前的 CPU/內存使用量。

Chrome 多進程架構的優勢

前文中提到了 Chrome 使用多個渲染進程。最簡單的狀況下,你能夠想象每一個標籤頁都有本身的渲染進程。假設你打開了三個標籤頁,每一個標籤頁都擁有本身獨立的渲染進程。若是某個標籤頁失去響應,你能夠關掉這個標籤頁,此時其它標籤頁依然運行着,能夠正常使用。若是全部標籤頁都運行在同一進程上,那麼當某個失去響應,全部標籤頁都會失去響應。這樣的體驗很糟糕。

多個標籤頁各自的渲染進程

圖 10:如圖所示每一個標籤頁上運行的渲染進程

把瀏覽器工做分紅多個進程的另外一好處是安全性與沙箱化。因爲操做系統提供了限制進程權限的方法,瀏覽器就能夠用沙箱保護某些特定功能的進程。例如,Chrome 瀏覽器限制處理任意用戶輸入的進程(如渲染器進程)對任意文件的訪問。

因爲進程有本身的私有內存空間,因此它們一般包含公共基礎設施的拷貝(如 V8,它是 Chrome 的 JavaScript 引擎)。這意味着使用了更多的內存,若是它們是同一進程中的線程,就沒法共享這些拷貝。爲了節省內存,Chrome 對可加速的內存數量進行了限制。具體限制數值依設備可提供的內存與 CPU 能力而定,可是當 Chrome 運行時達到限制時,會開始在同一站點的不一樣標籤頁上運行同一進程。

節省更多內存 —— Chrome 中的服務化

一樣的方法也適用於瀏覽器進程。Chrome 正在經歷架構變革,它轉變爲將瀏覽器程序的每一模塊做爲一個服務來運行,從而能夠輕鬆實現進程的拆解或聚合。

一般觀點是當 Chrome 運行在強力硬件上時,它會將每一個服務分解到不一樣進程中,從而提高穩定性,可是若是 Chrome 運行在資源有限的設備上時,它會將服務聚合到一個進程中從而節省了內存佔用。在這一架構變革實現前,相似的整合進程以減小內存使用的方法已經在 Android 類平臺上使用。

Chrome 服務化

圖 11: Chrome 的服務化圖,將不一樣的服務移動到多個進程和單個瀏覽器進程中

每一個 iframe 的渲染進程 —— 站點隔離

站點隔離 是近期引入到 Chrome 中的一個功能,它爲每一個 iframe 運行一個單獨的渲染進程。咱們已經討論了許久每一個標籤頁的渲染進程,它容許跨站點 iframe 運行在一個單獨的渲染進程,在不一樣站點中共享內存。運行 a.comb.com 在同一渲染進程中看起來還 ok。

同源策略 是 web 的核心安全模型。同源策略確保站點在未獲得其它站點許可的狀況下不能獲取其數據。安全攻擊的一個主要目標就是繞過同源策略。進程隔離是分離站點的最高效的手段。隨着 Meltdown and Spectre 的出現,使用進程來分離站點愈發勢在必行。Chrome 67 版本後,桌面版 Chrome 都默認開啓了站點隔離,每一個標籤頁的 iframe 都有一個單獨的渲染進程。

站點隔離

圖 12:站點隔離示意圖,多個渲染進程指向站點內的 iframe

啓用站點隔離是多年來工程人員努力的結果。站點隔離並不僅是分配不一樣的渲染進程這麼簡單。它從根本上改變了 iframe 的通訊方式。在一個頁面上打開開發者工具,讓 iframe 在不一樣的進程上運行,這意味着開發者工具必須在幕後工做,以使它看起來無縫。即便運行一個簡單的 Ctrl + F 來查找頁面中的一個單詞,也意味着在不一樣的渲染器進程中進行搜索。你能夠看到爲何瀏覽器工程師把發佈站點隔離功能做爲一個重要里程碑!

總結

本文從高級視角對瀏覽器架構與多進程架構的優勢進行闡述。咱們也對 Chrome 中與多進程架構密切相關的服務化與站點隔離進行了講解。下一篇文章中,咱們將開始深刻了解進程與線程中到底發生了什麼才能使網站得以呈現。

你喜歡這篇文章嗎?對後續文章有任何疑問或建議均可以在評論區或 Twitter 上 @kosamari 與我聯繫。

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索