學習使用Chrome性能分析工具(譯)

原文地址: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算力比臺式機和筆記本電腦小得多。不管什麼時候評測頁面,均可以使用CPU調節來模擬頁面在移動設備上的表現。chrome-devtools

  1. 在DevTools中,單擊 Performance 選項卡。
  2. 確保選中了 Screenshots
  3. 單擊 Capture Settings(設置按鈕)。其中包含了捕獲性能指標相關的設置。
  4. 對於 CPU選項,選擇 2x slowdown。DevTools會進行 CPU 節流,使其比平時慢2倍。

圖2: CPU 節流,藍色框區域工具

注意:在測試其餘頁面時,若是要確保它們在低端移動設備上工做良好,請將CPU節流設置爲減速20倍。這個演示不能很好地使用20倍的減速,因此它只使用2倍的減速做爲教學目的。

配置 Demo

很難爲本網站的全部讀者建立一致的運行時性能演示。本節容許你自定義演示,以確保你的體驗與你在本教程中看到的屏幕截圖和描述相對一致,而無論你的特定設置如何。

  1. 繼續單擊 Add 10,直到藍色方塊移動明顯比之前慢。在高端機器上,可能須要大約20次點擊。
  2. 單擊 Optimize,藍色方塊應該移動得更快更流暢。
  3. 單擊 Un-Optimize,藍色方塊應該移動得更慢且更加卡頓

注意:若是你看不到優化版本和未優化版本之間的明顯差別,請嘗試單擊 Subtract 10 幾回,而後再試一次。若是你添加太多的藍色方塊,至關於把CPU都幾乎佔滿了,就看不到優化和不優化版本的差別。

記錄運行時的頁面性能

當你運行優化版本時,藍色方塊移動得更快。爲何?兩個版本都應該在相同的時間內,將每一個方塊移動相同的距離。在性能面板中錄製,學習如何檢測未優化版本中的性能瓶頸。

  1. 在 DevTools 中,單擊 Record(左上角灰色圓圈)。DevTools 會捕捉頁面運行時的性能指標。

    圖3:頁面記錄中

  2. 等待幾秒

  3. 單擊 Stop,DevTools 中止記錄,分析數據,而後會將分析結果展現在性能面板中。

    圖4:分析的結果

    哇,這麼多的數據。別慌,很快咱們就知道具體的含義了。

分析結果

一旦你拿到了頁面的性能分析數據,你會發現這個頁面的性能到底有多差,而且找到致使頁面性能差的緣由。

分析幀率

衡量任何動畫性能的主要指標就是幀率(FPS)。當動畫以60 fps的速度運行時,用戶會很爽。

  1. 注意FPS圖表。只要你看到一條紅條,就意味着低幀率,進而影響用戶體驗。一般來講,綠色的柱條越高,表明幀率越高。

    圖5:藍框內的FPS圖表

  2. 在FPS圖表下方,你能夠看到CPU圖表。CPU圖表中的顏色與「性能」面板底部的 Summary 選項卡中的顏色相對應。CPU 圖表充滿顏色意味着CPU在記錄過程當中達到了最大負載。每當你看到CPU長時間達到最大負載時,這是進行優化的一個很好的提示。

    圖6:藍框內的 CPU 圖表和 Summary(摘要欄)

  3. 將鼠標懸停在 FPS、CPU 或 NET 圖表上。DevTools 顯示該頁面在該時間點的屏幕截圖。向左和向右移動鼠標以重放記錄過程。這稱爲 scrubbing,它對於手動分析動畫過程頗有用。

    圖7:查看頁面在2000ms左右時的屏幕截圖

  4. Frames 區域中,將鼠標懸停在其中一個綠色方塊上。DevTools 向你顯示該特定幀的 FPS。每幀可能遠遠低於60 FPS。

    圖8:鼠標懸停在一幀上

    固然,在這個 DEMO 中,很明顯這個頁面的性能不是很好。可是在真實的場景中,咱們不必定能一眼分辨出一個頁面的性能好壞,因此使用這些工具來進行測量分析是很方便的。

查出性能瓶頸的根源

如今你已經測量並驗證了頁面動畫表現不佳,接下來要回答的問題是:爲何?

  1. 注意 Summary 選項卡,在未選擇任何事件時,它呈現了瀏覽器在整個記錄過程當中把時間花在哪一個部分。能夠看到,頁面的大部分時間都花在渲染上。因此如今的目標就是:減小瀏覽器花費在渲染工做上的時間。

    圖10:藍框內的 Summary 選項卡

  2. 展開 Main 區域,DevTools 向你展現了一段時間內主線程上活動圖。x 軸表明着這段時間內的記錄,每個 Bar 都表明了一個事件。Bar 越寬,意味着該活動花費的時間更長。y軸表示調用堆棧,當你看到事件堆疊在一塊兒時,這意味着上面的事件致使了下面的事件。

    圖11:藍框內的 Main 區域

  3. 記錄過程當中有不少數據。在 OverView 面板(有 CPU, FPS, NET 圖表的區域)上,用鼠標單擊、按住、拖拽來放大單個 Animation Frame Fired 事件。此時 MainSummary 中展現了選中的區間的相關信息。

    圖12:放大單個 Animation Frame Fired 事件

    提示:你也能夠經過單擊 Main 中的某個事件後,經過鼠標的滾輪或者 W,S,A,D 鍵實現單個事件的縮放。

  4. 注意在 Animation Frame Fired 事件右上角的紅三角。只要你看到了紅三角,這個事件就可能形成嚴重的問題。

    提示:每當 requestAnimationFrame() 回調調用時, 都會觸發 Animation Frame Fired 事件

  5. 單擊某個 Animation Frame Fired 事件, Summary 中會展現與該事件相關的信息. 注意 reveal 連接,單擊後,DevTools 會將觸發當前的 Animation Frame Fired 事件的事件高亮出來。同時注意 app.js:94 連接,單擊後跳轉到相應的源碼。

    圖13: 查看 Animation Frame Fired 事件的詳細信息

    提示:選中一個事件以後,用左右方向鍵能夠跳轉到上/下一個事件

  6. app.update 事件下,有一堆紫色事件。稍微放大,看起來每一個均可能有一個紅色的三角形。如今單擊其中一個紫色事件。DevTools 在 Summary 中提供了有關事件的詳細信息。能夠看到,有一個關於強制迴流(forced reflows)的警告(也就是 Layout 的另外一種說法)。

  7. 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。

參考: Use transform and opacity changes for animations

下一步

瞭解性能的基礎是軌道模型(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

最後,有許多方法能夠提升運行時性能。本教程將重點放在一個特定的動畫瓶頸上,讓你經過性能面板進行重點介紹,但這只是你可能遇到的衆多瓶頸之一。如何提高頁面運行時的性能還能夠參考如下關於渲染性能的文章:

相關文章
相關標籤/搜索