溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

瀏覽器解析渲染HTML文檔的過程是什么

發(fā)布時間:2020-12-02 11:28:00 來源:億速云 閱讀:428 作者:小新 欄目:web開發(fā)

小編給大家分享一下瀏覽器解析渲染HTML文檔的過程是什么,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!

瀏覽器的工作原理

一、瀏覽器的高層結構

瀏覽器的主要組件為:

1、用戶界面 - 包括地址欄、前進/后退按鈕、書簽菜單等。除了瀏覽器主窗口顯示的您請求的頁面外,其他顯示的各個部分都屬于用戶界面。

2、瀏覽器引擎 - 在用戶界面和呈現(xiàn)引擎之間傳送指令。

3、呈現(xiàn)引擎 - 負責顯示請求的內(nèi)容。如果請求的內(nèi)容是 HTML,它就負責解析 HTML 和 CSS 內(nèi)容,并將解析后的內(nèi)容顯示在屏幕上。

4、網(wǎng)絡 - 用于網(wǎng)絡調(diào)用,比如 HTTP 請求。其接口與平臺無關,并為所有平臺提供底層實現(xiàn)。

5、用戶界面后端 - 用于繪制基本的窗口小部件,比如組合框和窗口。其公開了與平臺無關的通用接口,而在底層使用操作系統(tǒng)的用戶界面方法。

6、JavaScript 解釋器。用于解析和執(zhí)行 JavaScript 代碼。

7、數(shù)據(jù)存儲。這是持久層。瀏覽器需要在硬盤上保存各種數(shù)據(jù),例如 Cookie。新的 HTML 規(guī)范 (HTML5) 定義了“網(wǎng)絡數(shù)據(jù)庫”,這是一個完整(但是輕便)的瀏覽器內(nèi)數(shù)據(jù)庫。

瀏覽器解析渲染HTML文檔的過程是什么

值得注意的是,和大多數(shù)瀏覽器不同,Chrome 瀏覽器的每個標簽頁都分別對應一個呈現(xiàn)引擎實例。每個標簽頁都是一個獨立的進程。

二、主流程

呈現(xiàn)引擎一開始會從網(wǎng)絡層獲取請求文檔的內(nèi)容,內(nèi)容的大小一般限制在 8000 個塊以內(nèi)。

然后進行如下所示的基本流程:

瀏覽器解析渲染HTML文檔的過程是什么

呈現(xiàn)引擎將開始解析 HTML 文檔,并將各標記逐個轉化成“內(nèi)容樹”上的 DOM 節(jié)點。同時也會解析外部 CSS 文件以及樣式元素中的樣式數(shù)據(jù)。HTML 中這些帶有視覺指令的樣式信息將用于創(chuàng)建另一個樹結構:呈現(xiàn)樹。

呈現(xiàn)樹包含多個帶有視覺屬性(如顏色和尺寸)的矩形。這些矩形的排列順序就是它們將在屏幕上顯示的順序。

呈現(xiàn)樹構建完畢之后,進入“布局”處理階段,也就是為每個節(jié)點分配一個應出現(xiàn)在屏幕上的確切坐標。下一個階段是繪制 - 呈現(xiàn)引擎會遍歷呈現(xiàn)樹,由用戶界面后端層將每個節(jié)點繪制出來。

需要著重指出的是,這是一個漸進的過程。為達到更好的用戶體驗,呈現(xiàn)引擎會力求盡快將內(nèi)容顯示在屏幕上。它不必等到整個 HTML 文檔解析完畢之后,就會開始構建呈現(xiàn)樹和設置布局。在不斷接收和處理來自網(wǎng)絡的其余內(nèi)容的同時,呈現(xiàn)引擎會將部分內(nèi)容解析并顯示出來。

主流程示例:

瀏覽器解析渲染HTML文檔的過程是什么

三、處理腳本和樣式表的順序

1、腳本

網(wǎng)絡的模型是同步的。網(wǎng)頁作者希望解析器遇到 <script> 標記時立即解析并執(zhí)行腳本。文檔的解析將停止,直到腳本執(zhí)行完畢。如果腳本是外部的,那么解析過程會停止,直到從網(wǎng)絡同步抓取資源完成后再繼續(xù)。此模型已經(jīng)使用了多年,也在 HTML4 和 HTML5 規(guī)范中進行了指定。作者也可以將腳本標注為“defer”,這樣它就不會停止文檔解析,而是等到解析結束才執(zhí)行。HTML5 增加了一個選項,可將腳本標記為異步,以便由其他線程解析和執(zhí)行。

2、預解析

