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