瀏覽器工作原理與實踐總結一


一、常用Chrome架構

Chrome 打開一個頁面需要啓動多少進程?你可以點擊 Chrome 瀏覽器右上角的“選項”菜單,選擇“更多工具”子菜單,點擊“任務管理器”查看

相關概念

並行處理:同一時刻處理多個任務**(多線程,大大提升性能)


線程VS進程:1、線程是不能單獨存在的,它是由進程來啓動和管理的2、啓動一個程序的時候,操作系統會爲該程序創建一塊內存,用來存放代碼、運行中的數據和一個執行任務的主線程,我們把這樣的一個運行環境叫進程。


線程是依附於進程的,而進程中使用多線程並行處理能提升運算效率。

  1. 進程中的任意一線程執行出錯,都會導致整個進程的崩潰。
  2. 線程之間共享進程中的數據。
  3. 當一個進程關閉之後,操作系統會回收進程所佔用的內存。
  4. 進程之間的內容相互隔離。採用進程間通信(IPC)的機制。

單進程瀏覽器是指瀏覽器的所有功能模塊都是運行在同一個進程裏,這些模塊包含了網絡、插件、JavaScript運行環境、渲染引擎和頁面等。使用單進程瀏覽器會帶來以下三個原因:

  • 不穩定
  • 不流暢
  • 不安全

Chrome進程架構(多線程)

clipboard.png
從圖中可以看出,最新的 Chrome 瀏覽器包括:1 個瀏覽器(Browser)主進程、1 個 GPU 進程、1 個網絡(NetWork)進程、多個渲染進程和多個插件進程。


下面我們來逐個分析下這幾個進程的功能。

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

在多線程模型提升瀏覽器的穩定性、流暢性、安全性之外也帶來了:

  • 更高的資源佔用。(消耗內存)
  • 更復雜的體系架構。(瀏覽器各模塊之間耦合性高、擴展性差)

探索未來面向服務的架構


二、TCP協議,保證頁面文件能被完整送達瀏覽器


衡量Web頁面性能的時候有一個重要指標叫:“FP”指從頁面加載到首次開始繪製的時長。影響FP指標:網絡加載速度。


HTTPWebSocket都是基於TCP/IP的,TCP/IP是優化Web頁面的加載速度的根基。


如何保證頁面文件能被完整地送達到瀏覽器呢?

站在數據包的視角

clipboard.png
IP負責把數據包送達目的主機。


2、UDP:把數據包送達應用程序,因爲IP是非常底層的協議,只負責把數據包傳送到對方電腦,但是對方電腦並不知道把數據包交給哪個程序,因此,需要基於IP之上開發能和應用打交道的協議,常見的“用戶數據包協議”稱爲UDP。

clipboard.png
IP通過IP地址信息把數據包發送到指定的電腦,而UDP通過端口把數據包分發給正確程序。


使用UDP會產生那些問題:

  • 1、UDP發送數據時因各種因素會有丟包現象,且不提供重發機制,所以不能保證數據可靠性。
  • 2、UDP傳輸速度非常快,所以UDP會應用在一些關注速度、但不那麼嚴格要求數據完整的領域,如在線視頻、互動遊戲等。

爲了解決UDP數據包傳輸過程容易丟失,引入TCP。


TCP:把數據完整地送達應用程序,是一種面向連接的、可靠的、基於字節流的傳輸層通信協議。


TCP兩個特點:

  • 1、對於數據包丟失的情況,TCP提供重傳機制;
  • 2、TCP引入數據包排序機制,用來保證把亂序的數據包組合成一個完整的文件。

完整的TCP連接的生命週期包括:

  • 1、建立連接
  • 2、傳輸數據
  • 3、斷開連接

clipboard.png
TCP爲了保證數據傳輸的可靠性(通過TCP頭保證了一塊大的數據傳輸),犧牲了數據包的傳輸速度,因爲“三次握手”和“數據包校驗機制”等把傳輸過程的數據包數量提高了一倍。


三、HTTP請求流程,很多站點第二次打開速度會很快?