WebKit 和 Firefox 都進行了這項優(yōu)化。在執(zhí)行腳本時,其他線程會解析文檔的其余部分,找出并加載需要通過網(wǎng)絡加載的其他資源。通過這種方式,資源可以在并行連接上加載,從而提高總體速度。請注意,預解析器不會修改 DOM 樹,而是將這項工作交由主解析器處理;預解析器只會解析外部資源(例如外部腳本、樣式表和圖片)的引用。

3、樣式表

另一方面,樣式表有著不同的模型。理論上來說,應用樣式表不會更改 DOM 樹,因此似乎沒有必要等待樣式表并停止文檔解析。但這涉及到一個問題,就是腳本在文檔解析階段會請求樣式信息。如果當時還沒有加載和解析樣式,腳本就會獲得錯誤的回復,這樣顯然會產(chǎn)生很多問題。這看上去是一個非典型案例,但事實上非常普遍。Firefox 在樣式表加載和解析的過程中,會禁止所有腳本。而對于 WebKit 而言,僅當腳本嘗試訪問的樣式屬性可能受尚未加載的樣式表影響時,它才會禁止該腳本。

4、呈現(xiàn)樹構建

在 DOM 樹構建的同時,瀏覽器還會構建另一個樹結構:呈現(xiàn)樹。這是由可視化元素按照其顯示順序而組成的樹,也是文檔的可視化表示。它的作用是讓您按照正確的順序繪制內(nèi)容。

Firefox 將呈現(xiàn)樹中的元素稱為“框架”。WebKit 使用的術語是呈現(xiàn)器或呈現(xiàn)對象。
呈現(xiàn)器知道如何布局并將自身及其子元素繪制出來。

四、布局

呈現(xiàn)器在創(chuàng)建完成并添加到呈現(xiàn)樹時,并不包含位置和大小信息。計算這些值的過程稱為布局或重排。

HTML 采用基于流的布局模型,這意味著大多數(shù)情況下只要一次遍歷就能計算出幾何信息。處于流中靠后位置元素通常不會影響靠前位置元素的幾何特征,因此布局可以按從左至右、從上至下的順序遍歷文檔。但是也有例外情況,比如 HTML 表格的計算就需要不止一次的遍歷。

坐標系是相對于根框架而建立的,使用的是上坐標和左坐標。

布局是一個遞歸的過程。它從根呈現(xiàn)器(對應于 HTML 文檔的 <html> 元素)開始,然后遞歸遍歷部分或所有的框架層次結構,為每一個需要計算的呈現(xiàn)器計算幾何信息。

根呈現(xiàn)器的位置左邊是 0,0,其尺寸為視口(也就是瀏覽器窗口的可見區(qū)域)。
所有的呈現(xiàn)器都有一個“l(fā)ayout”或者“reflow”方法,每一個呈現(xiàn)器都會調(diào)用其需要進行布局的子代的 layout 方法。

五、繪制

在繪制階段,系統(tǒng)會遍歷呈現(xiàn)樹,并調(diào)用呈現(xiàn)器的“paint”方法,將呈現(xiàn)器的內(nèi)容顯示在屏幕上。繪制工作是使用用戶界面基礎組件完成的。

個人理解總結

一、解析器與預解析機制

呈現(xiàn)引擎從網(wǎng)絡層獲取請求文檔的內(nèi)容,然后開始解析 HTML 文檔,并將各標記逐個轉化為 DOM樹(內(nèi)容樹)上的 DOM 節(jié)點,同時也會解析外部 CSS 文件以及樣式元素中的樣式數(shù)據(jù)。HTML 中這些帶有視覺指令的樣式信息將用于創(chuàng)建另一個樹結構:渲染樹(呈現(xiàn)樹)。呈現(xiàn)樹構建完畢之后,呈現(xiàn)引擎將對呈現(xiàn)樹進行布局和繪制。

呈現(xiàn)引擎 的解析包括 HTML 解析和 CSS 解析,HTML 解析器的輸出“解析樹”是由 DOM 元素和屬性節(jié)點構成的樹結構,DOM 是文檔對象模型 (Document Object Model) 的縮寫。它是 HTML 文檔的對象表示,同時也是外部內(nèi)容(例如 JavaScript)與 HTML 元素之間的接口。解析樹的根節(jié)點是“Document”對象。CSS 解析器會將 CSS 樣式文件和樣式元素中的樣式數(shù)據(jù)解析為 CSS 規(guī)則樹,瀏覽器結合 CSS 規(guī)則樹和 DOM 樹生成渲染樹。

JavaScript 解釋器 用于解析和執(zhí)行 JavaScript 代碼。

一般來講,我們認為瀏覽器從網(wǎng)絡層接收到 HTML 文檔內(nèi)容,然后開始解析文檔生成 DOM 樹,遇到 CSS 樣式表標簽或 JS 腳本標簽就起新線程去下載它們,并繼續(xù)構建 DOM 樹,瀏覽器根據(jù) DOM 樹構建渲染樹,最后瀏覽器將渲染書繪制到用戶界面。

在上述描述中,需要著重指出的是,HTML  文檔的解析和渲染是一個漸進的過程。為達到更好的用戶體驗,呈現(xiàn)引擎會力求盡快將內(nèi)容顯示在屏幕上。它不必等到整個 HTML 文檔解析完畢,就會開始構建呈現(xiàn)樹和設置布局。在不斷接收和處理來自網(wǎng)絡的其余內(nèi)容的同時,呈現(xiàn)引擎會將部分內(nèi)容解析并顯示出來。

瀏覽器的預解析。WebKit 和 Firefox 都進行了這項優(yōu)化。在執(zhí)行腳本時,其他線程會解析 HTML 文檔的其余部分,找出并加載需要通過網(wǎng)絡加載的其他資源。通過這種方式,資源可以在并行連接上加載,從而提高總體速度。請注意,預解析器不會修改 DOM 樹,而是將這項工作交由主解析器處理;預解析器只會解析外部資源(例如外部腳本、樣式表和圖片)的引用。

瀏覽器的預解析可以減緩渲染被阻塞的情況,例如文檔解析過程中預加載器發(fā)現(xiàn)了 <script src="last.js"></script> 標簽,會對 last.js 文件進行加載并放在瀏覽器緩存中,這樣當解析器遇到這個 <script> 標記時,由于預加載器已經(jīng)將 last.js 文件加載下來了,所以 last.js 會被立即執(zhí)行,不需要等待從網(wǎng)絡抓取資源,減緩了對渲染的阻塞。

二、CSS 和 JS 的處理順序和阻塞分析

HTML 文檔的解析和渲染過程中,外部樣式表和腳本 順序執(zhí)行、并發(fā)加載。

JS 腳本會阻塞 HTML 文檔的解析,包括 DOM 樹的構建和渲染樹的構建;CSS 樣式表會阻塞渲染樹的構建,但 DOM 樹依然繼續(xù)構建(除非遇到 script 標簽且 css 文件此時仍未加載完成),但不會渲染繪制到頁面上。

在 HTML 文檔的解析過程中,解析器遇到 <script> 標記時會立即解析并執(zhí)行腳本,HTML 文檔的解析將被阻塞,直到腳本執(zhí)行完畢。如果腳本是外部的,那么解析過程會停止,直到從網(wǎng)絡抓取資源并解析和執(zhí)行完成后,再繼續(xù)解析后續(xù)內(nèi)容。

理論上來說,應用樣式表不會更改 DOM 樹,因此似乎沒有必要等待樣式表并停止文檔解析。但這涉及到一個問題,就是腳本在文檔解析階段會請求樣式信息。如果當時還沒有加載和解析樣式,腳本就會獲得錯誤的回復,這樣顯然會產(chǎn)生很多問題。這看上去是一個非典型案例,但事實上非常普遍。Firefox 在樣式表加載和解析的過程中,會禁止所有腳本。而對于 WebKit 而言,僅當腳本嘗試訪問的樣式屬性可能受尚未加載的樣式表影響時,它才會禁止該腳本。

但無論是哪種情況導致的阻塞,該加載的外部資源還是會加載,例如外部腳本、樣式表和圖片。HTML 文檔的解析可能會被阻塞,但外部資源的加載不會被阻塞。

CSS 外部樣式表的加載會阻塞外部腳本的執(zhí)行,但并不會阻塞外部腳本的加載。這一點可以通過 chrome 調(diào)試工具中的 Network - Waterfall 進行驗證,但是需要注意 chrome 的并發(fā)連接數(shù)(同一域名)上限為 6 個。

瀏覽器解析渲染HTML文檔的過程是什么

瀏覽器解析渲染HTML文檔的過程是什么

由上面兩張截圖可以看到,jquery.min.js 腳本文件與 bootstrap.css 等樣式文件并行加載,但是由于 chrome 的并發(fā)連接數(shù)上限為 6 個,因此 bootstrap.min.js 腳本、xxx.css 樣式等文件的加載會等待前面的文件加載完成,有可用連接數(shù)的時候才開始加載。

瀏覽器解析渲染HTML文檔的過程是什么

了解以上信息之后,我們可以對該頁面進行相應優(yōu)化,例如對CSS文件進行壓縮處理、使用 CDN,將資源分布在多個域名下、合并 CSS 文件,減少 HTTP 請求數(shù)量等,來提高 CSS 的加載速度,減少 HTML 文檔解析和渲染的阻塞時間。

browser only allows six TCP connections per origin on HTTP 1.

瀏覽器的并發(fā)請求數(shù)目限制是針對同一域名的。因此可以使用 CDN 加速技術來提高用戶訪問網(wǎng)站的響應速度,這樣使用了 CDN 的資源加載不會占用當前域名下的并發(fā)連接數(shù),從而減少阻塞的時間。

網(wǎng)頁性能

了解 HTML 文檔的解析和渲染的過程對于分析網(wǎng)頁性能有著重要意義,它可以幫助我們找到影響網(wǎng)頁性能的關鍵因素。例如,我們知道 JS 外部腳本的執(zhí)行會阻塞文檔的解析,那么重量級的第三方插件則會影響首頁加載的速度,如果因此影響到了用戶體驗,我們就需要考慮這個第三方插件的使用成本是不是太高了,能否使用其他輕量級的插件進行替代,或者只使用其中一部分模塊。

以 Datatables 為例:

瀏覽器解析渲染HTML文檔的過程是什么

上圖是一個項目頁面的 Network 截圖,紅色框中的部分出現(xiàn)了約 700ms 左右的空白,我們需要知道為什么頁面的加載會出現(xiàn)這樣的情況,這段空白時間瀏覽器在干什么?

我們分析 Timeline 圖,看看瀏覽器在這段時間的具體信息,如下:

瀏覽器解析渲染HTML文檔的過程是什么

通過 Timeline 圖我們可以看到,在 250ms~900ms 時間區(qū)間內(nèi),瀏覽器在執(zhí)行 datatables.min.js 腳本代碼,這個腳本的執(zhí)行阻塞了文檔的解析,耗時約 700ms,對應了 Network 圖中的空白。

我們繼續(xù)查看頁面總的耗時時間,評估 700ms 耗時的影響,如下:

瀏覽器解析渲染HTML文檔的過程是什么

可以看到,頁面總的完成耗時為 1.66s,由此可知 datatables.min.js 的執(zhí)行耗時占了很大比重,應當慎重考慮是否一定要使用這個插件,能否使用其他輕量級的插件進行替代,或者能否精簡插件的不必要模塊,或者舍棄插件的使用。

參考資料-1
瀏覽器接收到html代碼,可能是一份完整的文檔,也可能是一個chunk,即開始解析。解析過程是先構建dom樹,再根據(jù)dom樹構建渲染樹,最后瀏覽器將渲染樹繪制到頁面上。
構建dom樹的過程即根據(jù)html代碼自上而下進行構建,當遇到script文件加載/執(zhí)行會阻塞后面dom樹的構建(javascript可能會改變dom樹),而遇到css文件則會阻塞渲染樹的構建,即dom樹依然繼續(xù)構建(除非遇到script標簽并且css文件依舊未加載完成),但不會渲染繪制到頁面上。而無論哪個阻塞,該加載的文件還是會加載,例如html文檔中的其他css/js/圖片文件。
另外javascript被加載后就會被執(zhí)行,執(zhí)行的過程也阻塞樹的構建。是執(zhí)行完了才解析其他內(nèi)容,而不是執(zhí)行完了才加載其他內(nèi)容。

作者:加冰
鏈接:https://www.zhihu.com/questio...

參考資料-2
首先,開源瀏覽器一般以8k每塊下載html頁面。
然后解析頁面生成DOM樹,遇到css標簽或JS腳本標簽就新起線程去下載他們,并繼續(xù)構建DOM。
下載完后解析CSS為CSS規(guī)則樹,瀏覽器結合CSS規(guī)則樹和DOM樹生成Render Tree。
注意:構建CSS Object Model(CSSOM)會阻塞JavaScript的執(zhí)行。JavaScript的執(zhí)行也會阻塞DOM的構建。
JavaScript下載后可以通過DOM API修改DOM,通過CSSOM API修改樣式作用域Render Tree。
每次修改會造成Render Tree的重新布局和重繪。只要修改DOM或修改了元素的形狀或大小,就會觸發(fā)Reflow,單純修改元素的顏色只需Repaint一下(調(diào)用操作系統(tǒng)Native GUI的API繪制)。

看完了這篇文章,相信你對瀏覽器解析渲染HTML文檔的過程是什么有了一定的了解,想了解更多相關知識,歡迎關注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI