原文地址:developers.google.com/web/tools/c…javascript
在本教程中,你將學會如何使用性能分析工具分析頁面上的性能瓶頸。java
在隱身模式下打開Google Chrome。隱身模式確保Chrome在乾淨的狀態下運行。例如,若是你安裝了不少擴展,這些擴展可能會影響到性能分析的結果。git
在隱身窗口中加載如下頁面。這是本教程的Demo,頁面顯示了一堆上下移動的藍色小方塊。github
googlechrome.github.io/devtools-sa…web
接着按 F12 打開 DevTools。chrome
圖1: Demo 在左側,DevTools在右側。瀏覽器
注意:爲了保證更好的閱讀體驗,在後續的截圖中,DelTools分到單獨的窗口顯示。app
移動設備的CPU算力比臺式機和筆記本電腦小得多。不管什麼時候評測頁面,均可以使用CPU調節來模擬頁面在移動設備上的表現。chrome-devtools
圖2: CPU 節流,藍色框區域工具
注意:在測試其餘頁面時,若是要確保它們在低端移動設備上工做良好,請將CPU節流設置爲減速20倍。這個演示不能很好地使用20倍的減速,因此它只使用2倍的減速做爲教學目的。
很難爲本網站的全部讀者建立一致的運行時性能演示。本節容許你自定義演示,以確保你的體驗與你在本教程中看到的屏幕截圖和描述相對一致,而無論你的特定設置如何。
注意:若是你看不到優化版本和未優化版本之間的明顯差別,請嘗試單擊 Subtract 10 幾回,而後再試一次。若是你添加太多的藍色方塊,至關於把CPU都幾乎佔滿了,就看不到優化和不優化版本的差別。
當你運行優化版本時,藍色方塊移動得更快。爲何?兩個版本都應該在相同的時間內,將每一個方塊移動相同的距離。在性能面板中錄製,學習如何檢測未優化版本中的性能瓶頸。
在 DevTools 中,單擊 Record(左上角灰色圓圈)。DevTools 會捕捉頁面運行時的性能指標。
圖3:頁面記錄中
等待幾秒
單擊 Stop,DevTools 中止記錄,分析數據,而後會將分析結果展現在性能面板中。
圖4:分析的結果
哇,這麼多的數據。別慌,很快咱們就知道具體的含義了。
一旦你拿到了頁面的性能分析數據,你會發現這個頁面的性能到底有多差,而且找到致使頁面性能差的緣由。
衡量任何動畫性能的主要指標就是幀率(FPS)。當動畫以60 fps的速度運行時,用戶會很爽。
注意FPS圖表。只要你看到一條紅條,就意味着低幀率,進而影響用戶體驗。一般來講,綠色的柱條越高,表明幀率越高。
圖5:藍框內的FPS圖表
在FPS圖表下方,你能夠看到CPU圖表。CPU圖表中的顏色與「性能」面板底部的 Summary 選項卡中的顏色相對應。CPU 圖表充滿顏色意味着CPU在記錄過程當中達到了最大負載。每當你看到CPU長時間達到最大負載時,這是進行優化的一個很好的提示。
圖6:藍框內的 CPU 圖表和 Summary(摘要欄)
將鼠標懸停在 FPS、CPU 或 NET 圖表上。DevTools 顯示該頁面在該時間點的屏幕截圖。向左和向右移動鼠標以重放記錄過程。這稱爲 scrubbing,它對於手動分析動畫過程頗有用。
圖7:查看頁面在2000ms左右時的屏幕截圖
在 Frames 區域中,將鼠標懸停在其中一個綠色方塊上。DevTools 向你顯示該特定幀的 FPS。每幀可能遠遠低於60 FPS。
圖8:鼠標懸停在一幀上
固然,在這個 DEMO 中,很明顯這個頁面的性能不是很好。可是在真實的場景中,咱們不必定能一眼分辨出一個頁面的性能好壞,因此使用這些工具來進行測量分析是很方便的。
如今你已經測量並驗證了頁面動畫表現不佳,接下來要回答的問題是:爲何?
注意 Summary 選項卡,在未選擇任何事件時,它呈現了瀏覽器在整個記錄過程當中把時間花在哪一個部分。能夠看到,頁面的大部分時間都花在渲染上。因此如今的目標就是:減小瀏覽器花費在渲染工做上的時間。
圖10:藍框內的 Summary 選項卡
展開 Main 區域,DevTools 向你展現了一段時間內主線程上活動圖。x 軸表明着這段時間內的記錄,每個 Bar 都表明了一個事件。Bar 越寬,意味着該活動花費的時間更長。y軸表示調用堆棧,當你看到事件堆疊在一塊兒時,這意味着上面的事件致使了下面的事件。
圖11:藍框內的 Main 區域
記錄過程當中有不少數據。在 OverView 面板(有 CPU, FPS, NET 圖表的區域)上,用鼠標單擊、按住、拖拽來放大單個 Animation Frame Fired 事件。此時 Main 和 Summary 中展現了選中的區間的相關信息。
圖12:放大單個 Animation Frame Fired 事件
提示:你也能夠經過單擊 Main 中的某個事件後,經過鼠標的滾輪或者 W,S,A,D 鍵實現單個事件的縮放。
注意在 Animation Frame Fired 事件右上角的紅三角。只要你看到了紅三角,這個事件就可能形成嚴重的問題。
提示:每當
requestAnimationFrame()
回調調用時, 都會觸發 Animation Frame Fired 事件
單擊某個 Animation Frame Fired 事件, Summary 中會展現與該事件相關的信息. 注意 reveal 連接,單擊後,DevTools 會將觸發當前的 Animation Frame Fired 事件的事件高亮出來。同時注意 app.js:94 連接,單擊後跳轉到相應的源碼。
圖13: 查看 Animation Frame Fired 事件的詳細信息
提示:選中一個事件以後,用左右方向鍵能夠跳轉到上/下一個事件
在 app.update 事件下,有一堆紫色事件。稍微放大,看起來每一個均可能有一個紅色的三角形。如今單擊其中一個紫色事件。DevTools 在 Summary 中提供了有關事件的詳細信息。能夠看到,有一個關於強制迴流(forced reflows)的警告(也就是 Layout 的另外一種說法)。
在 Summary 中,單擊 Layout Forced 下的 app.js:70 連接,DevTools 會跳轉到引起強制迴流的源代碼。
圖14:致使強制迴流的源代碼
注意:這行代碼的問題在於:修改了藍塊樣式以後,馬上讀取藍塊 offsetTop 值。此時樣式變動,而offsetTop 值是上一幀的值,瀏覽器爲了保證讀取 offsetTop 值的準確性,會先處理樣式變動,而後從新佈局以計算準確的 offsetTop 值,而從新佈局(迴流)的性能開銷是很大的。參考:Avoid_forced_synchronous_layouts
使用剛剛學習的工做流和工具,單擊演示中的優化以啓用優化的代碼,進行另外一次性能記錄,而後分析結果。從改進的幀率到 Main 中的活動圖表中事件的減小,你能夠看到應用程序的優化版本作的工做少得多,從而帶來更好的性能。
app.update = function (timestamp) {
for (var i = 0; i < app.count; i++) {
var m = movers[i];
if (!app.optimize) { // 1.普通版本
var pos = m.classList.contains('down') ?
m.offsetTop + distance : m.offsetTop - distance; // 讀取offsetTop, 變動樣式
if (pos < 0) pos = 0;
if (pos > maxHeight) pos = maxHeight;
m.style.top = pos + 'px';
if (m.offsetTop === 0) { // 樣式變動後讀取 offsetTop,致使迴流
m.classList.remove('up');
m.classList.add('down');
}
if (m.offsetTop === maxHeight) { // 樣式變動後讀取 offsetTop,致使迴流
m.classList.remove('down');
m.classList.add('up');
}
} else { // 2.優化版本
var pos = parseInt(m.style.top.slice(0, m.style.top.indexOf('px')));
m.classList.contains('down') ? pos += distance : pos -= distance; // 經過讀取top,來獲取原來藍塊的位置,避免讀取 offsetTop
if (pos < 0) pos = 0;
if (pos > maxHeight) pos = maxHeight;
m.style.top = pos + 'px';
if (pos === 0) { // 樣式變動後用從樣式 top 中讀取到的位置信息進行判斷,避免讀取 offsetTop
m.classList.remove('up');
m.classList.add('down');
}
if (pos === maxHeight) {
m.classList.remove('down');
m.classList.add('up');
}
}
}
frame = window.requestAnimationFrame(app.update);
}
複製代碼
注意:優化版本的代碼雖然不會觸發迴流(Layout),但依然會觸發重繪(Paint)。一個更好的解決方案是使用只會觸發**合成(Composite)**的屬性,例如: transform 和 opacity。
瞭解性能的基礎是軌道模型(The RAIL model)。這個模型告訴你對你的用戶來講最重要的性能指標。有關詳細信息,請參見 Measure Performance With The RAIL Model 。
爲了讓性能面板更溫馨,熟能生巧。嘗試分析本身的頁面並分析結果。若是你對結果有任何疑問,去Stack Overflow 提出關於 google-chrome-devtools 的問題。若是可能,包括可複製頁面的截圖或連接。
要真正掌握運行時性能,你必須瞭解瀏覽器如何將HTML、CSS和JS轉換爲屏幕上的像,能夠參考: Rendering Performance Overview. 這篇文章則更加深刻:The Anatomy Of A Frame
最後,有許多方法能夠提升運行時性能。本教程將重點放在一個特定的動畫瓶頸上,讓你經過性能面板進行重點介紹,但這只是你可能遇到的衆多瓶頸之一。如何提高頁面運行時的性能還能夠參考如下關於渲染性能的文章: