優化網站性能和關鍵渲染路徑
已發表: 2022-03-11您的網頁的渲染性能是否符合當今的標準? 渲染是將服務器的響應翻譯成用戶訪問網站時瀏覽器“繪製”的圖片的過程。 糟糕的渲染性能可以轉化為相對較高的跳出率。
有不同的服務器響應來確定是否呈現頁面。 在本文中,我們將重點關注網頁的初始呈現,它從解析 HTML 開始(前提是瀏覽器已成功接收到 HTML 作為服務器的響應)。 我們將探索可能導致高渲染時間的問題,以及如何解決它們。
關鍵渲染路徑
關鍵渲染路徑 (CRP) 是瀏覽器將代碼轉換為屏幕上可顯示像素的過程。 它有幾個階段,其中一些可以並行執行以節省時間,但有些部分必須依次完成。 這裡是可視化的:
首先,一旦瀏覽器得到響應,它就會開始解析它。 當它遇到依賴項時,它會嘗試下載它。
如果它是一個樣式表文件,瀏覽器必須在渲染頁面之前完全解析它,這就是為什麼CSS 被稱為渲染阻塞的原因。
如果是腳本,瀏覽器必須:停止解析,下載腳本,然後運行。 只有在那之後它才能繼續解析,因為 JavaScript 程序可以改變網頁的內容(尤其是 HTML)。 這就是為什麼JS 被稱為解析器阻塞。
完成所有解析後,瀏覽器將構建文檔對像模型 (DOM) 和級聯樣式表對像模型 (CSSOM)。 將它們組合在一起得到渲染樹。 頁面的非顯示部分不會進入渲染樹,因為它只包含繪製頁面所需的數據。
倒數第二步是將渲染樹轉換為佈局。 這個階段也稱為回流。 這就是計算每個渲染樹節點的每個位置及其大小的地方。
最後,最後一步是畫圖。 它涉及根據瀏覽器在前一階段計算的數據對像素進行著色。
優化相關結論
您可以猜到,網站性能優化的過程涉及對網站的更改,這些更改會減少:
- 必須傳輸的數據量
- 瀏覽器必須下載的資源數量(尤其是阻塞的資源)
- CRP的長度
此外,我們將深入研究它是如何完成的,但首先,有一條重要的規則需要遵守。
如何衡量績效
優化的一個重要規則是:先測量,按需優化。 大多數瀏覽器的開發人員工具都有一個名為Performance的選項卡,這就是測量發生的地方。 在優化最快的初始(第一次)渲染時,最重要的是要查看以下事件的時間:
- 第一次油漆
- 第一次內容豐富的油漆
- 第一次有意義的油漆
在這裡,“繪製”意味著頁面的成功渲染,是關鍵渲染路徑的最後階段。 一些渲染可能會一個接一個地發生,因為瀏覽器會嘗試盡快顯示某些內容並稍後更新。
除了渲染時間之外,還有其他一些事情需要考慮——最重要的是,使用了多少阻塞資源以及下載它們需要多長時間。 進行測量後,可以在“性能”選項卡中找到此信息。
性能優化策略
鑑於我們在上面了解到的內容,網站性能優化有三種主要策略:
- 盡量減少通過網絡傳輸的數據量,
- 減少通過網絡傳輸的資源總數,以及
- 縮短關鍵渲染路徑
1. 盡量減少要傳輸的數據量
首先,移除所有未使用的部分,例如 JavaScript 中無法訪問的函數、帶有從不匹配任何元素的選擇器的樣式以及被 CSS 永遠隱藏的 HTML 標籤。 其次,刪除所有重複項。
然後,我建議建立一個自動縮小過程。 例如,它應該從您的後端服務中刪除所有註釋(但不是源代碼)以及每個不包含附加信息的字符(例如 JS 中的空白字符)。
完成後,我們剩下的可以是文本。 這意味著我們可以安全地應用諸如 GZIP(大多數瀏覽器都理解)之類的壓縮算法。
最後,還有緩存。 這在瀏覽器第一次呈現頁面時無濟於事,但在後續訪問時會節省很多。 但是,記住兩點至關重要:
- 如果您使用 CDN,請確保支持緩存並在此處正確設置。
- 而不是等待資源的到期日期到來,您可能希望有一種方法可以從您身邊更早地更新它。 將文件的“指紋”嵌入到它們的 URL 中,以使本地緩存無效。
當然,應該為每個資源定義緩存策略。 有些可能很少改變或根本不會改變。 其他人的變化更快。 有些包含敏感信息,有些可能被認為是公開的。 使用“private”指令防止 CDN 緩存私有數據。