HTTP協議,是建立在TCP連接的基礎上的(HTTP應用層,TCP傳輸層)。HTTP是一種允許瀏覽器向服務器獲取資源的協議,是Web基礎。


爲什麼很多站點第二次打開速度會很快?這一切都隱藏在HTTP請求中。


瀏覽器端發起HTTP請求流程:

  • 1、構建請求行信息,構建好後,瀏覽器準備發起網絡請求。
  • 2、查找緩存。
在真正發起網絡請求之前,瀏覽器會先在瀏覽器緩存中查詢是否要請求的文件。其中,瀏覽器緩存是一種在本地保存資源副本,以供下次請求時直接使用的技術。發起網絡請求——瀏覽器緩存已存副本——攔截請求——返回該資源副本——結束請求(不會重新去服務器下載資源)

這樣做的好處:1、緩解服務器端壓力,提升性能(獲取資源耗時更短)2、對網站來說,緩存是實現快速資源加載的重要組成部分。

  • 3、準備IP地址和端口
HTTP網絡請求的第一步是和服務器建立TCP連接,建立TCP連接第一步準備IP地址和端口號(HTTP默認80,HTTPS默認443)。DNS數據緩存服務,對域名解析以供下次直接使用,這樣會減少一次網絡請求。
  • 4、等待TCP隊列
Chrome有個機制,同一個域名同時最多隻能建立6個TCP連接,如果在同一個域名下同時有10個請求發生,那麼4個請求會進入排隊等待狀態,直至進行中請求完成。
  • 5、建立TCP連接
  • 6、發送HTTP請求(請求行、請求頭、請求體(數據))Get跟post方法

服務器端處理瀏覽器端發送過來的HTTP請求

  • 1、返回請求(成功狀態碼200,沒找到頁面404,響應行、響應頭、響應體)
  • 2、斷開連接(服務器向客戶端返回請求數據,關閉TCP連接)
  • 3、重定向

頁面二次打開會很快?

  • 1、DNS緩存
  • 2、頁面資源緩存

DNS緩存:瀏覽器本地IP和域名關聯起來
頁面資源緩存:響應頭Cache-Control字段來設置是否緩存該資源。時長是Max-age參數設置。

Cache-Control:Max-age=2000

若緩存資源過期則會繼續發起請求。

很多網站第二次訪問能夠秒開,是因爲這些網站把很多資源都緩存在了本地,瀏覽器緩存直接使用本地副本來回應請求,而不會產生真實的網絡請求,從而節省了時間。同時,DNS 數據也被瀏覽器緩存了,這又省去了 DNS 查詢環節。


如何保持登錄狀態?

clipboard.png


四、從輸入URL到頁面展示經歷什麼?

整個過程需要各個進程之間的配合:

  • 瀏覽器進程:主要負責用戶交互、子進程管理和文件儲存等功能。
  • 網絡進程:是面向渲染進程和瀏覽器進程等提供網絡下載功能。
  • 渲染進程:主要職責是把從網絡下載的HTML、JavaScript、CSS、圖片等資源解析爲可以顯示和交互的頁面。因爲渲染進程所有的內容都是通過網絡獲取的,會存在一些惡意代碼利用瀏覽器漏洞對系統進行攻擊,所以運行在渲染進程裏面的代碼是不被信任的。這也是爲什麼 Chrome 會讓渲染進程運行在安全沙箱裏,就是爲了保證系統的安全。

不考慮用戶輸入搜索關鍵字的情況:

1、用戶輸入url並回車
2、瀏覽器進程檢查url,組裝協議,構成完整的url
3、瀏覽器進程通過進程間通信(IPC)把url請求發送給網絡進程
4、網絡進程接收到url請求後檢查本地緩存是否緩存了該請求資源,如果有則將該資源返回給瀏覽器進程

5、如果沒有,網絡進程向web服務器發起http請求(網絡請求),請求流程如下:
    5.1 進行DNS解析,獲取服務器ip地址,端口(http端口默認80,https默認443)
    5.2 利用ip地址和服務器建立tcp連接
    5.3 構建請求頭信息
    5.4 發送請求頭信息
    5.5 服務器響應後,網絡進程接收響應頭和響應信息,並解析響應內容
