前端--瀏覽器運行原理

瀏覽器
      瀏覽器(Web browser)是專門用來訪問和瀏覽萬維網頁面的客戶端軟件,也是現代計算機系統中應用最爲廣泛的軟件之一。前端工程師作爲負責程序頁面顯示的工程師,需要直接與瀏覽器打交道。本文將介紹瀏覽器的工作原理。

      瀏覽器的主要功能是向服務器發出請求,在瀏覽器窗口中展示用戶所需的網絡資源。這裏的資源一般指HTML文檔,PDF、圖片或其他類型。資源的位置由用戶使用URL(統一資源定位符)指定。

      目前使用的主流瀏覽器有5個: Internet Explore、Firefox、Safari、Chrome、Opera。
瀏覽器組成
      瀏覽器的組成如下圖1-1:
圖1 瀏覽器組成部分
  主要組件包括:

  1. 用戶界面 - 包括地址欄、 前進/後退按鈕、 書籤菜單等。 除了瀏覽器主窗口顯示的請求的頁面外,其他顯示的各個部分都屬於用戶界面。其他顯示的各個部分都屬於用戶界面。
  2. 瀏覽器引擎 - 在用戶界面和呈現引擎之間傳送指令。
  3. 渲染引擎 - 用來顯示請求的內容,例如,如果請求內容爲html,它負責解析html及css,並將解析後的結果顯示出來。
  4. 網絡 - 用來完成網絡調用,例如http請求,它具有平臺無關的接口,可以在不同平臺上工作。
  5. UI後端 - 用來繪製類似組合選擇框及對話框等基本組件,具有不特定於某個平臺的通用接口,底層使用操作系統的用戶接口。
  6. JS解釋器 - 用來解釋執行JS代碼。
  7. 數據存儲 - 屬於持久層,瀏覽器需要在硬盤中保存類似cookie的各種數據,HTML5定義了web database(網絡數據庫)技術,這是一種輕量級完整的客戶端存儲技術。

瀏覽器內核
      瀏覽器內核分成兩部分:渲染引擎和js引擎,由於js引擎越來越獨立,內核就傾向於只指渲染引擎,所以渲染引擎也稱爲瀏覽器內核,負責請求網絡頁面資源加以解析排版並呈現給用戶。渲染引擎一開始會從網絡層獲取請求文檔的內容,通常以8K分塊的方式完成。 獲取了文檔內容之後,渲染引擎開始正式工作,其基本流程如圖所示:圖片1-2 渲染引擎工作原理
      從資源的下載到最終的頁面展現,渲染流程可簡單地理解成一個線性串聯的變換過程的組合,原始輸入爲URL地址,最終輸出爲頁面Bitmap,中間依次經過了Loader、Parser、Layout和Paint模塊。

      渲染引擎解析HTML文檔,並將文檔中的標籤轉化爲DOM節點樹,即” 內容樹” 。 同時,它也會解析外部CSS文件以及style標籤中的樣式數據。 這些樣式信息連同HTML中的” 可見內容” 一道,被用於構建另一棵樹——” 渲染樹(Render樹)” 。 渲染樹構建完畢之後,將會進入” 佈局” 處理階段,即爲每一個節點分配一個屏幕座標。 再下一步就是繪製(painting),即遍歷render樹,並使用UI後端層繪製每個節點。

      注意:這個過程是逐步完成的,爲了更好的用戶體驗,渲染引擎將會盡可能早的將內容呈現到屏幕上,並不會等到所有的html都解析完成之後再去構建和佈局渲染樹。 它是解析完一部分內容就顯示一部分內容,同時,可能還在通過網絡下載其餘內容。
