新聞中心
瀏覽器加載流程
瀏覽器在渲染頁面時需要將 HTML 標(biāo)記轉(zhuǎn)化成 DOM 對象

成都創(chuàng)新互聯(lián)公司是一家專注于成都做網(wǎng)站、成都網(wǎng)站制作與策劃設(shè)計,穆棱網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十余年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:穆棱等地區(qū)。穆棱做網(wǎng)站價格咨詢:18980820575
CSS 則會被轉(zhuǎn)化成 CSSOM 對象
DOM 和 CSSOM 是獨立的樹形結(jié)構(gòu),
當(dāng) DOM 樹和 CSSOM 樹都構(gòu)建完成的時候,他們就會合并在一起構(gòu)建 render tree,因為要在頁面上渲染不僅需要這個頁面的結(jié)構(gòu),也需要知道整個頁面的樣式,所以 render tree 是 DOM 樹和 CSSOM 樹的結(jié)合體,有了 render tree,瀏覽器才能知道把什么內(nèi)容按照什么樣式渲染在屏幕上。
瀏覽器從獲取 HTML 到最終在屏幕上顯示內(nèi)容需要完成以下步驟:
- 處理 HTML 標(biāo)記并構(gòu)建 DOM 樹。
- 處理 CSS 標(biāo)記并構(gòu)建 CSSOM 樹。
- 將 DOM 與 CSSOM 合并成一個 render tree。
- 根據(jù)渲染樹來布局,以計算每個節(jié)點的幾何信息。
- 將各個節(jié)點繪制到屏幕上。
經(jīng)過以上整個流程我們才能看見屏幕上出現(xiàn)渲染的內(nèi)容,優(yōu)化關(guān)鍵渲染路徑就是指最大限度縮短執(zhí)行上述第 1 步至第 5 步耗費的總時間,讓用戶最快的看到首次渲染的內(nèi)容。
另外,這是一個漸進(jìn)的過程。為達(dá)到更好的用戶體驗,呈現(xiàn)引擎會力求盡快將內(nèi)容顯示在屏幕上。它不必等到整個 HTML 文檔解析完畢之后,就會開始構(gòu)建呈現(xiàn)樹和設(shè)置布局。在不斷接收和處理來自網(wǎng)絡(luò)的其余內(nèi)容的同時,呈現(xiàn)引擎會將部分內(nèi)容解析并顯示出來,因為 HTML 采用基于流的布局模型,這意味著大多數(shù)情況下只要一次遍歷就能計算出幾何信息。處于流中靠后位置元素通常不會影響靠前位置元素的幾何特征,因此布局可以按從左至右、從上至下的順序遍歷文檔。但是也有例外情況,比如 HTML 表格的計算就需要不止一次的遍歷。
阻塞渲染的因素
外部樣式表
從上面的整個流程我們已經(jīng)知道,瀏覽器的渲染需要 render tree, render tree 需要 CSSOM 樹才行,所以樣式表的加載是會阻塞頁面的渲染的,如果有一個外部的樣式表處于下載中,那么即使 HTML 已經(jīng)下載完畢,也會等待外部樣式表下載并解析完畢才會開始構(gòu)建 render tree。
腳本
腳本就更麻煩了,先明確一點, JS 引擎和 UI 的渲染引擎是互斥的,所以當(dāng)腳本在執(zhí)行的時候瀏覽器要將控制權(quán)就給 JS 引擎,等到 JS 執(zhí)行完畢再還給 UI 引擎,不論這個腳本是以何種形式加載的,在執(zhí)行時均會阻塞 UI 的渲染。
接下來分別看不同形式加載的腳本對頁面渲染的阻塞情況:
內(nèi)聯(lián)腳本
內(nèi)聯(lián)的腳本隨著 HTML 一起下載,在開始執(zhí)行時已經(jīng)完成了 字節(jié) → 字符 → 令牌 → 節(jié)點 → 對象模型 的整個過程,所以不存在下載的時間(其實也不能這么說,下載的時間算在了 HTML 的下載時間中),執(zhí)行時是會阻塞關(guān)鍵渲染路徑的。
外部腳本
外部腳本的整個加載過程及執(zhí)行過程都是阻塞關(guān)鍵渲染路徑的。
帶 defer 和 async 的外部腳本
帶 defer/async 的腳本會與 HTML 并行下載,下載的過程不會阻塞 DOM 的構(gòu)建,但是執(zhí)行是會的,不同的是 defer 是在 DomContentLoaded 之前執(zhí)行,async 是加載完之后立刻執(zhí)行。
defer/async 的腳本在下載期間不會阻塞頁面解析不是一個技術(shù)原因而是一個選擇,因為內(nèi)聯(lián)腳本/外部腳本是要等待他們執(zhí)行,所以不得不等待他們下載。而頁面并不需要等待 defer/async 的腳本,所以他們的下載與頁面的解析是并行的。
動態(tài)生成的腳本
var dynamicScript = document.creatElement('script')
dynamicScript.src = 'sample.js'
document.head.appendChild(dynamicScript)
dynamicScript.onload = function(){...}動態(tài)生成的腳本的下載過程不會阻塞頁面的解析,執(zhí)行會阻塞解析,有點 async 的感覺。
腳本與樣式表的依賴關(guān)系
腳本不僅能夠訪問 DOM 元素,還能訪問 DOM 的樣式,如果將要執(zhí)行腳本時瀏覽器尚未完成 CSSOM 的下載及構(gòu)建,瀏覽器將延遲腳本執(zhí)行和 DOM 構(gòu)建,直至其完成 CSSOM 的下載和構(gòu)建。
所以,CSSOM 的構(gòu)建會阻塞 HTML 的渲染,也會阻塞 JS 的執(zhí)行,JS 的下載與執(zhí)行(內(nèi)聯(lián)及外部樣式表)也會阻塞 HTML 的渲染。
優(yōu)化方法
為盡快完成首次渲染,我們需要最大限度減小以下三種可變因素:
- 關(guān)鍵資源的數(shù)量:可能阻止網(wǎng)頁首次渲染的資源。
- 關(guān)鍵路徑長度:獲取所有關(guān)鍵資源所需的往返次數(shù)或總時間。
- 關(guān)鍵字節(jié)的數(shù)量:實現(xiàn)網(wǎng)頁首次渲染所需的總字節(jié)數(shù),它是所有關(guān)鍵資源傳送文件大小的總和。我們包含單個 HTML 頁面的第一個示例包含一項關(guān)鍵資源(HTML 文檔);關(guān)鍵路徑長度也與 1 次網(wǎng)絡(luò)往返相等(假設(shè)文件較?。?,而總關(guān)鍵字節(jié)數(shù)正好是 HTML 文檔本身的傳送大小。
優(yōu)化關(guān)鍵渲染路徑的常規(guī)步驟如下:
- 對關(guān)鍵路徑進(jìn)行分析和特性描述:資源數(shù)、字節(jié)數(shù)、長度。
- 最大限度減少關(guān)鍵資源的數(shù)量:刪除它們,延遲它們的下載,將它們標(biāo)記為異步等。
- 優(yōu)化關(guān)鍵字節(jié)數(shù)以縮短下載時間(往返次數(shù))。
- 優(yōu)化其余關(guān)鍵資源的加載順序:您需要盡早下載所有關(guān)鍵資產(chǎn),以縮短關(guān)鍵路徑長度。
關(guān)鍵 CSS
上面已經(jīng)分析過了,樣式表會阻塞渲染,在加載完畢之前是不會顯示的,為了讓用戶以最快的速度看到頁面上的內(nèi)容,可以將頁面的某一部分的樣式抽離出來,單獨放在一個樣式表中或者內(nèi)聯(lián)在頁面中,這樣的樣式稱為關(guān)鍵樣式,這部分樣式會優(yōu)先它可以是頁面的骨架屏或者是用戶剛加載進(jìn)頁面時看到的首屏的內(nèi)容。
...body goes here


咨詢
建站咨詢