本文是筆者對Mario Kosaka寫的inside look at modern web browser系列文章的翻譯。這裏的翻譯不是指直譯,而是結合我的的理解將做者想表達的意思表達出來,並且會盡可能補充一些相關的內容來幫助你們更好地理解。git
在這個4集系列教程裏面,我將會從Chrome瀏覽器的高層次架構(high-level architecture)開始提及,一直深刻講到頁面渲染流水線(rendering pipeline)的具體細節。若是你想知道瀏覽器是怎麼把你編寫的代碼轉變成一個可用的網站,或者你不知道爲何一些特定的代碼寫法能夠提升網站的性能的,那你就來對地方了,這篇文章就是爲你準備的。github
做爲本系列文章的第一篇,咱們會先了解一些關鍵的計算機術語以及Chrome瀏覽器的多進程架構。web
要想理解瀏覽器的運行環境,咱們先要搞明白一些計算機組件以及它們的做用。瀏覽器
首先咱們要說的是計算機的大腦 - CPU(Central Processing Unit)。CPU是計算機裏面的一塊芯片,上面有一個或者多個核心(core)。咱們能夠把CPU的一個核心(core)比喻成一個辦公室工人,他功能強大,上知天文下知地理,琴棋書畫無所不能,它能夠串行地一件接着一件處理交給它的任務。好久以前的時候大多數CPU只有一個核心,不過在如今的硬件設備上CPU一般會有多個核心,由於多核心CPU能夠大大提升手機和電腦的運算能力。 安全
四個CPU核心愉快地在各自工位上一個接着一個地處理交給它們的任務網絡
圖形處理器 - 或者說GPU(Graphics Processing Unit)是計算機的另一個重要組成部分。和功能強大的CPU核心不同的是,單個GPU核心只能處理一些簡單的任務,不過它勝在數量多,單片GPU上會有不少不少的核心能夠同時工做,也就是說它的並行計算能力是很是強的。圖形處理器(GPU)顧名思義一開始就是專門用來處理圖形的,因此在說到圖形使用GPU(using)或者GPU支持(backed)時,人們就會聯想到圖形快速渲染或者流暢的用戶體驗相關的概念。最近幾年來,隨着GPU加速概念的流行,在GPU上單獨進行的計算也變得愈來愈多了。 架構
每一個GPU核心手裏只有一個扳手,這就說明它的能力是很是有限的,但是它們人多啊!ide
當你在手機或者電腦上打開某個應用程序的時候,背後實際上是CPU和GPU支撐着這個應用程序的運行。一般來講,你的應用要經過操做系統提供的一些機制才能跑在CPU和GPU上面。 工具
計算機的三層架構,最下層是硬件機器,操做系統夾在中間,最上層是運行的應用post
在深刻到瀏覽器的架構以前咱們還得了解一下進程(process)和線程(thread)的相關概念。進程能夠當作正在被執行的應用程序(executing program)。而線程是跑在進程裏面的,一個進程裏面可能有一個或者多個線程,這些線程能夠執行任何一部分應用程序的代碼。
進程就像一個大魚缸,而線程就是浴缸裏面暢遊的魚兒
當你啓動一個應用程序的時候,操做系統會爲這個程序建立一個進程同時還爲這個進程分配一片私有的內存空間,這片空間會被用來存儲全部程序相關的數據和狀態。當你關閉這個程序的時候,這個程序對應的進程也會隨之消失,進程對應的內存空間也會被操做系統釋放掉。
進程使用系統分配的內存空間去存儲應用的數據
有時候爲了知足功能的須要,建立的進程會叫系統建立另一些進程去處理其它任務,不過新建的進程會擁有全新的獨立的內存空間而不是和原來的進程共用內存空間。若是這些進程須要通訊,它們要經過IPC機制(Inter Process Communication)來進行。不少應用程序都會採起這種多進程的方式來工做,由於進程和進程之間是互相獨立的它們互不影響,換句話來講,若是其中一個工做進程(worker process)掛掉了其餘進程不會受到影響,並且掛掉的進程還能夠重啓。
不一樣的進程經過IPC來通訊
那麼瀏覽器是怎麼使用進程和線程來工做的呢?其實大概能夠分爲兩種架構,一種是單進程架構,也就是隻啓動一個進程,這個進程裏面有多個線程工做。第二種是多進程架構,瀏覽器會啓動多個進程,每一個進程裏面有多個線程,不一樣進程經過IPC進行通訊。
單進程和多進程瀏覽器的架構圖
上面的圖表架構其實包含了瀏覽器架構的具體實現了,在現實中其實並無一個你們都遵循的瀏覽器實現標準,因此不一樣瀏覽器的實現方式可能會徹底不同。
爲了更好地在本系列文章中展開論述,咱們主要討論最新的Chrome瀏覽器架構,它採用的是多進程架構,如下是架構圖:
Chrome的多進程架構圖,多個渲染進程的卡片(render process)是用來代表Chrome會爲每個tab建立一個渲染進程。
Chrome瀏覽器會有一個瀏覽器進程(browser process),這個進程會和其餘進程一塊兒協做來實現瀏覽器的功能。對於渲染進程(renderer process),Chrome會盡量爲每個tab甚至是頁面裏面的每個iframe都分配一個單獨的進程。
如下是各個進程具體負責的工做內容:
進程 | 負責的工做 |
---|---|
Browser | 負責瀏覽器的「Chrome」部分, 包括導航欄,書籤, 前進和後退按鈕。同時這個進程還會控制那些咱們看不見的部分,包括網絡請求的發送以及文件的讀寫。 |
Renderer | 負責tab內和網頁展現相關的全部工做。 |
Plugin | 控制網頁使用的全部插件,例如flash插件。 |
GPU | 負責獨立於其它進程的GPU任務。它之因此被獨立爲一個進程是由於它要處理來自於不一樣tab的渲染請求並把它在同一個界面上畫出來。 |
不一樣的進程負責瀏覽器不一樣部分的界面內容
除了上面列出來的進程,Chrome還有不少其餘進程在工做,例如擴展進程(Extension Process)和工具進程(utility process)。若是你想看一下你的Chrome瀏覽器如今有多少個進程在跑能夠點擊瀏覽器右上角的更多按鈕,選擇更多工具和任務管理器:
那麼爲何Chrome會採起多進程架構工做呢?
其中一個好處是多進程可使瀏覽器具備很好的容錯性。對於大多數簡單的情景來講,Chrome會爲每一個tab單獨分配一個屬於它們的渲染進程(render process)。舉個例子,假如你有三個tab,你就會有三個獨立的渲染進程。當其中一個tab的崩潰時,你能夠隨時關閉這個tab而且其餘tab不受到影響。但是若是全部的tab都跑在同一個進程的話,它們就會有連帶關係,一個掛所有掛。
不一樣的tab會有不一樣的渲染進程來負責
Chrome採用多進程架構的另一個好處就是能夠提供安全性和沙盒性(sanboxing)。由於操做系統能夠提供方法讓你限制每一個進程擁有的能力,因此瀏覽器可讓某些進程不具有某些特定的功能。例如,因爲tab渲染進程可能會處理來自用戶的隨機輸入,因此Chrome限制了它們對系統文件隨機讀寫的能力。
不過多進程架構也有它很差的地方,那就是進程的內存消耗。因爲每一個進程都有各自獨立的內存空間,因此它們不能像存在於同一個進程的線程那樣共用內存空間,這就形成了一些基礎的架構(例如V8 JavaScript引擎)會在不一樣進程的內存空間同時存在的問題,這些重複的內容會消耗更多的內存。因此爲了節省內存,Chrome會限制被啓動的進程數目,當進程數達到必定的界限後,Chrome會將訪問同一個網站的tab都放在一個進程裏面跑。
一樣的優化方法也能夠被使用在瀏覽器進程(browser process)上面。Chrome瀏覽器的架構正在發生一些改變,目的是將和瀏覽器自己(Chrome)相關的部分拆分爲一個個不一樣的服務,服務化以後,這些功能既能夠放在不一樣的進程裏面運行也能夠合併爲一個單獨的進程運行。
這樣作的主要緣由是讓Chrome在不一樣性能的硬件上有不一樣的表現。當Chrome運行在一些性能比較好的硬件時,瀏覽器進程相關的服務會被放在不一樣的進程運行以提升系統的穩定性。相反若是硬件性能很差,這些服務就會被放在同一個進程裏面執行來減小內存的佔用。其實在此次架構變化以前,Chrome在Android上面已經開始採起相似的作法了。
Chrome將瀏覽器相關的服務放在同一個進程裏面運行和放在不一樣的進程運行的區別
網站隔離(Site Isolation)是最近Chrome瀏覽器啓動的功能,這個功能會爲網站內不一樣站點的iframe分配一個獨立的渲染進程。以前說過Chrome會爲每一個tab分配一個單獨的渲染進程,但是若是一個tab只有一個進程的話不一樣站點的iframe都會跑在這個進程裏面,這也意味着它們會共享內存,這就有可能會破壞同源策略。同源策略是瀏覽器最核心的安全模型,它能夠禁止網站在未經贊成的狀況下去獲取另一個站點的數據,所以繞過同源策略是不少安全攻擊的主要目的。而進程隔離(proces isolation)是隔離網站最好最有效的辦法了。再加上CPU存在Meltdown和Spectre的隱患,網站隔離變得勢在必行。所以在Chrome 67版本以後,桌面版的Chrome會默認開啓網站隔離功能,這樣每個跨站點的iframe都會擁有一個獨立的渲染進程。
網站隔離功能會讓跨站的iframe擁有獨立的進程
網站隔離技術匯聚了咱們工程師好幾年的研發努力,它其實遠遠沒有想象中那樣只是爲不一樣站點的iframe分配一個獨立的渲染進程那麼簡單,由於它從根本上改變了各個iframe之間的通訊方式。網站隔離後,對於有iframe的網站,當用戶打開右邊的devtool時,Chrome瀏覽器其實要作不少幕後工做才能讓開發者感受不出這和以前的有什麼區別,這實際上是很難實現的。對於一些很簡單的功能,例如在devtool裏面用Ctrl + F鍵在頁面搜索某個關鍵詞,Chrome都要遍歷多個渲染進程去完成。因此咱們的瀏覽器工程師在網站隔離這個功能發佈後都感嘆這是一個里程碑式的成就。
在本篇文章中,咱們探討了瀏覽器高層次的架構設計以及多進程架構的帶來的好處。同時咱們還討論了服務化和網站隔離這些和瀏覽器多進程架構息息相關的技術。在下一篇文章中咱們要開始深刻了解這些進程和線程是如何呈現咱們的網站頁面的了。
我是進擊的大蔥,關注我和我一塊兒進步成獨當一面的全棧工程師!
文章首發於:窺探現代瀏覽器架構(一)
關注個人我的公衆號獲取個人最新技術推送!