渲染引擎的核心流程如下圖
渲染引擎的核心流程
【Loader】

      Loader模塊負責處理所有的HTTP請求以及網絡資源的緩存,相當於是從URL輸入到Page Resource輸出的變換過程。HTML頁面中通常有外鏈的JS/CSS/Image資源,爲了不阻塞後續解析過程,一般會有兩個IO管道同時存在,一個負責主頁面下載,一個負責各種外鏈資源的下載。
  loader模塊工作流程
      注意:雖然大部分情況下不同資源可以併發下載異步解析(如圖片資源可以在主頁面解析顯示完成後再被顯示),但JS腳本可能會要求改變頁面,因此有時保持執行順序和下載管道後續處理的阻塞是不可避免的。
 1、解析HTML

      Parser模塊主要負責解析HTML頁面,完成從HTML文本到HTML語法樹再到文檔對象樹(Document Object Model Tree,DOM Tree)的映射過程
      HTML語法樹生成是一個典型的語法解析過程,可以分成兩個子過程:詞法解析和語法解析

      詞法解析按照詞法規則(如正則表達式)將HTML文本分割成大量的標記(token),並去除其中無關的字符如空格。語法解析按照語法規則(如上下文無關文法)匹配Token序列生成語法樹,通常有自上而下和自下而上兩種匹配方式

      瀏覽器內核中對HTML頁面真正的內部表示並不是語法樹,而是W3C組織規範的文檔對象模型(Document Object Model,DOM)。DOM也是樹形結構,以Document對象爲根。DOM節點基本和HTML語法樹節點一一對應,因此在語法解析過程中,通常直接生成最終的DOM樹

2、解析CSS

      頁面中所有的CSS由樣式表CSSStyleSheet集合構成,而CSSStyleSheet是一系列CSSRule的集合,每一條CSSRule則由選擇器CSSStyleSelector部分和聲明CSSStyleDeclaration部分構成,而CSSStyleDeclaration是CSS屬性和值的Key-Value集合

      CSS解析完畢後會進行CSSRule的匹配過程,即尋找滿足每條CSS規則Selector部分的HTML元素,然後將其Declaration部分應用於該元素。實際的規則匹配過程會考慮到默認和繼承的CSS屬性、匹配的效率及規則的優先級等因素

3、解析Javascript

      JavaScript一般由單獨的腳本引擎解析執行,它的作用通常是動態地改變DOM樹(比如爲DOM節點添加事件響應處理函數),即根據時間(timer)或事件(event)映射一棵DOM樹到另一棵DOM樹。

      簡單來說,經過了Parser模塊的處理,內核把頁面文本轉換成了一棵節點帶CSS Style、會響應自定義事件的Styled DOM樹

【layout】

      Layout過程就是排版,它包含兩大過程

1、創建渲染樹

      佈局樹(或者叫做渲染樹、Render Tree)和DOM樹大體能一一對應,兩者在內核中同時存在但作用不同。DOM樹是HTML文檔的對象表示,同時也作爲JavaScript操縱HTML的對象接口。Render樹是DOM樹的排版表示,用以計算可視DOM節點的佈局信息(如寬、高、座標)和後續階段的繪製顯示

注意:並非所有DOM節點都可視,也就是並非所有DOM樹節點都會對應生成一個Render樹節點。例如head標籤(HTMLHeadElement節點)不表示任何排版區域,因而沒有對應的Render節點。同時,DOM樹可視節點的CSS Style就是其對應Render樹節點的Style。在這裏插入圖片描述
2、計算佈局

      佈局就是安排和計算頁面中每個元素大小位置等幾何信息的過程。HTML採用流式佈局模型,基本的原則是頁面元素在順序遍歷過程中依次按從左至右、從上至下的排列方式確定各自的位置區域

      一個HTML元素對應一個以CSS盒子模型描述的方塊區域,HTML元素分成兩個基本類型,Inline和Block。Inline元素不會換行,按從左到右來佈局。Block元素的出現意味着需要從上至下換到下一行來佈局。除了這種基本的順序按照元素的Inline和Block來進行流式佈局之外,還有特殊指定的一些佈局方式,如Absolute/Fixed/Relative三種定位佈局以及Float浮動佈局

      簡單情況下,佈局可以順序遍歷一次Render樹完成,但也有需要迭代的情況。當祖先元素的大小位置依賴於後代元素或者互相依賴時,一次遍歷就無法完成佈局,如Table元素的寬高未明確指定而其下某一子元素Tr指定其高度爲父Table高度的30%的情況

      經過了Layout階段的處理,把帶Style的DOM樹變換成包含佈局信息和繪製信息的Render樹,接下來的顯示工作就交由Paint模塊進行操作了。
