構(gòu)建對(duì)象模型
瀏覽器渲染頁面前需要先構(gòu)建 DOM 和 CSSOM 樹躲履。因此,我們需要確保盡快將 HTML 和 CSS 都提供給瀏覽器。
- 字節(jié) → 字符 → 令牌 → 節(jié)點(diǎn) → 對(duì)象模型。
- HTML 標(biāo)記轉(zhuǎn)換成文檔對(duì)象模型 (DOM);CSS 標(biāo)記轉(zhuǎn)換成 CSS 對(duì)象模型 (CSSOM)历葛。
- DOM 和 CSSOM 是獨(dú)立的數(shù)據(jù)結(jié)構(gòu)。
- Chrome DevTools Timeline 讓我們可以捕獲和檢查 DOM 和 CSSOM 的構(gòu)建和處理開銷嘀略。
渲染樹構(gòu)建恤溶、布局及繪制
- DOM 樹與 CSSOM 樹合并后形成渲染樹。
- 渲染樹只包含渲染網(wǎng)頁所需的節(jié)點(diǎn)帜羊。
- 布局計(jì)算每個(gè)對(duì)象的精確位置和大小咒程。
- 最后一步是繪制,使用最終渲染樹將像素渲染到屏幕上讼育。
為構(gòu)建渲染樹帐姻,瀏覽器大體上完成了下列工作:
- 從 DOM 樹的根節(jié)點(diǎn)開始遍歷每個(gè)可見節(jié)點(diǎn)。
- 某些節(jié)點(diǎn)不可見(例如腳本標(biāo)記奶段、元標(biāo)記等)饥瓷,因?yàn)樗鼈儾粫?huì)體現(xiàn)在渲染輸出中,所以會(huì)被忽略痹籍。
- 某些節(jié)點(diǎn)通過 CSS 隱藏呢铆,因此在渲染樹中也會(huì)被忽略,例如蹲缠,上例中的 span 節(jié)點(diǎn)---不會(huì)出現(xiàn)在渲染樹中棺克,---因?yàn)橛幸粋€(gè)顯式規(guī)則在該節(jié)點(diǎn)上設(shè)置了“display: none”屬性悠垛。
- 對(duì)于每個(gè)可見節(jié)點(diǎn),為其找到適配的 CSSOM 規(guī)則并應(yīng)用它們娜谊。
- 發(fā)射可見節(jié)點(diǎn)确买,連同其內(nèi)容和計(jì)算的樣式。
阻塞渲染的 CSS
請(qǐng)注意“阻塞渲染”僅是指瀏覽器是否需要暫停網(wǎng)頁的首次渲染纱皆,直至該資源準(zhǔn)備就緒湾趾。無論哪一種情況,瀏覽器仍會(huì)下載 CSS 資產(chǎn)派草,只不過不阻塞渲染的資源優(yōu)先級(jí)較低罷了搀缠。
- 默認(rèn)情況下,CSS 被視為阻塞渲染的資源澳眷。
- 我們可以通過媒體類型和媒體查詢將一些 CSS 資源標(biāo)記為不阻塞渲染。
- 瀏覽器會(huì)下載所有 CSS 資源蛉艾,無論阻塞還是不阻塞钳踊。
使用 JavaScript 添加交互
JavaScript 允許我們修改網(wǎng)頁的方方面面:內(nèi)容、樣式以及它如何響應(yīng)用戶交互勿侯。 不過拓瞪,JavaScript 也會(huì)阻止 DOM 構(gòu)建和延緩網(wǎng)頁渲染。 為了實(shí)現(xiàn)最佳性能助琐,可以讓您的 JavaScript 異步執(zhí)行祭埂,并去除關(guān)鍵渲染路徑中任何不必要的 JavaScript。
- JavaScript 可以查詢和修改 DOM 與 CSSOM兵钮。
- JavaScript 執(zhí)行會(huì)阻止 CSSOM蛆橡。
- 除非將 JavaScript 顯式聲明為異步,否則它會(huì)阻止構(gòu)建 DOM掘譬。
- 腳本在文檔中的位置很重要泰演。
- 當(dāng)瀏覽器遇到一個(gè) script 標(biāo)記時(shí),DOM 構(gòu)建將暫停葱轩,直至腳本完成執(zhí)行睦焕。
- JavaScript 可以查詢和修改 DOM 與 CSSOM。
- JavaScript 執(zhí)行將暫停靴拱,直至 CSSOM 就緒垃喊。
評(píng)估關(guān)鍵渲染路徑
- Lighthouse 方法會(huì)對(duì)頁面運(yùn)行一系列自動(dòng)化測試,然后生成關(guān)于頁面的 CRP 性能的報(bào)告袜炕。 這一方法對(duì)您的瀏覽器中加載的特定頁面的 CRP 性能提供了快速且簡單的高級(jí)概覽本谜,讓您可以快速地測試、循環(huán)訪問和提高其性能偎窘。
- Navigation Timing API 方法會(huì)捕獲[真實(shí)用戶監(jiān)控 指標(biāo)耕突。如名稱所示笤成,這些指標(biāo)捕獲自真實(shí)用戶與網(wǎng)站的互動(dòng),并為真實(shí)的 CRP 性能(您的用戶在各種設(shè)備和網(wǎng)絡(luò)狀況下的體驗(yàn))提供了準(zhǔn)確的信息眷茁。
分析關(guān)鍵渲染路徑性能
到目前為止炕泳,我們只關(guān)注了資源(CSS、JS 或 HTML 文件)可供處理后瀏覽器中會(huì)發(fā)生的情況上祈,而忽略了從緩存或從網(wǎng)絡(luò)獲取資源所需的時(shí)間培遵。我們作以下假設(shè):
- 到服務(wù)器的網(wǎng)絡(luò)往返(傳播延遲時(shí)間)需要 100 毫秒。
- HTML 文檔的服務(wù)器響應(yīng)時(shí)間為 100 毫秒登刺,所有其他文件的服務(wù)器響應(yīng)時(shí)間均為 10 毫秒籽腕。
優(yōu)化關(guān)鍵渲染路徑
為盡快完成首次渲染,我們需要最大限度減小以下三種可變因素:
關(guān)鍵資源的數(shù)量纸俭。
關(guān)鍵路徑長度皇耗。
關(guān)鍵字節(jié)的數(shù)量。
關(guān)鍵資源是可能阻止網(wǎng)頁首次渲染的資源揍很。這些資源越少郎楼,瀏覽器的工作量就越小,對(duì) CPU 以及其他資源的占用也就越少窒悔。
優(yōu)化關(guān)鍵渲染路徑的常規(guī)步驟如下:對(duì)關(guān)鍵路徑進(jìn)行分析和特性描述:資源數(shù)呜袁、字節(jié)數(shù)、長度简珠。
最大限度減少關(guān)鍵資源的數(shù)量:刪除它們阶界,延遲它們的下載,將它們標(biāo)記為異步等聋庵。
優(yōu)化關(guān)鍵字節(jié)數(shù)以縮短下載時(shí)間(往返次數(shù))膘融。
優(yōu)化其余關(guān)鍵資源的加載順序:您需要盡早下載所有關(guān)鍵資產(chǎn),以縮短關(guān)鍵路徑長度祭玉。
PageSpeed 規(guī)則和建議
消除阻塞渲染的 JavaScript 和 CSS
要以最快速度完成首次渲染托启,需要最大限度減少網(wǎng)頁上關(guān)鍵資源的數(shù)量并(盡可能)消除這些資源,最大限度減少下載的關(guān)鍵字節(jié)數(shù)攘宙,以及優(yōu)化關(guān)鍵路徑長度屯耸。-
優(yōu)化 JavaScript 的使用
- 首選使用異步 JavaScript 資源
- 避免同步服務(wù)器調(diào)用
- 延遲解析 JavaScript
- 避免運(yùn)行時(shí)間長的 JavaScript
-
優(yōu)化 CSS 的使用
- 將 CSS 置于文檔 head 標(biāo)簽內(nèi)
- 避免使用 CSS import
- 內(nèi)聯(lián)阻塞渲染的 CSS
加載過程是最為耗時(shí)的過程,可能會(huì)占到總耗時(shí)的80%時(shí)間蹭劈,因此是優(yōu)化的重點(diǎn)