前面的話
使用Chrome DevTools的performance皮膚可以記錄和分析頁面在執行時的所有活動。本文將詳細介紹如何使用performance皮膚解決效能瓶頸
準備
【匿名模式】
匿名模式可以保證Chrome在一個相對乾淨的環境下執行。比如安裝了許多chrome外掛,這些外掛可能會影響我們分析效能表現
使用快捷鍵ctrl + shift + N 即可程式碼匿名模式下的chrome新標籤頁
【移動裝置CPU】
移動裝置的CPU一般比桌上型電腦和筆記本弱很多。分析頁面時,可以用CPU控制器(CPU Throttling)來模擬移動端裝置CPU
在DevTools中,點選 Performance 的 tab。 確保 Screenshots checkbox 被選中;點選 Capture Settings(⚙️)按鈕,DevTools會展示很多設定,來模擬各種狀況;對於模擬CPU,選擇4x slowdown,於是Devtools就開始模擬4倍低速CPU
概覽
【組成】
performance皮膚有如下四個窗格:
1、controls。開始記錄,停止記錄和配置記錄期間捕獲的資訊
2、overview。頁面效能的高階彙總
3、火焰圖。 CPU 堆疊追蹤的視覺化
4、統計彙總。以圖表的形式彙總資料
【顏色表示】
HTML 檔案為藍色
指令碼為黃色
樣式表為紫色
媒體檔案為綠色
其他資源為灰色
【做記錄】
開啟想要記錄的頁面,然後重新載入頁面。 performance皮膚會自動記錄頁面重新載入。
要記錄頁面互動,開啟 performance 皮膚,然後按 Record 按鈕 或者鍵入鍵盤快捷鍵 Cmd+E (Mac) 或 Ctrl+E(Windows / Linux),開始記錄。記錄時,Record 按鈕會變成紅色。執行頁面互動,然後按 Record 按鈕或再次鍵入鍵盤快捷鍵停止記錄
完成記錄後,DevTools 會猜測哪一部分記錄最相關,並自動縮放到那一個部分
檢視
【Overview】
Overview 窗格包含以下三個圖表:
1、FPS。每秒幀數。綠色豎線越高,FPS 越高。 FPS 圖表上的紅色塊表示長時間幀,很可能會出現卡頓
2、CPU。 CPU 資源。此面積圖指示消耗 CPU 資源的事件型別
3、NET。每條彩色橫槓表示一種資源。橫槓越長,檢索資源所需的時間越長。 每個橫槓的淺色部分表示等待時間(從請求資源到第一個位元組下載完成的時間)
可以放大顯示一部分記錄,以便簡化分析。使用 Overview 窗格可以放大顯示一部分記錄。 放大後,火焰圖會自動縮放以匹配同一部分
選擇部分後,可以使用 W、A、S 和 D 鍵調整您的選擇。 W 和 S 分別代表放大和縮小。 A 和 D 分別代表左移和右移
【火焰圖】
在火焰圖上看到一到三條垂直的虛線。藍線代表 DOMContentLoaded
事件。 綠線代表首次繪製的時間。 紅線代表 load
事件
在火焰圖中選擇事件時,Details 窗格會顯示與事件相關的其他資訊
診斷
【JS】
JavaScript 計算,特別是會觸發大量視覺變化的計算會降低應用效能。 不要讓時機不當或長時間執行的 JavaScript 影響使用者互動
下面是一些常見 JavaScript 問題
1、大開銷輸入處理程式影響響應或動畫
讓瀏覽器儘可能晚地處理觸控和滾動,或者繫結偵聽
2、時機不當的 JavaScript 影響響應、動畫、載入
使用 requestAnimationFrame
、使 DOM 操作遍佈各個幀、使用網路工作執行緒
3、長時間執行的 JavaScript 影響響應
將純粹的計算工作轉移到web worker中。如果需要 DOM 訪問許可權,配合使用requestAnimationFrame
【樣式】
樣式更改開銷較大,在這些更改會影響 DOM 中的多個元素時更是如此。 只要將樣式應用到元素,瀏覽器就必須確定對所有相關元素的影響、重新計算佈局並重新繪製
點選 Recalculate Style 事件(以紫色顯示)可以在 Details 窗格中檢視更多相關資訊。 如果樣式更改需要較長時間,對效能的影響會非常大。 如果樣式計算會影響大量元素,則需要改進另一個方面
要降低 Recalculate Style 事件的影響,使用一些對渲染效能的影響較小的屬性。如使用 transform 和 opacity 屬性更改來實現動畫,使用 will-change
或 translateZ
提升移動的元素
下面是一些常見的CSS問題
1、大開銷樣式計算影響響應或動畫
任何會更改元素幾何形狀的 CSS 屬性,如寬度、高度或位置;瀏覽器必須檢查所有其他元素並重做佈局。避免會觸發重排的CSS屬性
2、複雜的選擇器影響響應或動畫
巢狀選擇器強制瀏覽器瞭解與所有其他元素有關的全部內容,包括父級和子級。儘量在CSS中引用只有一個類的元素
【重排】
佈局(或重排)是瀏覽器用來計算頁面上所有元素的位置和大小的過程。 網頁的佈局模式意味著一個元素可能影響其他元素;例如body
元素的寬度一般會影響其子元素的寬度以及樹中各處的節點等等。這個過程對於瀏覽器來說可能很複雜。 一般的經驗法則是,如果在幀完成前從 DOM 請求返回幾何值,將發現會出現“強制同步佈局”,在頻繁地重複或針對較大的 DOM 樹執行操作時這會成為效能的大瓶頸。
performance皮膚可以確定頁面何時會導致強制同步佈局。 這些 Layout 事件使用紅色豎線標記
“佈局抖動”是指反覆出現強制同步佈局情況。 這種情況會在 JavaScript 從 DOM 反覆地寫入和讀取時出現,將會強制瀏覽器反覆重新計算佈局
【重繪】
繪製是填充畫素的過程。這經常是渲染流程開銷最大的部分。 如果在任何情況下注意到頁面出現卡頓現象,很有可能存在繪製問題。
合成是將頁面的已繪製部分放在一起以在螢幕上顯示的過程。 大多數情況下,如果堅持僅合成器屬性並避免一起繪製,效能會有極大的改進,但是需要留意過多的層計數
一定不要使用下面的程式碼
* { will-change: transform; transform: translateZ(0); }
這是以迂迴方式說想要提升頁面上的每個元素。此處的問題是建立的每一層都需要記憶體和管理,而這些並不是免費的。事實上,在記憶體有限的裝置上,對效能的影響可能遠遠超過建立層帶來的任何好處。每一層的紋理都需要上傳到 GPU,使 CPU 與 GPU 之間的頻寬、GPU 上可用於紋理處理的記憶體都受到進一步限制
如果大部分渲染時間花費在繪製上,即表示存在繪製問題
下面是一些常見的繪製問題
1、繪製風暴影響響應或動畫
較大的繪製區域或大開銷繪製影響了響應或動畫,要避免繪製、提升將要移動到自有層的元素,使用變形和不透明度
2、層數激增影響動畫
使用 translateZ(0) 過度提升過多的元素會嚴重影響動畫效能,要謹慎提升到層,並且僅在瞭解這樣會有切實改進時才提升到層