0%

【文章翻譯】Performance testing on the web

【文章內容使用 Gemini 1.5 Pro 自動產生】

網頁上的效能測試

本文於 2020 年 11 月 25 日更新,以使用 `web_benchmarks` 套件。

概觀

在開發過程中,我們經常希望在瀏覽器中測試應用程式的效能。效能測試很有用,因為它可以揭露可能導致應用程式變慢的潛在錯誤。

本文介紹了一種在 Chrome 中測試應用程式效能的方法。此方法類似於我們測試 新的 Flutter Gallery 效能的方式。

範例應用程式

我們使用一個簡單的應用程式,其中包含一個 appbar、一個浮動動作按鈕和一個無限項目列表。列表還顯示按鈕被按下次數。

應用程式有一個包含一些資訊的第二頁。

您可以在這裡複製應用程式:

測試什麼?

我們希望在以下使用情境下測試應用程式在 Chrome 中的效能:

  1. 使用者在無限列表中捲軸。
  2. 使用者在兩個頁面之間切換。
  3. 使用者點擊浮動動作按鈕。

設定框架

pubspec.yaml 中加入以下內容:

此相依性會導入 web_benchmarks,一個實現 Chrome 中效能測試的最小套件。

此套件改編自 macrobenchmarksdevicelab,這兩個套件由 Flutter 用於在 Flutter Gallery 上進行網頁效能測試。目前,這兩個套件專門用於 flutter/flutter 中的網頁效能測試,因此導入更通用的套件 web_benchmarks 更容易。

執行 flutter pub get 以導入此套件。

撰寫第一個測試

lib 目錄下加入 benchmarks 目錄,並在其中加入一個名為 runner.dart 的新 dart 檔案:

檔案的內容如下:

此測試在做什麼?

  • 當此應用程式執行時,會建立一個 ScrollRecorder 物件,它會透過自動執行手勢來驅動應用程式。在本例中,在應用程式啟動後不久,它會開始向下捲軸無限列表。
  • ScrollRecorder 類別擴展了 AppRecorder 類別,AppRecorder 類別擴展了 WidgetRecorder 類別,WidgetRecorder 類別還會在驅動應用程式時記錄效能資料。
  • runBenchmarks 是在 package:web_benchmarks/client.dart 中定義的函式,它允許使用者選擇要執行的基準測試,並在瀏覽器中顯示結果。
  • automate 方法使用 flutter_test 套件,該套件提供了在應用程式中執行手勢或尋找特定 Widget 的方法。

執行第一個測試

在專案的根目錄中,執行 flutter run -d chrome -t lib/benchmarks/runner.dart。這會指示 Flutter 使用 runner.dart 作為入口點,而不是 main.dart

到目前為止,我們只有一個基準測試,因此點擊「捲軸」以啟動它。

測試開始,列表會自動向下捲軸。

測試在幾秒鐘內結束,顯示以下螢幕:

此圖表顯示應用程式繪製每個(記錄的)畫面所需的時間。橫軸表示時間流逝;縱軸表示每個畫面所需的時間。

圖表的前 2/3 部分具有灰色背景;這些畫面被認為是「預熱畫面」,並且從統計資料中省略。預熱畫面通常會讓 JIT 編譯器有時間編譯程式碼並建立各種快取,以便測量畫面能產生反映應用程式「最終」效能的數字,而不是它最初幾秒鐘的效能。預熱階段不應始終被忽略 - 它可以提供應用程式最初幾秒鐘效能的寶貴資訊,這仍然會影響對應用程式品質的感知。

紅色畫面是「異常值」 - 它們是繪製時間比其他畫面顯著長得多的畫面。有些異常值幾乎不可察覺。例如,動畫開始或結束時的卡頓,直到一定程度才會被看見。但是,動畫 中間 的卡頓畫面非常明顯。

異常值很好地表明了應用程式卡頓的程度。透過改進您的應用程式,您可以降低異常值的數值或減少異常值的數量,這表示您的應用程式已變得更流暢。

從 Chrome 的 DevTools 收集資料

此基準測試完全在 Chrome 中執行。將以下檔案新增為 test/run_benchmarks.dart

然後,執行 dart test/run_benchmarks.dart

大約一分鐘後,您應該看到以下結果:

準確的基準測試數值可能會因機器而異。

此測試在做什麼?

  • 執行 test/run_benchmarks.dart 會為網頁構建應用程式。然後,它會啟動一個 Chrome 實例並在其中執行應用程式。
  • test/run_benchmarks.dart 會連接到 Chrome 的 DevTools 連接埠,並監聽和收集相關的效能資料。

結果的含義是什麼?

  • 渲染畫面時,會走訪 層級樹 兩次。
  • 「預先處理」是第一次走訪。它不會渲染任何內容,但會計算稍後用於渲染的值。例如:轉換矩陣、轉換的逆矩陣和剪裁。
  • 「應用程式畫面」是實際渲染 UI 的第二次走訪。
  • 「繪製畫面」是框架渲染畫面所需的時間。它包含「預先處理」和「應用程式畫面」,但它還包含花費在構建和佈局 Widget 上的時間。
  • 「總 UI 畫面」包含「繪製畫面」中的所有內容,但它還包含瀏覽器執行的某些隱藏工作,例如層級樹更新、樣式重新計算和瀏覽器端佈局(不要與 Flutter 自己進行的佈局混淆)。
  • 收集資料集(持續時間列表)時,演算法會移除異常值。
  • 首先,計算資料的平均值和標準差,並且任何比(平均值 + 1 個標準差)高的資料點都被視為異常值。
  • 非異常值(乾淨資料)的平均值和標準差用於計算資料集的平均值和雜訊,然後報告這些值。
  • 所有異常值的平均值以及「異常值平均值」和「非異常值平均值」的比率也會被報告。
  • 對於每個資料集,「異常值比率」和「雜訊」都是應用程式效能中存在多少雜訊的良好指標。如果結果過於雜亂,則可能表示效能不一致(例如,GC 暫停時的卡頓畫面)。透過降低雜訊,您可以使應用程式執行更順暢。

加入更多測試

編輯 lib/benchmarks/runner.dart 以加入兩個更多測試。

首先,修改 main 函式:

最後,加入兩個更多擴展 AppRecorder 的類別:

這些測試在做什麼?

  • 我們加入了兩個剩餘的基準測試:一個用於在頁面之間切換,另一個用於點擊浮動動作按鈕。
  • animationStops 反覆檢查動畫是否正在進行,並在所有動畫停止時停止。這會確保,例如,成功轉換到「關於」頁面。
  • 在「頁面」和「點擊」基準測試中,_completed 布林值追蹤自動手勢是否已完成。
  • 在「頁面」和「點擊」基準測試中,覆寫 shouldContinue 方法會導致 AppRecorder 所有手勢完成 停止記錄畫面。

如何執行這些測試?

若要在 Chrome 中執行這些測試(並查看動畫),請執行:

  • flutter run -d chrome -t lib/benchmarks/runner.dart --profile

若要執行這些測試並收集 DevTools 資料,請執行:

  • dart test/run_benchmarks.dart

接下來要做什麼?

在您有方法收集效能資料後,您可以隨意使用它:

  • 您可以為 CI 設定一個作業,只要有人提交 PR 就執行這些基準測試,以避免引入效能負擔大的變更。
  • 您也可以設定一個儀表板來追蹤效能基準測試的趨勢。這就是我們對 Flutter Gallery 所做的事情(請參閱 Flutter Dashboard)。


網頁上的效能測試 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。