網頁前端效能優化學習筆記

根據統計網頁的大小正逐年上升。

內容大致上分為以下4個章節:

  • Optimizing content efficiency
  • Chrome Developer Tools
  • Website Performance Optimization
  • Browser Rendering Optimization

1. Optimizing content efficiency

一、減少不必要的下載

  • 評估每個資產的成效:資產的價值及其技術效能。
  • Determine if the resources are providing sufficient value

二、最佳化文字內容(文字壓縮)

  • 程式碼註解是開發人員的最佳夥伴,但瀏覽器不需要這項資訊 只要除去 CSS (/* … */)、HTML (<! — … →) 和 JavaScript (// …) 註解,即可大幅縮減網頁的總大小。
  • 「智慧型」CSS 壓縮工具可以察覺到我們正在使用一種效率不彰的方式為 .awesome-container 定義規則,並將兩個聲明合併為一個而不影響任何其他樣式,因此節省更多位元組。
  • 在 HTML、CSS 和 JavaScript 中,空白 (空格和定位字元) 僅僅是為了開發人員方便。另外有一種壓縮工具可以除去所有定位字元和空格。
  • 使用 GZIP 進行文字壓縮 (所有現代瀏覽器都支援 GZIP 壓縮並會自動請求解壓縮)

三、圖片壓縮

  • 清除及取代圖片
  • 消除不必要的圖片資源
  • 儘量運用 CSS3 效果
  • 使用網路字型,避免在圖片中將文字編碼
  • 圖片壓縮工具
gifsicle / 建立及最佳化 GIF 圖片
jpegtran / 最佳化 JPEG 圖片
optipng / 無失真 PNG 最佳化
pngquant /失真 PNG 最佳化

四、如何選擇圖片檔案類型?

五、最佳化圖片

  • 優先選用向量格式:向量圖片不受解析度和縮放程度影響,最適用於多裝置或高解析度的情況。(如果複雜的畫面中包含許多不規則的圖形和細節,向量式格式會顯得不真實,請使用點陣圖片)
  • 縮減及壓縮 SVG 資源:大多數繪圖應用程式產生的 XML 標記通常包含不必要的中繼資料,可以放心刪除;請確保伺服器設定為對 SVG 資產採用 GZIP 壓縮。
  • 選擇最佳點陣圖片格式:確定功能要求,然後選擇適合每個特定資產的格式。
  • 試驗點陣格式的最佳品質設定:請大膽降低「品質」設定,效果通常非常好,節省的位元組可能會很可觀。
  • 刪除不必要的圖片中繼資料:許多點陣圖片包含不必要的資產中繼資料:地理資訊、相機資訊等。請使用適合的工具刪除這些資料。
  • 提供可縮放的圖片:調整伺服器上的圖片大小,確保「顯示」大小盡可能接近圖片的「自然」大小。請特別留意較大的圖片,因為調整這些圖片的大小時,通常會產生最大的間接成本!
  • 自動化、自動化、自動化:請投資自動化工具和基礎設施,如此可以確保所有圖片資產一定會經過最佳化。

六、網頁字型最佳化

  • 查核及監控您的字型使用情況: 請勿在您的網頁上使用過多字型。對於每種字型,也請儘量使用最少的變體。這有助您為使用者提供更加一致且快速的體驗。
  • 對您的字型資源進行子集擷取: 許多字型可以進行子集擷取或劃分為多個 unicode-range,方便只交付某個特定網頁需要的字符,如此即可縮減檔案大小並加快資源的下載速度。但是,在定義子集時,請小心最佳化字型重新使用,例如,您不需要在每個網頁上下載一種不同但重疊的字元集。一個比較好的做法是根據指令碼進行子集擷取,例如拉丁文、西里爾文等。
  • 為每個瀏覽器交付最佳化的字型格式: 每種字型都應以 WOFF2、WOFF、EOT 和 TTF 格式提供。請務必向 EOT 和 TTF 格式套用 GZIP 壓縮,因為在預設情況下並不會進行壓縮。
  • 指定重新驗證和最佳快取策略: 字型是不經常更新的靜態資源。確保您的伺服器提供一個較長的 max-age 時間戳記和一個重新驗證token,以允許在不同網頁之間有效的字型重複使用。
  • 使用 Font Loading API 來最佳化關鍵轉譯路徑: 預設延遲載入行為可能會導致文字呈現延遲。對於特定字型,我們可以透過 Font Loading API 覆寫這個行為,並為網頁上不同的內容指定自訂轉譯和逾時策略。對於不支援 API 的較舊瀏覽器,您可以使用 webfontloader JavaScript 程式庫或使用 CSS 內嵌策略。

七、使用快取:

定義最佳 Cache-Control Policy

Q:如果我們希望更新或作廢已快取的回應,該怎麼辦?

A:在檔案名稱中嵌入檔案的指紋碼或版本號碼

  • 使用一致的網址:如果您在不同的網址上提供相同的內容,將會多次取得及儲存該內容。提示:請注意網址區分大小寫
  • 確認伺服器提供token驗證 (ETag):透過token驗證,如果伺服器上的資源未曾變更,就不必傳輸相同的位元組。
  • 確定中繼快取可以快取哪些資源:對所有使用者的回應完全相同的資源很適合由 CDN 或其他中繼快取進行快取。
  • 確定每個資源的最佳快取效期:不同的資源可能有不同的更新要求。審查並確定每個資源適合的 max-age。
  • 確定網站的最佳快取階層:對 HTML 文件組合使用包含內容指紋碼的資源網址以及短時間或 no-cache 的效期,可以控制用戶端取得更新的速度。
  • 更新內容最小化:有些資源的更新頻率比其他資源高。如果資源的特定部分 (例如 JavaScript 函式或一組 CSS 樣式) 會經常更新,請考慮將其程式碼當做單獨的檔案提供。如此一來,每次擷取更新時,剩餘內容 (例如不會頻繁更新的程式庫程式碼) 可以從快取中擷取,讓需要下載的內容量降到最低。

2. Chrome Developer Tools

Timeline

For Web Performance Meature

Test runtime performance in events mode; test rendering performance in frames mode.

Measure Resource Loading Times

Remote Debugging Devices

3. Website Performance Optimization

Meature first, then optimize

Google page speed test

Critical Rendering Path(關鍵轉譯路徑

  • HTML is converted to the Document Object Model (DOM).
  • CSS is converted to the CSS Object Model (CSSOM).
  • Combine HTML DOM and CSSDOM -> Render Tree
  • the browser runs layout to determine the position and size of elements before painting pixels on the screen. (對轉譯樹狀結構進行版面配置,計算每個節點的幾何形狀。)
  • 在螢幕上繪製各個節點。

五個步驟:

  • 處理 HTML 標記,產生 DOM 樹狀結構。
  • 處理 CSS 標記,產生 CSSOM 樹狀結構。
  • 將 DOM 樹狀結構和 CSSOM 樹狀結構合併為轉譯樹狀結構。
  • 對轉譯樹狀結構進行版面配置,計算每個節點的幾何形狀。
  • 在螢幕上繪製各個節點。

所謂最佳化關鍵轉譯路徑,就是儘可能縮短上述第 1 步到第 5 步所花費的總時間。

CSS 是禁止轉譯的資源,您必須儘快將 CSS 提供給用戶端,以便縮短初次轉譯的時間。

  • Use media queies
  • Inline Small Css

JS 也是禁止轉譯資源,一般瀏覽器會遇到JS Script TAG會將執行指令碼的作業延遲到 CSSOM 下載及建構完成之後;在等待的同時,DOM 建構作業也會遭到禁止!

使用非同步載入JS

<script src=”./index.js” async ></script>
<script src=”./index.js” defer ></script>

Navigation Timing API (use chrome)

  • domLoading:這是整個過程開始的時間戳記,瀏覽器開始解析 HTML 文件第一批收到的位元組 。
  • domInteractive:標記瀏覽器完成解析並且所有 HTML 和 DOM 都建構完畢的時間點。
  • domContentLoaded:標記 DOM 準備就緒並且沒有樣式表禁止 JavaScript 執行的時間點,表示我們現在 (大概) 可以開始建構轉譯樹狀結構了。
  • 很多 JavaScript 框架等待這個事件發生後,才會開始執行自己的邏輯。因此,瀏覽器會透過捕捉 EventStartEventEnd 時間戳記,方便我們追蹤執行邏輯所需的時間。
  • domComplete: 顧名思義,所有的處理程序都已完成,網頁上所有資源 (圖片等) 也下載完成,表示載入旋轉圖示停止旋轉了。
  • loadEvent:這是每個網頁載入的最後一步,瀏覽器會觸發「onLoad」事件,以便觸發額外的應用程式邏輯。

如何分析?

使用非同步後:

最佳化網頁恢復到具有2種關鍵資源 (HTML 和 CSS)、具有2個往返過程的最短關鍵路徑長度和 9 KB 的總關鍵位元組數量。

最佳化目標:

  • 儘可能減少關鍵資源數量。
  • 儘可能減少關鍵位元組數。
  • 儘量縮短關鍵路徑的長度。

最佳化關鍵轉譯路徑的常見步驟如下:

  • 分析及描述關鍵路徑:資源數量、位元組數、長度。
  • 盡量減少關鍵資源數量:刪除相應資源、延遲下載、標記為非同步資源等等。
  • 最佳化剩餘關鍵資源的載入順序:您需要儘早下載所有關鍵資源,以縮短關鍵路徑長度。
  • 盡量減少關鍵位元組數,以縮短下載時間 (往返次數)。

4. Browser Rendering Optimization

60fps 和裝置重新整理頻率

時下大多數裝置會以 每秒 60 次 重新整理螢幕。 如果正在執行動畫或轉換,或使用者正在捲動網頁,瀏覽器需要符合裝置的重新整理頻率,並針對每一次螢幕重新整理,組成一個新圖形,或畫面。

每一個畫面的容許預算只有稍高於 16ms (1 秒 / 60 = 16.66ms)。 在現實中,瀏覽器還有例常任務要執行,因此您的所有工作必須在 10ms 內完成。 當您未能滿足此預算要求,畫面率就會下降,而螢幕上的內容會顫動。 這通常稱為 閃避,這會負面影響使用者體驗。

用 JS 改變 Layout:

改變陰影顏色

transform-style

查看各種CSS會觸發哪些行為: http://csstriggers.com

一些概念

DOM + CSS -> Recalculate

Image -> Decode + Resize (像素)

HTML Composite Layer

Browser from CPU 計算 to GPU 繪製

App Lifecycles (RAIL)

Load:網頁讀取

Idle: 等待user操作

Animate :畫面開始改變

Response :畫面反應

Junk(找出問題所在)

Performance issues, such as:

  • Layout Thrashing
  • Expensive painting
  • Unnecessary layouts
  • Long-running and badly-timed JavaScript
  • Bad touch handling

http://output.jsbin.com/nanana/2/quiet#

Here’s the site for your analysis!

Javascript (避免Long run JS)

Just In Time Compiler

  • 避免微最佳化您的 JavaScript

Micro-Optimization is last one to do. (不要先過度優化一些程式碼,像是不要去思考用for還是while哪個比較好這種complie上的問題)

  • 針對視覺更新避免 setTimeout 或 setInterval;一律改為使用 requestAnimationFrame
  • 將長時間執行的 JavaScript 從主執行緒移動至 Web Worker
  • 使用 Chrome DevTools 的 Timeline 和 JavaScript Profiler,以評估 JavaScript 的影響。

Javascript Profiler

Here’s the site for your analysis!

Memory Management:可以用chrome查看memory使用

Style and Layout (有效率的撰寫CSS)

  • The cost of style change:
  • The cost of recalculate styles scales linearly with the number of elements.
  • Selector:
  • Block element modifier: keep selecting mathching simple.

Writing efficient CSS

Layout Thrashing (避免大型、複雜的版面配置和版面配置輾轉)

Here’s the demo site!

  • Use flexible box layout
  • 避免強制性同步版面配置
  • 首先是 JavaScript 執行、然後 樣式計算,然後 版面配置。 然而,是可以利用 JavaScript 強制瀏覽器早一點執行版面配置。 它稱為 強制性同步版面配置
  • Solve Forced Sychronours Latout -> Use batch style change

如果您想要確保安全,您應該檢查 FastDOM,它會為您自動批次處理讀取與寫入,也應該能避免您意外觸發強制同步版面配置或版面配置輾轉。

Compositing and Painting

Painting is super expensive to mobile.

Turn on chrome show painting reactange

  • 變更變形或透明度之外的任何屬性,一定會觸發繪製。
  • 繪製往往是像素管道中最高成本的一部分;儘可能避免這個動作。
  • 透過層升階和動畫的協調流程,以減少繪製區域。
  • 使用 Chrome DevTools 繪製分析工具以評估繪製複雜性和成本;儘可能減少這個動作。

Layout change -> Add will-change to box element

  • 動畫使用變形和透明度變更。
  • 以 will-change 或 translateZ 將移動元素升階。
  • 避免過度使用升階規則;圖層需要記憶體和管理

Debounce your input handlers

The solution to both of the problems above is the same: you should always debounce visual changes to the next requestAnimationFrame callback:

參考來源:

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.