6、網絡進程解析響應流程;
    6.1 檢查狀態碼,如果是301/302,則需要重定向,從Location自動中讀取地址,重新進行第4步。 301資源被永久移除 ,302資源還在。          
    6.2 200響應處理:
        檢查響應類型Content-Type,如果是字節流類型,則將該請求提交給下載管理器,該導航流程結束,不再進行
        後續的渲染,如果是html則通知瀏覽器進程準備渲染進程準備進行渲染。
7、準備渲染進程
    7.1 瀏覽器進程檢查當前url是否和之前打開的渲染進程根域名是否相同,如果相同,則複用原來的進程,如果不同,則開啓新的渲染進程
8、傳輸數據、更新狀態
    8.1 渲染進程準備好後,瀏覽器向渲染進程發起“提交文檔”的消息,渲染進程接收到消息和網絡進程建立傳輸數據的“管道”
    8.2 渲染進程接收完數據後,向瀏覽器發送“確認提交”
    8.3 瀏覽器進程接收到確認消息後更新瀏覽器界面狀態:安全、地址欄url、前進後退的歷史狀態、更新web頁面。    
9、渲染進程對文檔進行頁面解析和子資源加載,HTML 通過HTM 解析器轉成DOM Tree
 (二叉樹類似結構的東西),CSS按照CSS規則和CSS解釋器轉成CSSOM TREE,兩個tree結合,
  形成rendertree(不包含HTML的具體元素和元素要畫的具體位置),
  通過Layout可以計算出每個元素具體的寬高顏色位置,結合起來,開始繪製,最後顯示在屏幕中新頁面顯示出來


五、渲染流程:HTML、CSS、JavaScript是如何變成頁面?

渲染機制過於複雜,所以渲染模塊在執行過程中會被劃分爲很多子階段,輸入的 HTML 經過這些子階段,最後輸出像素。我們把這樣的一個處理流程叫做渲染流水線。
從 HTML 到 DOM、樣式計算、佈局、圖層、繪製、光柵化、合成和顯示

  • DOM樹:渲染進程將 HTML 內容轉換爲能夠讀懂的DOM 樹結構。
  • 樣式計算:渲染引擎將 CSS 樣式錶轉化爲瀏覽器可以理解的styleSheets,計算出 DOM 節點的樣式。
  • 佈局樹:創建佈局樹,並計算元素的佈局信息。
  • 分層:對佈局樹進行分層,並生成分層樹。
  • 繪製:爲每個圖層生成繪製列表,並將其提交到合成線程。
  • 光柵化:合成線程將圖層分成圖塊,並在光柵化線程池中將圖塊轉換成位圖。
  • 合成:合成線程發送繪製圖塊命令DrawQuad給瀏覽器進程。
  • 顯示:瀏覽器進程根據 DrawQuad 消息生成頁面,並顯示到顯示器上。

重排:如果你通過 JavaScript 或者 CSS 修改元素的幾何位置屬性,例如改變元素的寬度、高度等,那麼瀏覽器會觸發重新佈局,解析之後的一系列子階段,這個過程就叫重排。無疑,重排需要更新完整的渲染流水線,所以開銷也是最大的。


重繪:如果修改了元素的背景顏色,那麼佈局階段將不會被執行,因爲並沒有引起幾何位置的變換,所以就直接進入了繪製階段,然後執行之後的一系列子階段,這個過程就叫重繪。相較於重排操作,重繪省去了佈局和分層階段,所以執行效率會比重排操作要高一些。


合成:如果你更改一個既不要佈局也不要繪製的屬性,會發生什麼變化呢?渲染引擎將跳過佈局和繪製,只執行後續的合成操作,我們把這個過程叫做合成。


減少重排重繪, 方法很多:

  1. 使用 class 操作樣式,而不是頻繁操作 style
  2. 避免使用 table 佈局
  3. 批量dom 操作,例如 createDocumentFragment,或者使用框架,例如 React
  4. Debounce window resize 事件
  5. 對 dom 屬性的讀寫要分離
  6. will-change: transform 做優化。

課程地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章