也可以優化網絡圖像,儘管圖像請求不會阻止解析或呈現。
2. 減少關鍵資源的總數
“關鍵”僅指網頁正確呈現所需的資源。 因此,我們可以直接跳過所有流程中沒有涉及的樣式。 還有所有的腳本。
樣式表
為了告訴瀏覽器不需要特定的 CSS 文件,我們應該為所有引用樣式表的鏈接設置media
體屬性。 使用這種方法,瀏覽器將只根據需要處理與當前media
(設備類型、屏幕尺寸)匹配的資源,同時降低所有其他樣式表的優先級(它們無論如何都會被處理,但不會作為關鍵渲染的一部分)小路)。 例如,如果您將media="print"
屬性添加到引用樣式以打印頁面的style
標記,則這些樣式不會在不print
媒體時干擾您的關鍵渲染路徑(即,當顯示瀏覽器中的頁面)。
為了進一步改進該過程,您還可以內聯一些樣式。 這為我們節省了至少一次往返服務器的時間,否則我們需要獲取樣式表。
腳本
如上所述,腳本是解析器阻塞的,因為它們可以改變 DOM 和 CSSOM。 因此,不改變它們的腳本不應該是塊解析,從而節省我們的時間。
為了實現這一點,所有腳本標籤都必須標有屬性—— async
或defer
。
標有async
的腳本不會阻塞 DOM 構建或 CSSOM,因為它們可以在 CSSOM 構建之前執行。 但請記住,內聯腳本無論如何都會阻止 CSSOM,除非您將它們放在 CSS 之上。
相比之下,標有defer
的腳本將在頁面加載結束時進行評估。 因此,它們不應該影響文檔(否則,它將觸發重新渲染)。
換句話說,使用defer
,腳本在頁面加載事件觸發後才會執行,而async
讓腳本在解析文檔時在後台運行。
3.縮短關鍵渲染路徑長度
最後,應將 CRP 長度縮短到可能的最小值。 部分地,上述方法將做到這一點。
作為樣式標籤屬性的媒體查詢將減少必須下載的資源總數。 script 標籤屬性defer
和async
將防止相應的腳本阻塞解析。
使用 GZIP 壓縮、壓縮和歸檔資源將減少傳輸數據的大小(從而也減少數據傳輸時間)。
內聯一些樣式和腳本可以減少瀏覽器和服務器之間的往返次數。
我們尚未討論的是在文件中重新排列代碼的選項。 按照最新的最佳性能理念,一個網站應該做的最快的第一件事就是展示 ATF 內容。 ATF 代表首屏。 這是立即可見的區域,無需滾動。 因此,最好以首先加載所需樣式和腳本的方式重新排列與渲染相關的所有內容,而其他所有內容都停止 - 既不解析也不渲染。 並且永遠記得在你做出改變之前和之後進行測量。
結論:優化涵蓋您的整個堆棧
總而言之,網站性能優化包含了站點響應的各個方面,例如緩存、設置 CDN、重構、資源優化等,但是所有這些都可以逐步完成。 作為 Web 開發人員,您應該將本文作為參考,並始終記住在實驗之前和之後測量性能。
瀏覽器開發人員盡最大努力優化您訪問的每個頁面的網站性能,這就是瀏覽器通常實現所謂的“預加載器”的原因。 這部分程序會在您以 HTML 格式請求的資源之前進行掃描,以便一次發出多個請求並讓它們並行運行。 這就是為什麼在 HTML(逐行)以及腳本標籤中保持樣式標籤彼此靠近的原因。
此外,嘗試批量更新 HTML 以避免多個佈局事件,這些事件不僅由 DOM 或 CSSOM 中的更改觸發,而且由設備方向更改和窗口大小調整觸發。
有用的資源和進一步閱讀:
- PageSpeed 見解
- 緩存清單
- 一種測試是否為您的網站啟用 GZIP 的方法
- 高性能瀏覽器網絡:Ilya Grigorik 的一本書