這是我參與8月更文挑戰的第2天,活動詳情查看:8月更文挑戰html
瀏覽器的主要功能就是向服務器發出請求,在瀏覽器窗口中展現您選擇的網絡資源。這裏所說的資源通常是指 HTML 文檔,也能夠是 PDF、圖片或其餘的類型。資源的位置由用戶使用 URI(統一資源標示符)指定。html5
瀏覽器解釋並顯示 HTML 文件的方式是在 HTML 和 CSS 規範中指定的。這些規範由網絡標準化組織 W3C(萬維網聯盟)進行維護。web
瀏覽器的主要組件爲 (1.1):數據庫
圖:瀏覽器的主要組件。後端
值得注意的是,和大多數瀏覽器不一樣,Chrome 瀏覽器的每一個標籤頁都分別對應一個渲染引擎實例。每一個標籤頁都是一個獨立的進程。瀏覽器
渲染引擎的做用嘛...固然就是「渲染」了,也就是在瀏覽器的屏幕上顯示請求的內容。服務器
默認狀況下,渲染引擎可顯示 HTML 和 XML 文檔與圖片。經過插件(或瀏覽器擴展程序),還能夠顯示其餘類型的內容;例如,使用 PDF 查看器插件就能顯示 PDF 文檔。可是在本章中只介紹其主要用途:顯示使用 CSS 格式化的 HTML 內容和圖片。markdown
呈現引擎一開始會從網絡層獲取請求文檔的內容,內容的大小通常限制在 8000 個塊之內。網絡
而後進行以下所示的基本流程:框架
圖:呈現引擎的基本流程。
呈現引擎將開始解析 HTML 文檔,並將各標記逐個轉化成「內容樹」上的 DOM 節點。同時也會解析外部 CSS 文件以及樣式元素中的樣式數據。HTML 中這些帶有視覺指令的樣式信息將用於建立另外一個樹結構:渲染樹。
渲染樹包含多個帶有視覺屬性(如顏色和尺寸)的矩形。這些矩形的排列順序就是它們將在屏幕上顯示的順序。
渲染樹構建完畢以後,進入「佈局」處理階段,也就是爲每一個節點分配一個應出如今屏幕上的確切座標。下一個階段是繪製 - 渲染引擎會遍歷渲染樹,由用戶界面後端層將每一個節點繪製出來。
須要着重指出的是,這是一個漸進的過程。爲達到更好的用戶體驗,渲染引擎會力求儘快將內容顯示在屏幕上。它沒必要等到整個 HTML 文檔解析完畢以後,就會開始構建呈現樹和設置佈局。在不斷接收和處理來自網絡的其他內容的同時,渲染引擎會將部份內容解析並顯示出來。
圖:WebKit 主流程
圖:Mozilla 的 Gecko 呈現引擎主流程 (3.6)
從圖 3 和圖 4 能夠看出,雖然 WebKit 和 Gecko 使用的術語略有不一樣,但總體流程是基本相同的。
Gecko 將視覺格式化元素組成的樹稱爲「框架樹」。每一個元素都是一個框架。WebKit 使用的術語是「呈現樹」,它由「呈現對象」組成。對於元素的放置,WebKit 使用的術語是「佈局」,而 Gecko 稱之爲「重排」。對於鏈接 DOM 節點和可視化信息從而建立呈現樹的過程,WebKit 使用的術語是「附加」。有一個細微的非語義差異,就是 Gecko 在 HTML 與 DOM 樹之間還有一個稱爲「內容槽」的層,用於生成 DOM 元素。咱們會逐一論述流程中的每一部分:
解析文檔是指將文檔轉化成爲有意義的結構,也就是可以讓代碼理解和使用的結構。解析獲得的結果一般是表明了文檔結構的節點樹,它稱做解析樹或者語法樹。是渲染引擎中很是重要的一個環節。
解析的過程能夠分紅兩個子過程:詞法分析和語法分析。
詞法分析是將輸入內容分割成大量標記
的過程。標記是語言中的詞彙,即構成內容的單位。在人類語言中,它至關於語言字典中的單詞。
語法分析是應用語言的語法規則
的過程。
解析器一般將解析工做分給如下兩個組件來處理:詞法分析器(有時也稱爲標記生成器),負責將輸入內容分解成一個個有效標記;而解析器負責根據語言的語法規則分析文檔的結構,從而構建解析樹。
HTML 解析器的任務是將 HTML 標記解析成解析樹。
HTML 的定義採用了 DTD 格式。此格式可用於定義 SGML 族的語言。它包括全部容許使用的元素及其屬性和層次結構的定義。
DTD 存在一些變體。嚴格模式徹底遵照 HTML 規範,而混雜模式可支持之前的瀏覽器所使用的標記。這樣作的目的是確保向下兼容一些早期版本的內容。最新的嚴格模式 DTD 能夠在這裏找到:www.w3.org/TR/html4/st…
解析器的輸出「解析樹」是由 DOM 元素和屬性節點構成的樹結構。DOM 是文檔對象模型 (Document Object Model) 的縮寫。它是 HTML 文檔的對象表示,同時也是外部內容(例如 JavaScript)與 HTML 元素之間的接口。
解析樹的根節點是「Document」對象。
和 HTML 不一樣,CSS 是上下文無關的語法,可使用解析器進行解析。事實上,CSS 規範定義了 CSS 的詞法和語法。
網絡的模型是同步的。網頁做者但願解析器遇到
在執行腳本時,其餘線程會解析文檔的其他部分,找出並加載須要經過網絡加載的其餘資源。經過這種方式,資源能夠在並行鏈接上加載,從而提升整體速度。請注意,預解析器不會修改 DOM 樹,而是將這項工做交由主解析器處理;預解析器只會解析外部資源(例如外部腳本、樣式表和圖片)的引用。
理論上來講,應用樣式表不會更改 DOM 樹,所以彷佛沒有必要等待樣式表並中止文檔解析。但這涉及到一個問題,就是腳本在文檔解析階段會請求樣式信息。若是當時尚未加載和解析樣式,腳本就會得到錯誤的回覆,這樣顯然會產生不少問題。Firefox 在樣式表加載和解析的過程當中,會禁止全部腳本。而對於 WebKit 而言,僅當腳本嘗試訪問的樣式屬性可能受還沒有加載的樣式表影響時,它纔會禁止該腳本。
在 DOM 樹構建的同時,瀏覽器還會構建另外一個樹結構:渲染樹
。這是由可視化元素按照其顯示順序而組成的樹,也是文檔的可視化表示。它的做用是按照正確的順序繪製內容。
渲染器是和 DOM 元素相對應的,但並不是一一對應。非可視化的 DOM 元素不會插入渲染樹中,例如「head」元素。若是元素的 display 屬性值爲「none」,那麼也不會顯示在渲染樹中(可是 visibility 屬性值爲「hidden」的元素仍會顯示)。
處理 html 和 body 標記就會構建渲染樹根節點。這個根節點渲染對象對應於 CSS 規範中所說的容器 block,這是最上層的 block,包含了其餘全部 block。它的尺寸就是視口,即瀏覽器窗口顯示區域的尺寸。這就是文檔所指向的渲染對象。渲染樹的其他部分以 DOM 樹節點插入的形式來構建。
構建渲染樹時,須要計算每個渲染對象的可視化屬性。這是經過計算每一個元素的樣式屬性來完成的。
樣式上下文可分割成多個結構。這些結構體包含了特定類別(如 border 或 color)的樣式信息。
在計算某個特定元素的樣式上下文時,咱們首先計算規則樹中的對應路徑,或者使用現有的路徑。而後咱們沿此路徑應用規則,在新的樣式上下文中填充結構。咱們從路徑中擁有最高優先級的底層節點(一般也是最特殊的選擇器)開始,並向上遍歷規則樹,直到結構填充完畢。
渲染器在建立完成並添加到渲染樹時,並不包含位置和大小信息。計算這些值的過程稱爲佈局或重排
。
HTML 採用基於流的佈局模型,這意味着大多數狀況下只要一次遍歷就能計算出幾何信息。處於流中靠後位置元素一般不會影響靠前位置元素的幾何特徵,所以佈局能夠按從左至右、從上至下的順序遍歷文檔。
座標系是相對於根框架而創建的,使用的是上座標和左座標。
佈局是一個遞歸的過程。它從根渲染器(對應於 HTML 文檔的 <html>
元素)開始,而後遞歸遍歷部分或全部的框架層次結構,爲每個須要計算的呈現器計算幾何信息。
根呈現器的位置左邊是 0,0,其尺寸爲視口(也就是瀏覽器窗口的可見區域)。
在繪製階段,系統會遍歷渲染樹,並調用呈現器的「paint」方法,將渲染器的內容顯示在屏幕上。繪製工做是使用用戶界面基礎組件完成的。
在發生變化時,瀏覽器會盡量作出最小的響應。所以,元素的顏色改變後,只會對該元素進行重繪。元素的位置改變後,只會對該元素及其子元素(可能還有同級元素)進行佈局和重繪。