【Paint】
       Paint模塊負責將Render樹映射成可視的圖形,它會遍歷Render樹調用每個Render節點的繪製方法將其內容顯示在一塊畫布或者位圖上,並最終呈現在瀏覽器應用窗口中成爲用戶看到的實際頁面。每個節點對應的大小位置等信息都已經由Layout階段計算好了,節點的內容取決於對應的HTML元素,或是文本,或是圖片,或是UI控件

      通常情況下,佈局和繪製是相當耗時的操作。如果DOM樹每次略有改動都要重新佈局和繪製一次,效率會相當低下。因此,一般瀏覽內核都會實現一種增量佈局和增量繪製的方式。當一個DOM樹節點(或者它的子節點)內容或者樣式發生變化時,內核會確定其影響範圍,在佈局階段會標記出受該節點佈局影響的其他節點(比如可能是子節點),在繪製階段則會標記出一個Dirty區域並通知系統重繪

      按照HTML相關規範,頁面元素的CSS屬性也規定了其繪製順序,如根據不同Layer必須按順序繪製,否則覆蓋疊加效果會出現錯誤,如元素的邊框輪廓和內容背景的繪製次序也有規定。
網頁解析
 可以將瀏覽器整體看作一個網頁處理模塊,這個模塊的輸入是網絡上接收到的字節流形式的網頁內容。輸出是三棵樹型邏輯結構:DOM樹、Render樹及RenderLayer樹

      瀏覽器的解析過程就是將字節流形式的網頁內容構建成DOM樹、Render樹及RenderLayer樹的過程

      瀏覽器的解析對象是網頁內容,網頁內容包括以下三個部分:

1、HTML文檔:超文本標記語言,製作Web頁面的標準語言

2、CSS樣式表(Cascading Style Sheet):級聯樣式表,用來控制網頁樣式,並允許樣式信息與網頁內容相分離的一種標記性語言

3、JavaScript腳本:JavaScript是一種無類型的解釋型腳本語言。常用於爲網頁添加動態功能

      HTML文檔決定了DOM樹及Render樹的結構。CSS樣式表決定了Render樹上節點的排版佈局方式。JavaScript代碼可以操作DOM樹,改變DOM樹的結構,也可以用來給頁面添加更豐富的動態功能。

      HTML文檔被解析生成DOM樹,由DOM節點創建Render樹節點時,會觸發CSS匹配過程,CSS匹配的結果是RenderStyle實例,這個實例由Render節點持有,保存了Render節點的排版佈局信息。CSS的解析過程即是CSS語法在瀏覽器的內部表示過程,解析的結果是得到一系列的CSS規則。CSS的匹配過程主要依據CSS選擇器的不同優先級進行,高優先級選擇器優先適用。根據網頁上定義的JavaScript腳本的不同屬性,JavaScript腳本的下載和執行時機會有所不同。JavaScript腳本的執行是由渲染引擎轉交給JS引擎執行的。下面分別看一下HTML、CSS、JavaScript的具體解析和執行。
