1. 程式人生 > 實用技巧 >瀏覽器工作原理與實踐總結

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

轉載:https://segmentfault.com/a/1190000020372713?utm_source=tag-newest

一、常用Chrome架構

Chrome 開啟一個頁面需要啟動多少程序?你可以點選 Chrome 瀏覽器右上角的“選項”選單,選擇“更多工具”子選單,點選“工作管理員”檢視

相關概念

並行處理:同一時刻處理多個任務**(多執行緒,大大提升效能)


執行緒VS程序:1、執行緒是不能單獨存在的,它是由程序來啟動和管理的2、啟動一個程式的時候,作業系統會為該程式建立一塊記憶體,用來存放程式碼、執行中的資料和一個執行任務的主執行緒,我們把這樣的一個執行環境叫程序。


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

  1. 程序中的任意一執行緒執行出錯,都會導致整個程序的崩潰。
  2. 執行緒之間共享程序中的資料。
  3. 當一個程序關閉之後,作業系統會回收程序所佔用的記憶體。
  4. 程序之間的內容相互隔離。採用程序間通訊(IPC)的機制。

單程序瀏覽器是指瀏覽器的所有功能模組都是執行在同一個程序裡,這些模組包含了網路、外掛、JavaScript執行環境、渲染引擎和頁面等。使用單程序瀏覽器會帶來以下三個原因:

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

Chrome程序架構(多執行緒)


從圖中可以看出,最新的 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頁面的載入速度的根基。


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

站在資料包的視角


IP負責把資料包送達目的主機。


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


IP通過IP地址資訊把資料包傳送到指定的電腦,而UDP通過埠把資料包分發給正確程式。


使用UDP會產生那些問題:

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

為了解決UDP資料包傳輸過程容易丟失,引入TCP。


TCP:把資料完整地送達應用程式,是一種面向連線的、可靠的、基於位元組流的傳輸層通訊協議。


TCP兩個特點:

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

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

  • 1、建立連線
  • 2、傳輸資料
  • 3、斷開連線


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 查詢環節。


如何保持登入狀態?


四、從輸入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 做優化。

作者:陽光總在風雨後
連結:https://segmentfault.com/a/1190000020372713?utm_source=tag-newest
來源:SegmentFault 思否
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。