1. 程式人生 > >前端必讀:瀏覽器內部工作原理

前端必讀:瀏覽器內部工作原理

 目錄

  一、介紹
  二、渲染引擎
  三、解析與DOM樹構建
  四、渲染樹構建
  五、佈局
  六、繪製
  七、動態變化
  八、渲染引擎的執行緒
  九、CSS2可視模型

  一、介紹

  瀏覽器可以被認為是使用最廣泛的軟體,本文將介紹瀏覽器的工作原理,我們將看到,從你在位址列輸入google.com到你看到google主頁過程中都發生了什麼。

  將討論的瀏覽器

  今天,有五種主流瀏覽器——IE、Firefox、Safari、Chrome及Opera。

  本文將基於一些開源瀏覽器的例子——Firefox、Chrome及Safari,Safari是部分開源的。

  根據W3C(World Wide Web Consortium全球資訊網聯盟)的瀏覽器統計資料,當前(2011年5月),Firefox、Safari及Chrome的市場佔有率綜合已接近60%。(原文為2009年10月,資料沒有太大變化)因此,可以說開源瀏覽器已經佔據了瀏覽器市場的半壁江山。

  瀏覽器的主要功能

  瀏覽器的主要功能是將使用者選擇的web資源呈現出來,它需要從伺服器請求資源,並將其顯示在瀏覽器視窗中,資源的格式通常是HTML,也包括PDF、image及其他格式。使用者用URI(Uniform Resource Identifier統一資源識別符號)來指定所請求資源的位置,在網路一章有更多討論。

  HTML和CSS規範中規定了瀏覽器解釋html文件的方式,由W3C組織對這些規範進行維護,W3C是負責制定web標準的組織。

  HTML規範的最新版本是HTML4(http://www.w3.org/TR/html401/),HTML5還在制定中(譯註:兩年前),最新的CSS規範版本是2(http://www.w3.org/TR/CSS2),CSS3也還正在制定中(譯註:同樣兩年前)。

  這些年來,瀏覽器廠商紛紛開發自己的擴充套件,對規範的遵循並不完善,這為web開發者帶來了嚴重的相容性問題。

  但是,瀏覽器的使用者介面則差不多,常見的使用者介面元素包括:

  • 用來輸入URI的位址列
  • 前進、後退按鈕
  • 書籤選項
  • 用於重新整理及暫停當前載入文件的重新整理、暫停按鈕
  • 用於到達主頁的主頁按鈕

  奇怪的是,並沒有哪個正式公佈的規範對使用者介面做出規定,這些是多年來各瀏覽器廠商之間相互模仿和不斷改進的結果。

  HTML5並沒有規定瀏覽器必須具有的UI元素,但列出了一些常用元素,包括位址列、狀態列及工具欄。還有一些瀏覽器有自己專有的功能,比如Firefox的下載管理。更多相關內容將在後面討論使用者介面時介紹。

  瀏覽器的主要構成(High Level Structure)

  瀏覽器的主要元件包括:

  1. 使用者介面 - 包括位址列、後退/前進按鈕、書籤目錄等,也就是你所看到的除了用來顯示你所請求頁面的主視窗之外的其他部分。

  2. 瀏覽器引擎 - 用來查詢及操作渲染引擎的介面。

  3. 渲染引擎 - 用來顯示請求的內容,例如,如果請求內容為html,它負責解析html及css,並將解析後的結果顯示出來。

  4. 網路 - 用來完成網路呼叫,例如http請求,它具有平臺無關的介面,可以在不同平臺上工作。

  5. UI後端 - 用來繪製類似組合選擇框及對話方塊等基本元件,具有不特定於某個平臺的通用介面,底層使用作業系統的使用者介面。

  6. JS直譯器 - 用來解釋執行JS程式碼。

  7. 資料儲存 - 屬於持久層,瀏覽器需要在硬碟中儲存類似cookie的各種資料,HTML5定義了web database技術,這是一種輕量級完整的客戶端儲存技術

圖1:瀏覽器主要元件

  需要注意的是,不同於大部分瀏覽器,Chrome為每個Tab分配了各自的渲染引擎例項,每個Tab就是一個獨立的程序。

  對於構成瀏覽器的這些元件,後面會逐一詳細討論。

  二、渲染引擎(The rendering engine)

  渲染引擎的職責就是渲染,即在瀏覽器視窗中顯示所請求的內容。

  預設情況下,渲染引擎可以顯示html、xml文件及圖片,它也可以藉助外掛(一種瀏覽器擴充套件)顯示其他型別資料,例如使用PDF閱讀器外掛,可以顯示PDF格式,將由專門一章講解外掛及擴充套件,這裡只討論渲染引擎最主要的用途——顯示應用了CSS之後的html及圖片。

  渲染引擎簡介

  本文所討論的瀏覽器——Firefox、Chrome和Safari是基於兩種渲染引擎構建的,Firefox使用Geoko——Mozilla自主研發的渲染引擎,Safari和Chrome都使用webkit。

  Webkit是一款開源渲染引擎,它本來是為Linux平臺研發的,後來由Apple移植到Mac及Windows上,相關內容請參考http://webkit.org

  渲染主流程(The main flow)

  渲染引擎首先通過網路獲得所請求文件的內容,通常以8K分塊的方式完成。

  下面是渲染引擎在取得內容之後的基本流程:

  解析html以構建dom樹 -> 構建render樹 -> 佈局render樹 -> 繪製render樹

圖2:渲染引擎基本流程

  渲染引擎開始解析html,並將標籤轉化為內容樹中的dom節點。接著,它解析外部CSS檔案及style標籤中的樣式資訊。這些樣式資訊以及html中的可見性指令將被用來構建另一棵樹——render樹。

  Render樹由一些包含有顏色和大小等屬性的矩形組成,它們將被按照正確的順序顯示到螢幕上。

  Render樹構建好了之後,將會執行佈局過程,它將確定每個節點在螢幕上的確切座標。再下一步就是繪製,即遍歷render樹,並使用UI後端層繪製每個節點。

  值得注意的是,這個過程是逐步完成的,為了更好的使用者體驗,渲染引擎將會盡可能早的將內容呈現到螢幕上,並不會等到所有的html都解析完成之後再去構建和佈局render樹。它是解析完一部分內容就顯示一部分內容,同時,可能還在通過網路下載其餘內容。

圖3:webkit主流程

圖4:Mozilla的Geoko渲染引擎主流程

  從圖3和4中可以看出,儘管webkit和Gecko使用的術語稍有不同,他們的主要流程基本相同。Gecko稱可見的格式化元素組成的樹為frame樹,每個元素都是一個frame,webkit則使用render樹這個名詞來命名由渲染物件組成的樹。Webkit中元素的定位稱為佈局,而Gecko中稱為迴流。Webkit稱利用dom節點及樣式資訊去構建render樹的過程為attachment,Gecko在html和dom樹之間附加了一層,這層稱為內容接收器,相當製造dom元素的工廠。下面將討論流程中的各個階段。

  三、解析與DOM樹構建(Parsing and DOM tree construction)

  解析(Parsing-general)

  既然解析是渲染引擎中一個非常重要的過程,我們將稍微深入的研究它。首先簡要介紹一下解析。

  解析一個文件即將其轉換為具有一定意義的結構——編碼可以理解和使用的東西。解析的結果通常是表達文件結構的節點樹,稱為解析樹或語法樹。

  例如,解析“2+3-1”這個表示式,可能返回這樣一棵樹。

圖5:數學表示式樹節點

  文法(Grammars)

  解析基於文件依據的語法規則——文件的語言或格式。每種可被解析的格式必須具有由詞彙及語法規則組成的特定的文法,稱為上下文無關文法。人類語言不具有這一特性,因此不能被一般的解析技術所解析。

  解析器-詞法分析器(Parser-Lexer combination)

  解析可以分為兩個子過程——語法分析及詞法分析

  詞法分析就是將輸入分解為符號,符號是語言的詞彙表——基本有效單元的集合。對於人類語言來說,它相當於我們字典中出現的所有單詞。

  語法分析指對語言應用語法規則。

  解析器一般將工作分配給兩個元件——詞法分析器(有時也叫分詞器)負責將輸入分解為合法的符號,解析器則根據語言的語法規則分析文件結構,從而構建解析樹,詞法分析器知道怎麼跳過空白和換行之類的無關字元。

圖6:從源文件到解析樹

  解析過程是迭代的,解析器從詞法分析器處取到一個新的符號,並試著用這個符號匹配一條語法規則,如果匹配了一條規則,這個符號對應的節點將被新增到解析樹上,然後解析器請求另一個符號。如果沒有匹配到規則,解析器將在內部儲存該符號,並從詞法分析器取下一個符號,直到所有內部儲存的符號能夠匹配一項語法規則。如果最終沒有找到匹配的規則,解析器將丟擲一個異常,這意味著文件無效或是包含語法錯誤。

  轉換(Translation)

  很多時候,解析樹並不是最終結果。解析一般在轉換中使用——將輸入文件轉換為另一種格式。編譯就是個例子,編譯器在將一段原始碼編譯為機器碼的時候,先將原始碼解析為解析樹,然後將該樹轉換為一個機器碼文件。

圖7:編譯流程

  解析例項Parsing example

  圖5中,我們從一個數學表示式構建了一個解析樹,這裡定義一個簡單的數學語言來看下解析過程。

  詞彙表:我們的語言包括整數、加號及減號。

  語法:

  1. 該語言的語法基本單元包括表示式、term及操作符

  2. 該語言可以包括多個表示式

  3. 一個表示式定義為兩個term通過一個操作符連線

  4. 操作符可以是加號或減號

  5. term可以是一個整數或一個表示式

  現在來分析一下“2+3-1”這個輸入

  第一個匹配規則的子字串是“2”,根據規則5,它是一個term,第二個匹配的是“2+3”,它符合第2條規則——一個操作符連線兩個term,下一次匹配發生在輸入的結束處。“2+3-1”是一個表示式,因為我們已經知道“2+3”是一個term,所以我們有了一個term緊跟著一個操作符及另一個term。“2++”將不會匹配任何規則,因此是一個無效輸入。

  詞彙表及語法的定義

  詞彙表通常利用正則表示式來定義。

  例如上面的語言可以定義為:

  INTEGER:0|[1-9][0-9]*

  PLUS:+

  MINUS:-

  正如看到的,這裡用正則表示式定義整數。

  語法通常用BNF格式定義,我們的語言可以定義為:

  expression := term operation term

  operation := PLUS | MINUS

  term := INTEGER | expression

  解析器型別(Types of parsers)

  有兩種基本的解析器——自頂向下解析及自底向上解析。比較直觀的解釋是,自頂向下解析,檢視語法的最高層結構並試著匹配其中一個;自底向上解析則從輸入開始,逐步將其轉換為語法規則,從底層規則開始直到匹配高層規則。

  來看一下這兩種解析器如何解析上面的例子:

  自頂向下解析器從最高層規則開始——它先識別出“2+3“,將其視為一個表示式,然後識別出”2+3-1“為一個表示式(識別表示式的過程中匹配了其他規則,但出發點是最高層規則)。

  自底向上解析會掃描輸入直到匹配了一條規則,然後用該規則取代匹配的輸入,直到解析完所有輸入。部分匹配的表示式被放置在解析堆疊中。

Stack

Input

2 + 3 – 1

term

+ 3 - 1

term operation

3 – 1

expression

- 1

expression operation

1

expression

  自底向上解析器稱為shift reduce解析器,因為輸入向右移動(想象一個指標首先指向輸入開始處,並向右移動),並逐漸簡化為語法規則。

  自動化解析(Generating parsers automatically)

  解析器生成器這個工具可以自動生成解析器,只需要指定語言的文法——詞彙表及語法規則,它就可以生成一個解析器。建立一個解析器需要對解析有深入的理解,而且手動的建立一個由較好效能的解析器並不容易,所以解析生成器很有用。Webkit使用兩個知名的解析生成器——用於建立語法分析器的Flex及建立解析器的Bison(你可能接觸過Lex和Yacc)。Flex的輸入是一個包含了符號定義的正則表示式,Bison的輸入是用BNF格式表示的語法規則。

  HTML解析器(HTML Parser)

  HTML解析器的工作是將html標識解析為解析樹。

  HTML文法定義(The HTML grammar definition)

  W3C組織制定規範定義了HTML的詞彙表和語法。

  非上下文無關文法(Not a context free grammar)

  正如在解析簡介中提到的,上下文無關文法的語法可以用類似BNF的格式來定義。

  不幸的是,所有的傳統解析方式都不適用於html(當然我提出它們並不只是因為好玩,它們將用來解析css和js),html不能簡單的用解析所需的上下文無關文法來定義。

  Html有一個正式的格式定義——DTD(Document Type Definition文件型別定義)——但它並不是上下文無關文法,html更接近於xml,現在有很多可用的xml解析器,html有個xml的變體——xhtml,它們間的不同在於,html更寬容,它允許忽略一些特定標籤,有時可以省略開始或結束標籤。總的來說,它是一種soft語法,不像xml呆板、固執。

  顯然,這個看起來很小的差異卻帶來了很大的不同。一方面,這是html流行的原因——它的寬容使web開發人員的工作更加輕鬆,但另一方面,這也使很難去寫一個格式化的文法。所以,html的解析並不簡單,它既不能用傳統的解析器解析,也不能用xml解析器解析。

  HTML DTD

  Html適用DTD格式進行定義,這一格式是用於定義SGML家族的語言,包括了對所有允許元素及它們的屬性和層次關係的定義。正如前面提到的,html DTD並沒有生成一種上下文無關文法。

  DTD有一些變種,標準模式只遵守規範,而其他模式則包含了對瀏覽器過去所使用標籤的支援,這麼做是為了相容以前內容。最新的標準DTD在http://www.w3.org/TR/html4/strict.dtd

  DOM

  輸出的樹,也就是解析樹,是由DOM元素及屬性節點組成的。DOM是文件物件模型的縮寫,它是html文件的物件表示,作為html元素的外部介面供js等呼叫。

  樹的根是“document”物件。

  DOM和標籤基本是一一對應的關係,例如,如下的標籤:

<html>
<body>
<p>
Hello DOM
</p>
<div><img src=”example.png” /></div>
</body>
</html>

  將會被轉換為下面的DOM樹:

圖8:示例標籤對應的DOM樹

  這裡所謂的樹包含了DOM節點是說樹是由實現了DOM介面的元素構建而成的,瀏覽器使用已被瀏覽器內部使用的其他屬性的具體實現。

  解析演算法(The parsing algorithm)

  正如前面章節中討論的,hmtl不能被一般的自頂向下或自底向上的解析器所解析。

  原因是:

  1. 這門語言本身的寬容特性

  2. 瀏覽器對一些常見的非法html有容錯機制

  3. 解析過程是往復的,通常原始碼不會在解析過程中發生改變,但在html中,指令碼標籤包含的“document.write”可能新增標籤,這說明在解析過程中實際上修改了輸入。

  不能使用正則解析技術,瀏覽器為html定製了專屬的解析器。

  Html5規範中描述了這個解析演算法,演算法包括兩個階段——符號化及構建樹。

  符號化是詞法分析的過程,將輸入解析為符號,html的符號包括開始標籤、結束標籤、屬性名及屬性值。

  符號識別器識別出符號後,將其傳遞給樹構建器,並讀取下一個字元,以識別下一個符號,這樣直到處理完所有輸入。

圖9:HTML解析流程

  符號識別演算法(The tokenization algorithm)

  演算法輸出html符號,該演算法用狀態機表示。每次讀取輸入流中的一個或多個字元,並根據這些字元轉移到下一個狀態,當前的符號狀態及構建樹狀態共同影響結果,這意味著,讀取同樣的字元,可能因為當前狀態的不同,得到不同的結果以進入下一個正確的狀態。

  這個演算法很複雜,這裡用一個簡單的例子來解釋這個原理。

  基本示例——符號化下面的html:

<html>
<body>
Hello world
</body>
</html>

  初始狀態為“Data State”,當遇到“<”字元,狀態變為“Tag open state”,讀取一個a-z的字元將產生一個開始標籤符號,狀態相應變為“Tag name state”,一直保持這個狀態直到讀取到“>”,每個字元都附加到這個符號名上,例子中建立的是一個html符號。

  當讀取到“>”,當前的符號就完成了,此時,狀態回到“Data state”,“<body>”重複這一處理過程。到這裡,html和body標籤都識別出來了。現在,回到“Data state”,讀取“Hello world”中的字元“H”將建立並識別出一個字元符號,這裡會為“Hello world”中的每個字元生成一個字元符號。

  這樣直到遇到“</body>”中的“<”。現在,又回到了“Tag open state”,讀取下一個字元“/”將建立一個閉合標籤符號,並且狀態轉移到“Tag name state”,還是保持這一狀態,直到遇到“>”。然後,產生一個新的標籤符號並回到“Data state”。後面的“</html>”將和“</body>”一樣處理。

圖10:符號化示例輸入

  樹的構建演算法(Tree construction algorithm)

  在樹的構建階段,將修改以Document為根的DOM樹,將元素附加到樹上。每個由符號識別器識別生成的節點將會被樹構造器進行處理,規範中定義了每個符號相對應的Dom元素,對應的Dom元素將會被建立。這些元素除了會被新增到Dom樹上,還將被新增到開放元素堆疊中。這個堆疊用來糾正巢狀的未匹配和未閉合標籤,這個演算法也是用狀態機來描述,所有的狀態採用插入模式。

  來看一下示例中樹的建立過程:

<html>

相關推薦

前端必讀瀏覽器內部工作原理

 目錄   一、介紹   二、渲染引擎   三、解析與DOM樹構建   四、渲染樹構建   五、佈局   六、繪製   七、動態變化   八、渲染引擎的執行緒   九、CSS2可視模型   一、介紹   瀏覽器可以被認為是使用最廣

瀏覽器渲染原理及解剖瀏覽器內部工作原理

1、簡單地說,頁面渲染就是瀏覽器將html程式碼根據CSS定義的規則顯示在瀏覽器視窗中的這個過程。先來大致瞭解一下瀏覽器都是怎麼工作的:   1. 使用者輸入網址(假設是個html頁面,並且是第一次訪問),瀏覽器向伺服器發出請求,伺服器返回html檔案;   2.

瀏覽器內部工作原理

  目錄   一、介紹   二、渲染引擎   三、解析與DOM樹構建   四、渲染樹構建   五、佈局   六、繪製   七、動態變化   八、渲染引擎的執行緒   九、CSS2可視模型   一、介紹   瀏覽器可以被認為是使用最廣泛的軟體,本文將介紹瀏覽器的工作原理,我們將看到,從你在位址列輸入goog

Docker(二)理解容器編排工具Kubernetes內部工作原理

一、Kubernetes是什麼   要說到Docker就不得不說說Kubernetes。當Docker容器在微服務的環境下數量一多,那麼統一的,自動化的管理自然少不了。而Kubernetes就是一個這樣的工具,它不僅僅提供了健康檢查和自修復,還有自動擴容縮容,以及服務發現和負載均衡等等功能。總的來說它使我們對

ArcGIS教程“流向”的工作原理

http wid distance 附近 ack post str 教程 處的   獲取表面的水文特征的關鍵之中的一個是可以確定從柵格中的每一個像元流出的方向。這可通過流向工具來完畢。   該工具把表面作為輸入,然後輸出一個顯示從每一個像元流出方向的

HTTPS協議詳解(二)TLS/SSL工作原理

-c 基本 公鑰加密 工作方式 通信 使用 sha2 公開 原理 HTTPS協議的主要功能基本都依賴於TLS/SSL協議,本節分析TLS/SSL協議工作原理。 TLS/SSL的功能實現主要依賴於三類基本算法:散列函數 Hash、對稱加密和非對稱加密,其利用非對稱加密實

8. 理解ZooKeeper的內部工作原理

zab 階段 身份驗證 過多 管理系統 多個 基礎 des jpg 到目前為止,我們已經討論了ZooKeeper服務的基礎知識,並詳細了解了數據模型及其屬性。 我們也熟悉了ZooKeeper 監視(watch)的概念,監視就是在ZooKeeper命名空間中的znode發生任

分享知識-快樂自己Struts2框架 工作原理及執行流程圖(攔截器的使用)

Struts2 架構圖: 1):提交請求 客戶端通過 HttpServletRequest 向 Servlet (即Tomcat)提交一個請求。 請求經過一系列的過濾器,例如圖中的 ActionContextCleanUp 和 Other filer (SlterMesh,etc)等,最後被 Str

