浏览器工作原理与实践学习笔记
瀏覽器工作原理與實(shí)踐
參考來(lái)源: 極客時(shí)間-李兵專欄
李兵簡(jiǎn)介: 08年,在 Chromium 和 IE 發(fā)布了一款雙核瀏覽器:太陽(yáng)花,國(guó)內(nèi)第一款雙核瀏覽器 ,支持chrome并兼容IE,日活達(dá)到了20多萬(wàn)。 李兵去了盛大創(chuàng)新院,參與研發(fā)WebOS項(xiàng)目, 基于WebKit內(nèi)核打造一個(gè)能和安卓并存的操作系統(tǒng)。在團(tuán)隊(duì)中負(fù)責(zé) HTML5 特性的實(shí)現(xiàn),比如實(shí)現(xiàn) Web Workers、Application Cache、LocalStorage、IndexedDB、CSS3 部分動(dòng)畫效果等。 后來(lái),他又到了順網(wǎng)科技,和團(tuán)隊(duì)打造了一款給 全國(guó)網(wǎng)吧使用的“F1瀏覽器”,日啟量達(dá)到2000萬(wàn)。 大家都知道,網(wǎng)吧的電腦環(huán)境異常復(fù)雜,頁(yè)面劫持經(jīng)常發(fā)生,再加上每天千萬(wàn)級(jí)別的啟動(dòng)量, 對(duì)頁(yè)面安全、加載速度和流暢度都有很高的要求。1. Chrome架構(gòu):僅僅打開了一個(gè)頁(yè)面,為什么有這么多進(jìn)程
從上圖可以看到,打開一個(gè)網(wǎng)頁(yè)需要這么多進(jìn)程(瀏覽器右上角-選項(xiàng)-更多工具-任務(wù)管理器),比如瀏覽器主進(jìn)程、GPU進(jìn)程、網(wǎng)絡(luò)進(jìn)程、渲染進(jìn)程,還有audio進(jìn)程和storage進(jìn)程。
下面了解一下瀏覽器進(jìn)程發(fā)展歷史:
1. 單進(jìn)程瀏覽器時(shí)代
2007年市面上的瀏覽器都是單進(jìn)程瀏覽器,單進(jìn)程瀏覽器是指瀏覽器的所有功能模塊都是運(yùn)行在同一個(gè)進(jìn)程里,這些模塊包含了網(wǎng)絡(luò)、插件、JavaScript 運(yùn)行環(huán)境、渲染引擎和頁(yè)面等。單進(jìn)程瀏覽器的架構(gòu)如下圖所示:
如此多的功能模塊運(yùn)行在一個(gè)進(jìn)程里,是導(dǎo)致單進(jìn)程瀏覽器不穩(wěn)定、不流暢和不安全的一個(gè)主要因素。具體分析如下:
(1)不穩(wěn)定
早期瀏覽器需要借助于插件來(lái)實(shí)現(xiàn)諸如 Web 視頻、Web 游戲等各種強(qiáng)大的功能,但是插件是最容易出問題的模塊,并且還運(yùn)行在瀏覽器進(jìn)程之中,所以一個(gè)插件的意外崩潰會(huì)引起整個(gè)瀏覽器的崩潰。
除了插件之外,渲染引擎模塊也是不穩(wěn)定的,通常一些復(fù)雜的 JavaScript 代碼就有可能引起渲染引擎模塊的崩潰。和插件一樣,渲染引擎的崩潰也會(huì)導(dǎo)致整個(gè)瀏覽器的崩潰。
(2)不流暢
所有頁(yè)面的渲染模塊、JavaScript 執(zhí)行環(huán)境以及插件都是運(yùn)行在同一個(gè)線程中的,這就意味著同一時(shí)刻只能有一個(gè)模塊可以執(zhí)行。
比如,下面這個(gè)無(wú)限循環(huán)的腳本:
function freeze() {while (1) {console.log("freeze");} } freeze();當(dāng)其執(zhí)行時(shí),它會(huì)獨(dú)占整個(gè)線程,這樣導(dǎo)致其他運(yùn)行在該線程中的模塊就沒有機(jī)會(huì)被執(zhí)行。因?yàn)闉g覽器中所有的頁(yè)面都運(yùn)行在該線程中,所以這些頁(yè)面都沒有機(jī)會(huì)去執(zhí)行任務(wù),這樣就會(huì)導(dǎo)致整個(gè)瀏覽器失去響應(yīng),變卡頓。
除了上述腳本或者插件會(huì)讓單進(jìn)程瀏覽器變卡頓外,頁(yè)面的內(nèi)存泄漏也是單進(jìn)程變慢的一個(gè)重要原因。通常瀏覽器的內(nèi)核都是非常復(fù)雜的,運(yùn)行一個(gè)復(fù)雜點(diǎn)的頁(yè)面再關(guān)閉頁(yè)面,會(huì)存在內(nèi)存不能完全回收的情況,這樣導(dǎo)致的問題是使用時(shí)間越長(zhǎng),內(nèi)存占用越高,瀏覽器會(huì)變得越慢。
(3) 不安全
插件可以使用 C/C++ 等代碼編寫,通過插件可以獲取到操作系統(tǒng)的任意資源,當(dāng)你在頁(yè)面運(yùn)行一個(gè)插件時(shí)也就意味著這個(gè)插件能完全操作你的電腦。如果是個(gè)惡意插件,那么它就可以釋放病毒、竊取你的賬號(hào)密碼,引發(fā)安全性問題。
至于頁(yè)面腳本,它可以通過瀏覽器的漏洞來(lái)獲取系統(tǒng)權(quán)限,這些腳本獲取系統(tǒng)權(quán)限之后也可以對(duì)你的電腦做一些惡意的事情,同樣也會(huì)引發(fā)安全問題。
2. 多進(jìn)程瀏覽器時(shí)代
早期多進(jìn)程瀏覽器
下圖是2008年chrome架構(gòu)
從圖中可以看出,Chrome 的頁(yè)面是運(yùn)行在單獨(dú)的渲染進(jìn)程中的,同時(shí)頁(yè)面里的插件也是運(yùn)行在單獨(dú)的插件進(jìn)程之中,而進(jìn)程之間是通過 IPC 機(jī)制進(jìn)行通信。解決了單進(jìn)程瀏覽器出現(xiàn)的一些問題:
(1)解決不穩(wěn)定問題
由于進(jìn)程是相互隔離的,所以當(dāng)一個(gè)頁(yè)面或者插件崩潰時(shí),影響到的僅僅是當(dāng)前的頁(yè)面進(jìn)程或者插件進(jìn)程,并不會(huì)影響到瀏覽器和其他頁(yè)面,這就完美地解決了頁(yè)面或者插件的崩潰會(huì)導(dǎo)致整個(gè)瀏覽器崩潰,也就是不穩(wěn)定的問題。
(2)解決不流暢問題
JavaScript 也是運(yùn)行在渲染進(jìn)程中的,所以即使 JavaScript 阻塞了渲染進(jìn)程,影響到的也只是當(dāng)前的渲染頁(yè)面,而并不會(huì)影響瀏覽器和其他頁(yè)面,因?yàn)槠渌?yè)面的腳本是運(yùn)行在它們自己的渲染進(jìn)程中的。所以當(dāng)我們?cè)僭?Chrome 中運(yùn)行上面那個(gè)死循環(huán)的腳本時(shí),沒有響應(yīng)的僅僅是當(dāng)前的頁(yè)面。對(duì)于內(nèi)存泄漏,當(dāng)關(guān)閉一個(gè)頁(yè)面時(shí),整個(gè)渲染進(jìn)程也會(huì)被關(guān)閉,之后該進(jìn)程所占用的內(nèi)存都會(huì)被系統(tǒng)回收,這樣就解決了瀏覽器頁(yè)面的內(nèi)存泄漏問題。
(3)解決不安全問題
采用多進(jìn)程架構(gòu)的額外好處是可以使用安全沙箱,你可以把沙箱看成是操作系統(tǒng)給進(jìn)程上了一把鎖,沙箱里面的程序可以運(yùn)行,但是不能在你的硬盤上寫入任何數(shù)據(jù),也不能在敏感位置讀取任何數(shù)據(jù),例如你的文檔和桌面。Chrome 把插件進(jìn)程和渲染進(jìn)程鎖在沙箱里面,這樣即使在渲染進(jìn)程或者插件進(jìn)程里面執(zhí)行了惡意程序,惡意程序也無(wú)法突破沙箱去獲取系統(tǒng)權(quán)限。
目前多進(jìn)程架構(gòu)
從圖中可以看出,最新的 Chrome 瀏覽器包括:1 個(gè)瀏覽器(Browser)主進(jìn)程、1 個(gè) GPU 進(jìn)程、1 個(gè)網(wǎng)絡(luò)(NetWork)進(jìn)程、多個(gè)渲染進(jìn)程和多個(gè)插件進(jìn)程。
(1)瀏覽器進(jìn)程
主要負(fù)責(zé)界面顯示、用戶交互、子進(jìn)程管理,同時(shí)提供存儲(chǔ)等功能。
(2)渲染進(jìn)程
核心任務(wù)是將 HTML、CSS 和 JavaScript 轉(zhuǎn)換為用戶可以與之交互的網(wǎng)頁(yè),排版引擎 Blink 和 JavaScript 引擎 V8 都是運(yùn)行在該進(jìn)程中,默認(rèn)情況下,Chrome 會(huì)為每個(gè) Tab 標(biāo)簽創(chuàng)建一個(gè)渲染進(jìn)程。出于安全考慮,渲染進(jìn)程都是運(yùn)行在沙箱模式下。
(3)GPU 進(jìn)程
其實(shí),Chrome 剛開始發(fā)布的時(shí)候是沒有 GPU 進(jìn)程的。而 GPU 的使用初衷是為了實(shí)現(xiàn) 3D CSS 的效果,只是隨后網(wǎng)頁(yè)、Chrome 的 UI 界面都選擇采用 GPU 來(lái)繪制,這使得 GPU 成為瀏覽器普遍的需求。最后,Chrome 在其多進(jìn)程架構(gòu)上也引入了 GPU 進(jìn)程。
(4)網(wǎng)絡(luò)進(jìn)程
主要負(fù)責(zé)頁(yè)面的網(wǎng)絡(luò)資源加載,之前是作為一個(gè)模塊運(yùn)行在瀏覽器進(jìn)程里面的,直至最近才獨(dú)立出來(lái),成為一個(gè)單獨(dú)的進(jìn)程。
(5)插件進(jìn)程
主要是負(fù)責(zé)插件的運(yùn)行,因插件易崩潰,所以需要通過插件進(jìn)程來(lái)隔離,以保證插件進(jìn)程崩潰不會(huì)對(duì)瀏覽器和頁(yè)面造成影響。
講到這里,現(xiàn)在你應(yīng)該就可以回答文章開頭提到的問題了:僅僅打開了 1 個(gè)頁(yè)面,為什么有 4 個(gè)進(jìn)程?因?yàn)榇蜷_ 1 個(gè)頁(yè)面至少需要 1 個(gè)網(wǎng)絡(luò)進(jìn)程、1 個(gè)瀏覽器進(jìn)程、1 個(gè) GPU 進(jìn)程以及 1 個(gè)渲染進(jìn)程,共 4 個(gè);如果打開的頁(yè)面有運(yùn)行插件的話,還需要再加上 1 個(gè)插件進(jìn)程。不過凡事都有兩面性,雖然多進(jìn)程模型提升了瀏覽器的穩(wěn)定性、流暢性和安全性,但同樣不可避免地帶來(lái)了一些問題:更高的資源占用。因?yàn)槊總€(gè)進(jìn)程都會(huì)包含公共基礎(chǔ)結(jié)構(gòu)的副本(如 JavaScript 運(yùn)行環(huán)境),這就意味著瀏覽器會(huì)消耗更多的內(nèi)存資源。更復(fù)雜的體系架構(gòu)。瀏覽器各模塊之間耦合性高、擴(kuò)展性差等問題,會(huì)導(dǎo)致現(xiàn)在的架構(gòu)已經(jīng)很難適應(yīng)新的需求了。
未來(lái)面向服務(wù)的架構(gòu)
為了解決這些問題,在 2016 年,Chrome 官方團(tuán)隊(duì)使用“面向服務(wù)的架構(gòu)”(Services Oriented Architecture,簡(jiǎn)稱 SOA)的思想設(shè)計(jì)了新的 Chrome 架構(gòu)。也就是說 Chrome 整體架構(gòu)會(huì)朝向現(xiàn)代操作系統(tǒng)所采用的“面向服務(wù)的架構(gòu)” 方向發(fā)展,原來(lái)的各種模塊會(huì)被重構(gòu)成獨(dú)立的服務(wù)(Service),每個(gè)服務(wù)(Service)都可以在獨(dú)立的進(jìn)程中運(yùn)行,訪問服務(wù)(Service)必須使用定義好的接口,通過 IPC 來(lái)通信,從而構(gòu)建一個(gè)更內(nèi)聚、松耦合、易于維護(hù)和擴(kuò)展的系統(tǒng),更好實(shí)現(xiàn) Chrome 簡(jiǎn)單、穩(wěn)定、高速、安全的目標(biāo)
Chrome 最終要把 UI、數(shù)據(jù)庫(kù)、文件、設(shè)備、網(wǎng)絡(luò)等模塊重構(gòu)為基礎(chǔ)服務(wù),類似操作系統(tǒng)底層服務(wù),下面是 Chrome“面向服務(wù)的架構(gòu)”的進(jìn)程模型圖:
目前 Chrome 正處在老的架構(gòu)向服務(wù)化架構(gòu)過渡階段,這將是一個(gè)漫長(zhǎng)的迭代過程。Chrome 正在逐步構(gòu)建 Chrome 基礎(chǔ)服務(wù)(Chrome Foundation Service),如果你認(rèn)為 Chrome 是“便攜式操作系統(tǒng)”,那么 Chrome 基礎(chǔ)服務(wù)便可以被視為該操作系統(tǒng)的“基礎(chǔ)”系統(tǒng)服務(wù)層。同時(shí) Chrome 還提供靈活的彈性架構(gòu),在強(qiáng)大性能設(shè)備上會(huì)以多進(jìn)程的方式運(yùn)行基礎(chǔ)服務(wù),但是如果在資源受限的設(shè)備上(如下圖),Chrome 會(huì)將很多服務(wù)整合到一個(gè)進(jìn)程中,從而節(jié)省內(nèi)存占用。
總結(jié)
以上是生活随笔為你收集整理的浏览器工作原理与实践学习笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nodejs express使用node
- 下一篇: 在浏览器里,从输入 URL 到页面展示,