DOM樹構建
  DOM(Document Object Model,文檔對象模型),是中立於平臺和語言的接口。它允許程序和腳本動態地訪問和更新文檔的內容結構和樣式。DOM是頁面上數據和結構的一個樹形表示,使用DOM接口可以對DOM樹結構進行操作。DOM規範只是定義了編程接口,沒有對文檔的表示方式做任何限制。以樹狀結構表示DOM文檔是比較普遍的實現方式。這個樹狀結構就稱爲DOM樹。DOM樹是DOM文檔中的節點按照層次組織構成的。以HTML文檔爲例,每一個標籤都對應着DOM樹上的一個節點。由於是樹形結構表示,這些節點之間的關係也是通過父子或兄弟維繫的。
      渲染引擎解析HTML文檔的過程就是將字節流形式的網頁內容解析成DOM Tree、Render Tree、Render Layer Tree三棵樹的過程。這個過程可以分爲解碼、分詞、解析、建樹四個步驟

1、解碼:將網絡上接收到的經過編碼的字節流,解碼成Unicode字符

2、分詞:按照一定的切詞規則,將Unicode字符流切成一個個的詞語(Tokens)

3、解析:根據詞語的語義,創建相應的節點(Node)

4、建樹:將節點關聯到一起,創建DOM樹、Render樹和RenderLayer樹
  
 緩存

      緩存在瀏覽器中也得到了廣泛的應用,對提高用戶體驗起到了重要作用。在瀏覽器中,主要存在三種類型的緩存:Page Cache、Memory Cache、Disk Cache。這三類Cache的容量都是可以配置的,比如限制Memory Cache最大不超過30MB,Page Cache緩存的頁面數量不超過5個等。
 
【內存緩存】

      Memory Cache,顧名思義內存緩存,其主要作用爲緩存頁面使用各種派生資源。在使用瀏覽器瀏覽網頁時,尤其是瀏覽一個大型網站的不同頁面時,經常會遇到網頁中包含相同資源的情況,應用Memory Cache可以顯著提高瀏覽器的用戶體驗,減少無謂的內存、時間以及網絡帶寬開銷。

【頁面緩存】

      Page Cache,即頁面緩存。用來緩存用戶訪問過的網頁DOM樹、Render樹等數據。設計頁面緩存的意圖在於提供流暢的頁面前進、後退瀏覽體驗。幾乎所有的現代瀏覽器都支持頁面緩存功能。

      如果瀏覽器沒有頁面緩存,用戶點擊鏈接訪問新頁面時,原頁面的各種派生資源、JavaScript對象、DOM樹節點等佔據的內存統統被回收,此後當用戶點擊後退按鈕以瀏覽原頁面時,瀏覽器必須先要重新從網絡下載相關資源,然後進行解碼、解析、佈局、渲染一系列操作,最後才能爲用戶呈現出頁面,這無疑增加了用戶的等待時間,影響了用戶的使用體驗。

      所有的派生資源加載時都會與Memory Cache關聯,如果Memory Cache中有資源的備份且條件合適,則可以直接從Memory Cache中加載。而Page Cache只會在用戶點擊前進或後退按鈕時纔會被查詢,如果頁面符合緩存條件並被緩存了,則直接從Page Cache中加載。即使某個需要被加載的頁面在Page Cache中有備份,但若觸發加載的原因是用戶在地址欄輸入url或點擊鏈接,則頁面仍然是通過網絡加載。也就是說Page Cache並不是主資源的通用緩存。

【磁盤緩存】

      Disk Cache,即磁盤緩存。現代的瀏覽器基本都有磁盤緩存機制,爲了提升用戶的使用體驗,瀏覽器將下載的資源保存到本地磁盤,當瀏覽器下次請求相同的資源時,可以省去網絡下載資源的時間,直接從本地磁盤中取出資源即可。

      磁盤緩存即我們常說的Web緩存,分爲強緩存和協商緩存,它們的區別在於強緩存不發請求到服務器,協商緩存會發請求到服務器。
關於瀏覽器工作原理內容還有很多,在此不詳細敘述,本人前端小白,此文章部分內容也是源自大佬的文章學習參考.
參考資料:
      1.http://www.cnblogs.com/xiaohuochai/p/9174471.html 深入理解瀏覽器工作原理
      2.https://blog.csdn.net/u014744118/article/details/80698602 前端進階(一)瀏覽器運行原理

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