瀏覽器原理系列 --- 宏觀篇

概述

基於一個高頻面試題‘瀏覽器地址欄輸入到展現發生了什麼’引起的深刻思考;若是要很好的回答這個問題,須要比較全面地掌握計算機不少知識,其中涉及到了網絡、操做系統、Web等一系列的知識。此次經過瀏覽器底層原理系列分析來更好地回答這個問題。javascript

主要經過如下四個系列學習瀏覽器原理:java

  • 瀏覽器宏觀框架
  • 瀏覽器網絡原理
  • 瀏覽器渲染引擎
  • 瀏覽器安全

收斂發現問題本質

針對問題‘瀏覽器地址欄輸入到展現發生了什麼’可能咱們不少人的腦海中第一印象是以下圖所示答案比較發散:web

實際若是有關注過Chrome瀏覽器的任務管理系統,咱們能夠發現瀏覽器打開一個標籤頁面會啓動四個進程面試

基於這四個進程咱們能夠從新梳理髮散的答案,對這些答案進行收斂以下圖所示chrome

經過簡單收斂咱們能夠發現學習瀏覽器原理只要學習這四類進程之間在作什麼進行歸類學習。編程

學習以前能夠追溯歷史看看瀏覽器的發展歷史,方便咱們在後續學習中針對遇到的一些能夠找到歷史的影子。瀏覽器

進程 VS 線程

進程

進程能夠被描述爲一個應用的執行程序,線程存在於進程並執行任意部分。操做系統爲進程提供了一塊可使用的內存[數據],應用的全部狀態都保存在該私有內存空間中,關閉應用,進程會關閉,操做系統釋放內存安全

進程以下圖所示:服務器

如圖所示單獨的進程中包含了可執行代碼、內存數據、操做系統文件等網絡

進程具備的特徵:

  • 動態性:進程是程序的一次執行過程,是臨時的,有生命期的,是動態產生,動態消亡的;
  • 併發性:任何進程均可以同其餘進行一塊兒併發執行;
  • 獨立性:進程是系統進行資源分配和調度的一個獨立單位;
  • 結構性:進程由程序,數據和進程控制塊三部分組成

線程

  早期的操做系統中並無線程的概念,後來隨着計算機的發展,對CPU的要求愈來愈高,進程之間的切換開銷較大,已經沒法知足愈來愈複雜的程序的要求了。因而就發明了線程,線程是程序執行中一個單一的順序控制流程,是程序執行流的最小單元,是處理器調度和分派的基本單位。   

  • 線程是程序執行的最小單位,而進程是操做系統分配資源的最小單位;
  • 一個進程由一個或多個線程組成,線程是一個進程中代碼的不一樣執行路線
  • 同一進程下的各個線程之間共享程序的內存空間(包括代碼段,數據集,堆等)及一些進程級的資源(如打開文件和信號等),某進程內的線程在其餘進程不可見;
  • 調度和切換:線程上下文切換比進程上下文切換要快得多

多線程

從上圖能夠看出,線程 一、線程 二、線程 3 分別把執行的結果寫入 A、B、C 中,而後線程 2 繼續從 A、B、C 中讀取數據,用來顯示執行結果

總結

  • 進程之間的內容相互隔離
  • 當一個進程關閉以後,操做系統會回收進程所佔用的內存
  • 線程之間共享進程中的數據
  • 進程中的任意一線程執行出錯,都會致使整個進程的崩潰。
  • 線程是依附於進程的,而進程中使用多線程並行處理能提高運算效率
  • 線程是不能單獨存在的,它是由進程來啓動和管理的

瀏覽器架構演進

單進程瀏覽器架構

單進程瀏覽器是指瀏覽器的全部功能模塊都是運行在同一個進程裏,這些模塊包含了網絡、插件、JavaScript 運行環境、渲染引擎和頁面等。在2007年以前的瀏覽器都基本是單進程瀏覽器。

能夠看出只有一個進程(progress), 多個功能模塊都是經過多個線程並行處理任務實現。

單進程架構問題

問題1:不穩定

早起瀏覽器都是經過第三方插件來實現諸如 Web 視頻、Web 遊戲等各類強大的功能,可是插件是最容易出問題的模塊。這些插件以線程運行在瀏覽器,一個插件的意外崩潰會引發整個瀏覽器的崩潰。

渲染引擎模塊也是不穩定的。一般一些複雜的 JavaScript 代碼就有可能引發渲染引擎模塊的崩潰。