很棒的開源監控系統原理系列文章UAV MOF工作原理之Agent注入機制原理

原文連結:https://mp.weixin.qq.com/s/eA6nuYPVvgoCWO4E3yP4BQ 也可關注公眾號:UAVStack智慧運維 大家好,UAVStack推送時間到~ 上月我們為大家介紹了UAVStack中的呼叫鏈技術,助力大家進行問題診斷和系統性能提升,希望大家有

Spark學習筆記DStream基本工作原理

DStream基本工作原理 DStream是Spark Streaming提供的一種高階抽象,英文全稱為Discretized Stream,中文翻譯為離散流,它代表了一個持續不斷的資料流。DStream可以通過輸入資料來源(比如從Flume、Kafka中)來建立,也可以通

SSD背後的祕密SSD基本工作原理

SSD主要由SSD控制器,FLASH儲存陣列,板上DRAM(可選),以及跟HOST介面(諸如SATA,SAS, PCIe等)組成。 SSD主控通過若干個通道(channel)並行操作多塊FLASH顆粒,類似RAID0,大大提高底層的頻寬。舉個例子,假設主控與FLASH顆

Filter對Request的改變HttpServletRequestWrapper的工作原理

8)Filter對Request的改變:HttpServletRequestWrapper的工作原理 馬 克-to-win:有了HttpServletResponseWrapper的基礎,就好理解HttpServletRequestWrapper了。 無疑它就是想在Request到達伺服器之前,先把

