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

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


咨詢
建站咨詢