問題2:不流暢

從上面的「單進程瀏覽器架構示意圖」能夠看出,全部頁面的渲染模塊、JavaScript 執行環境以及插件都是運行在同一個線程中的,這就意味着同一時刻只能有一個模塊能夠執行

function freeze() {
    while (1) { 
        console.log("freeze");
    }
};
freeze();
複製代碼

由於這個腳本是無限循環的,因此當其執行時,它會獨佔整個線程,這樣致使其餘運行在該線程中的模塊就沒有機會被執行。由於瀏覽器中全部的頁面都運行在該線程中,因此這些頁面都沒有機會去執行任務,這樣就會致使整個瀏覽器失去響應,變卡頓。

頁面的內存泄漏也是單進程變慢的一個重要緣由。一般瀏覽器的內核都是很是複雜的,運行一個複雜點的頁面再關閉頁面,會存在內存不能徹底回收的狀況,這樣致使的問題是使用時間越長,內存佔用越高,瀏覽器會變得越慢。

問題3:不安全

插件可使用 C/C++ 等代碼編寫,經過插件能夠獲取到操做系統的任意資源,當你在頁面運行一個插件時也就意味着這個插件能徹底操做你的電腦。若是是個惡意插件,那麼它就能夠釋放病毒、竊取你的帳號密碼,引起安全性問題。

至於頁面腳本,它能夠經過瀏覽器的漏洞來獲取系統權限,這些腳本獲取系統權限以後也能夠對你的電腦作一些惡意的事情,一樣也會引起安全問題

多進程瀏覽器架構

在2008年因爲Chrome的橫空出世,chrome採用多進程架構,比較好的體驗快速的佔領了使用市場。最新的 Chrome 瀏覽器包括:1 個瀏覽器(Browser)主進程、1 個 GPU 進程、1 個網絡(NetWork)進程、多個渲染進程和多個插件進程。

架構示意圖以下圖所示:

基於上面的架構示意圖咱們來分析多進程架構如何解決單進程的架構的問題

如何解決單進程問題

解決不穩定的問題

因爲進程是相互隔離的,因此當一個頁面或者插件崩潰時,影響到的僅僅是當前的頁面進程或者插件進程,並不會影響到瀏覽器和其餘頁面,這就完美地解決了頁面或者插件的崩潰會致使整個瀏覽器崩潰,也就是不穩定的問題

解決不流暢的問題

JavaScript也是運行在渲染進程中的,因此即便 JavaScript 阻塞了渲染進程,影響到的也只是當前的渲染頁面,而並不會影響瀏覽器和其餘頁面,由於其餘頁面的腳本是運行在它們本身的渲染進程中的。因此當咱們再在 Chrome 中運行上面那個死循環的腳本時,沒有響應的僅僅是當前的頁面。

對於內存泄漏的解決方法那就更簡單了,由於當關閉一個頁面時,整個渲染進程也會被關閉,以後該進程所佔用的內存都會被系統回收,這樣就輕鬆解決了瀏覽器頁面的內存泄漏問題。

解決安全問題

採用多進程架構的額外好處是可使用安全沙箱,你能夠把沙箱當作是操做系統給進程上了一把鎖,沙箱裏面的程序能夠運行,可是不能在你的硬盤上寫入任何數據,也不能在敏感位置讀取任何數據,例如你的文檔和桌面

各個進程職責

  • 瀏覽器進程。主要負責界面顯示、用戶交互、子進程管理,同時提供存儲等功能。
  • 渲染進程。核心任務是將 HTML、CSS 和 JavaScript 轉換爲用戶能夠與之交互的網頁,排版引擎 Blink 和 JavaScript 引擎 V8 都是運行在該進程中,默認狀況下,Chrome 會爲每一個 Tab 標籤建立一個渲染進程。出於安全考慮,渲染進程都是運行在沙箱模式下。
  • GPU 進程。其實,Chrome 剛開始發佈的時候是沒有 GPU 進程的。而 GPU 的使用初衷是爲了實現 3D CSS 的效果,只是隨後網頁、Chrome 的 UI 界面都選擇採用 GPU 來繪製,這使得 GPU 成爲瀏覽器廣泛的需求。最後,Chrome 在其多進程架構上也引入了 GPU 進程。
  • 網絡進程。主要負責頁面的網絡資源加載,以前是做爲一個模塊運行在瀏覽器進程裏面的,直至最近才獨立出來,成爲一個單獨的進程。插件進程。主要是負責插件的運行,因插件易崩潰,因此須要經過插件進程來隔離,以保證插件進程崩潰不會對瀏覽器和頁面形成影響。

