渲染引擎
渲染引擎的職責是……渲染,也就是把請求的內容顯示到瀏覽器屏幕上。
默認情況下渲染引擎可以顯示HTML,XML文檔以及圖片。 通過插件(瀏覽器擴展)它可以顯示其它類型文檔。比如使用PDF viewer插件顯示PDF文件。我們會在一個專門的章節討論插件與擴展。在這一節我們將專注渲染引擎的主要用途——顯示用CSS格式化的HTML與圖片。
各種渲染引擎
我們提到的Firefox, Safari兩種瀏覽器構建於兩種渲染引擎之上:Firefox使用Gecko —— Mozilla自家的渲染引擎;Safari 和 Chrome 都使用 Webkit。
Webkit 是一個開源的渲染引擎,它源自Linux平臺上的一個引擎,經過Apple公司的修改可以支持Mac與Windows平臺。更多信息可以參考: https://webkit.org/ 。
主要流程
渲染引擎開始於從網絡層獲取請求內容,一般是不超過8K的數據塊。接下來就是渲染引擎的基本工作流程:
圖 2:渲染引擎的基本工作流程(解析HTML構建DOM樹,渲染樹構建,渲染樹布局,繪製渲染樹)。
渲染引擎會解析HTML文檔並把標籤轉換成內容樹中的DOM節點。它會解析style元素和外部文件中的樣式數據。樣式數據和HTML中的顯示控制將共同用來創建另一棵樹——渲染樹。
渲染樹包含帶有顏色,尺寸等顯示屬性的矩形。這些矩形的順序與顯示順序一致。
渲染樹構建完成後就是"布局"處理,也就是確定每個節點在屏幕上的確切顯示位置。 下一個步驟是 繪製 —— 遍歷渲染樹並用UI後端層將每一個節點繪製出來。
一定要理解這是一個緩慢的過程,為了更好的用戶體驗,渲染引擎會嘗試儘快的把內容顯示出來。它不會等到所有HTML都被解析完才創建並布局渲染樹。它會 在處理後續內容的同時把處理過的局部內容先展示出來。
主要流程示例
圖 3:Webkit主要流程
圖 4:Mozilla的Gecko渲染引擎主要流程(3.6)
從圖3和圖4中可以看出,儘管Webkit與Gecko使用略微不同的術語,這個過程還是基本相同的。
Gecko 裡把格式化好的可視元素稱做"幀樹"(Frame tree)。每個元素就是一個幀(frame)。 Webkit 則使用"渲染樹"這個術語,渲染樹由"渲染對象"組成。Webkit 裡使用"layout"表示元素的布局,Gecko則稱為"Reflow"。Webkit使用"Attachment"來連接DOM節點與可視化信息以構建渲染樹。一個非語義上的小差別是Gecko在HTML與DOM樹之間有一個附加的層 ,稱作"content sink",是創建DOM對象的工廠。我們會討論流程中的每一部分。
解析
因為解析是渲染引擎中一個很重要的處理,我們會講的略深入一些。讓我們從一個小的解析介紹開始。
解析一個文檔意味著把它翻譯成有意義的結構以供代碼使用。解析的結果通常是一個表徵文檔的由節點組成的樹,稱為解析樹或句法樹。
示例——解析表達式"2 + 3 – 1″可以返回下面的樹:
圖 5:數學表達式樹節點
語法
解析是基於文檔所遵循的語法規則——書寫所用的語言或格式——來進行的。每一種可以解析的格式必須由確定的語法與詞彙組成。這被稱之為上下文無關語法。 人類語言並非此種語言,所以不能用常規的解析技術來解析。
解析器——詞法分析器組合
解析器有兩個處理過程——詞法分析與句法分析。
詞法分析負責把輸入切分成符號序列,符號是語言的詞彙——由該語言所有合法的單詞組成。
句法分析是對該語言句法法則的應用。
解析器通常把工作分給兩個組件——分詞程序負責把輸入切分成合法符號序列,解析程序負責按照句法規則分析文檔結構和構建句法樹。詞法分析器知道如何過濾像空格,換行之類的無關字符。
圖 6:從源文檔到解析樹(文檔,詞法分析,句法分析,解析樹)。
解析過程是交互式的。解析器通常會從詞法分析器獲取新符號並嘗試匹配句法規則。如果匹配成功,就在句法樹上創建相應的節點,並繼續從詞法分析器獲取下一個符號。如果沒有匹配的規則,解析器會內部保存這個符號,並繼續從詞法分析器獲取符號,直到內部保存的所有符號能夠成功匹配一個規則。如果最終無法匹配,解析器會拋出異常。這意味著文檔無效,含有句法錯誤。
轉換
多數情況下解析樹並非最終結果。解析經常是為了從輸入文檔轉換成另外一種格式。比如編譯器要把源碼編譯成機器碼,會首先解析成解析樹,再把解析樹轉換成機器碼。
圖 7:編譯過程(源碼,解析,解析樹,轉換,機器碼)。