Filter對Response的改變HttpServletResponseWrapper的工作原理

7)Filter對Response的改變:HttpServletResponseWrapper的工作原理 馬 克-to-win:前面我們講的知識,主要說的是由於Filter的參與,使用者的訪問路徑被改變的問題。底下我們就要講一點更難的話題,就是Filter 如何改變一個現有的html。比如我寫的新浪

大資料面試部分MapReduce的工作原理

3.講述一下mapreduce的流程(shuffle的sort,partitions,group) 首先是 Mapreduce經過SplitInput 輸入分片 決定map的個數在用Record記錄 key value。然後分為以下三個流程: Map: 輸入  key(

[聊天機器人]開源ChatterBot工作原理

作者:鄒祁峰 郵箱:[email protected] 部落格:http://blog.csdn.net/qifengzou 日期:2017.08.12 18:35 轉載請註明來自"祁峰"的CSDN部落格 1 引言 ChatterBot

Struts學習筆記Struts Framework工作原理

首先說一下Framework的概念:人們用於解決相同或者相似型別問題的方案 特點:可重用行,可擴充套件性,可收縮性 基於請求響應模式的應用framework的邏輯結構: 1,控制層; 2,業務邏輯層; 3,資料邏輯層 Struts的概念和體系結構: *    主要採用se

HBase學習總結(4)HBase的工作原理

一、切分和分配大表 HBase中的表是由行和列組成的。HBase中的表可能達到數十億行和數百萬列。每個表的大小可能達到TB級,有時甚至PB級。這些表會切分成小一點兒的資料單位,然後分配到多臺伺服器上。

Flask原始碼分析二路由內部實現原理

前言 Flask是目前為止我最喜歡的一個Python Web框架了,為了更好的掌握其內部實現機制,這兩天準備學習下Flask的原始碼,將由淺入深跟大家分享下,其中Flask版本為1.1.1。 上次瞭解了Flask服務的啟動流程,今天我們來看下路由的內部實現機理。 Flask系列文章: Flask開發初探 F

深入理解JS中的物件(二)new 的工作原理

**目錄** - 序言 - 不同返回值的建構函式 - 深入 new 呼叫函式原理 - 總結 - 參考 **1.序言** 在 [深入理解JS中的物件(一):原型、原型鏈和建構函式](https://www.cnblogs.com/forcheng/p/12866827.html) 中,我們分析了JS中

五分鐘瞭解瀏覽器工作原理

Web 瀏覽器無疑是使用者訪問網際網路最常見的入口。瀏覽器憑藉其免安裝和跨平臺等優勢,逐漸取代了很多傳統的富客戶端。 Web 瀏覽器通過向 URL 傳送網路請求來訪問 Web 伺服器資源,並以互動性的方式展示這些內容。基本操作包括獲取、處理、顯示和儲存。常見的瀏覽器包括 Internet Explorer、