多進程架構問題

問題1 比較高的資源佔用

由於每一個進程都會包含公共基礎結構的副本(如 JavaScript 運行環境),這就意味着瀏覽器會消耗更多的內存資源。

問題2 複雜的體系架構

瀏覽器各模塊之間耦合性高、擴展性差等問題,會致使如今的架構已經很難適應新的需求了

面向服務的架構(SOP)

在 2016 年,Chrome 官方團隊使用「面向服務的架構」(Services Oriented Architecture,簡稱 SOA)的思想設計了新的 Chrome 架構。也就是說 Chrome 總體架構會朝向現代操做系統所採用的「面向服務的架構」 方向發展,原來的各類模塊會被重構成獨立的服務(Service),每一個服務(Service)均可以在獨立的進程中運行,訪問服務(Service)必須使用定義好的接口,經過 IPC 來通訊,從而構建一個更內聚、鬆耦合、易於維護和擴展的系統,更好實現 Chrome 簡單、穩定、高速、安全的目標。

同時 Chrome 還提供靈活的彈性架構,在強大性能設備上會以多進程的方式運行基礎服務,可是若是在資源受限的設備上(以下圖),Chrome 會將不少服務整合到一個進程中,從而節省內存佔用。服務能夠彈性部署到不一樣進程中。核心解決佔用資源高的問題,和解耦進程之間的耦合。

安全沙箱

安全沙箱:將渲染進程和操做系統隔離的這道牆就是咱們要聊的安全沙箱。具體的架構示意圖以下圖所示

由於網絡資源的內容存在着各類可能性,因此瀏覽器會默認全部的網絡資源都是不可信的,都是不安全的。但誰也不能保證瀏覽器不存在漏洞,只要出現漏洞,黑客就能夠經過網絡內容對用戶發起攻擊。可是咱們沒有給網絡進程設置安全沙箱, 下載了一個惡意程序,可是沒有執行它,那麼惡意程序是不會生效的, 可是卻給渲染進程設置了安全沙箱,因爲渲染進程須要執行 DOM 解析、CSS 解析、網絡圖片解碼等操做,若是渲染進程中存在系統級別的漏洞,那麼以上操做就有可能讓惡意的站點獲取到渲染進程的控制權限,進而又獲取操做系統的控制權限,這對於用戶來講是很是危險的。

安全沙箱好處

  • 安全沙箱設置的最小單位是進程。單進程設置會致使功能不可用
  • 站點隔離,同一個標籤頁不一樣進程,互相不影響;不會致使惡意程序

安全沙箱不便利

  • 持久存儲受影響 -- 例如文件存儲
  • 用戶交互事件 --- 必須經過主進程
  • 網絡訪問 ---- 同源策略

總結

瀏覽器總體發展線路

  1. 應用程序 Web化:

    隨着雲計算的普及和 HTML5 技術的快速發展,愈來愈多的應用轉向了瀏覽器 / 服務器(B/S)架構,這種改變讓瀏覽器的重要性與日俱增,視頻、音頻、遊戲幾大核心場景也都在往 Web 的使用場景切換。

  2. Web 應用移動化。

    對於移動設備應用,Web 天生具備開放的基因,雖然在技術層面還有問題尚待解決(好比,渲染流程過於複雜且性能不及原生應用、離線時用戶沒法使用、沒法接收消息推送、移動端沒有一級入口),但 Google 推出了 PWA 方案來整合 Web 和本地程序各自的優點。順便說一句,PWA 也是我我的很是期待的方案。

  3. Web 操做系統化。

    在我看來,Web 操做系統有兩層含義:

    • 利用 Web 技術構建一個純粹的操做系統,如ChromeOS
    • 是瀏覽器的底層結構往操做系統架構方向發展,在整個架構演化的大背景下會牽涉諸多改變。Chrome 朝着 SOA 的方向演化,將來不少模塊都會以服務的形式提供給上層應用使用;在瀏覽器中引入多種編程語言的支持,好比新支持的 WebAssembly;簡化渲染流程,使得渲染過程更加直接高效;加大對系統設備特性的支持;提供對複雜Web 項目開發的支持。也就是說,瀏覽器已經逐步演化成了操做系統之上的「操做系統

最後總結推動瀏覽器架構演進是因爲web的世界愈來愈複雜化。

相關文章
相關標籤/搜索