我們建構成效深入分析的方式和原因

Chrome 102 中,您會在開發人員工具中看到新的實驗性面板「效能深入分析」。在本篇文章中,我們將討論為何我們一直在開發新的面板,以及我們面臨的技術挑戰和做出的決策。

ALT_TEXT_HERE

為何要建立另一個面板?

(如果您尚未觀看,我們發布了一段影片,說明為何要建立「成效深入分析」面板,以及如何透過該面板取得可採取行動的網站成效洞察資料)。

現有的成效面板是您想集中查看網站所有資料的絕佳資源,但我們認為這可能會讓您感到有些吃力。如果你不是效能專家,就很難確切知道要尋找什麼,以及錄製內容的哪些部分與效能相關。

進入「深入分析」面板後,您仍可查看追蹤記錄的時間軸並檢查資料,但也會看到 DevTools 認為值得深入探討的主要「深入分析」項目清單。洞察功能會找出各種問題,例如轉譯阻擋要求、版面配置變更和長時間工作,這些問題都可能對網站的網頁載入效能造成負面影響,特別是網站的 Core Web Vitals (CWV) 分數。除了標示問題,成效深入分析也會提供可行的建議,協助您改善 CWV 分數,並提供其他資源和說明文件的連結。

面板中的意見回饋連結

這個面板屬於實驗性質,歡迎提供意見!如果您遇到任何錯誤,或有任何有助於改善網站效能的功能要求,請與我們聯絡。

成效深入分析的建立方式

如同其他 DevTools,我們使用 TypeScript 建構 Performance Insights,並使用 網頁元件 (由 lit-html 提供支援) 建構使用者介面。成效洞察的不同之處在於,主要 UI 介面是 HTML canvas 元素,而時間軸會繪製到這個畫布上。管理這個畫布的複雜性,不僅是將正確的細節繪製在正確的位置,還要管理滑鼠事件 (例如:使用者在畫布上點選的位置為何?是否點選了我們繪製的事件?),並確保有效重新算繪畫布。

單一畫布上的多個軌道

針對特定網站,我們會算繪多個「軌跡」,每個軌跡代表不同的資料類別。舉例來說,洞察面板預設會顯示三個軌道:

隨著我們持續在資訊面板中推出新功能,我們預計會新增更多軌道。

我們最初的想法是讓每個軌道都算繪自己的 <canvas>,讓主要檢視畫面成為垂直堆疊的多個畫布元素。這麼做可簡化音軌層級的算繪作業,因為每個音軌都能單獨算繪,且不會有音軌算繪超出其邊界的問題,但這種做法有兩個主要問題:

canvas 元素的算繪/重新算繪作業成本較高;即使單一畫布較大,多個畫布的成本仍會更高。在多個軌道上算繪任何疊加層 (例如用來標示 FCP 時間等事件的垂直線) 會變得複雜:我們必須在多個畫布上算繪,並確保所有畫布都算繪在一起且正確對齊。

使用一個 canvas 來處理整個 UI,意味著我們需要找出如何確保每個軌跡都能在正確的座標處算繪,且不會溢位到其他軌跡。舉例來說,如果某個特定軌道的高度為 100 像素,我們就無法讓該軌道算繪出 120 像素高的內容,並讓該內容溢出至下方的軌道。如要解決這個問題,我們可以使用 clip。在轉譯每個軌跡之前,我們會繪製代表可見軌跡視窗的矩形。這樣一來,繪製在這些邊界以外的任何路徑都會遭到畫布裁剪。

canvasContext.beginPath();
canvasContext.rect(
    trackVisibleWindow.x, trackVisibleWindow.y, trackVisibleWindow.width, trackVisibleWindow.height);
canvasContext.clip();

我們也不希望每個音軌都必須知道自己的垂直位置:每個音軌都應以 (0, 0) 的座標顯示,我們有一個較高層級的元件 (稱為 TrackManager) 來管理整體音軌位置。您可以使用 translate 完成這項操作,該函式會根據指定的 (x, y) 位置轉譯畫布。例如:

canvasContext.translate(0, 10); // Translate by 10px in the y direction
canvasContext.rect(0, 0, 10, 10); // draw a rectangle at (0, 0) that’s 10px high and wide

雖然 rect 程式碼將 0, 0 設為位置,但套用的整體轉譯會導致矩形在 0, 10 處算繪。這樣一來,我們就能以軌道為單位進行作業,就像在 (0, 0) 處轉譯一樣,並讓軌道管理員在轉譯每個軌道時進行轉譯,確保每個軌道都能正確轉譯在前一個軌道下方。

用於曲目和精選內容的螢幕外畫布

轉換為畫布相對耗時,因此我們希望確保洞察資料板在您使用時,能保持流暢及回應迅速。有時您可能無法避免重新轉譯整個畫布:例如,如果您變更縮放比例,我們就必須重新開始並重新轉譯所有內容。您無法只重新繪製其中的一小部分,因此無論如何,您都必須清除整個畫布並重新繪製,因此畫布重新繪製作業的成本特別高。這與 DOM 重新轉譯不同,因為工具可以計算所需的最少工作量,而不會移除所有內容並重新開始。

我們在視覺效果方面遇到的問題之一,就是醒目顯示。當您將游標懸停在窗格中的指標上時,我們會在時間軸上醒目顯示這些指標。同樣地,如果您將游標懸停在特定事件的洞察資料上,我們會在該事件周圍繪製藍色邊框。

這項功能最初是透過偵測滑鼠在觸發醒目顯示的元素上移動,然後直接在主要畫布上繪製醒目顯示畫面來實作。當我們必須移除醒目顯示時,就會遇到問題:唯一的選項就是重新繪製所有內容!我們無法只重新繪製醒目顯示的區域 (除非要進行重大的架構變更),但如果只是為了移除某個項目周圍的藍色邊框,重新繪製整個畫布似乎有點過頭。此外,如果快速移動滑鼠游標至不同項目,以便快速觸發多個醒目顯示,也會造成視覺延遲。

為解決這個問題,我們將 UI 分割成兩個離螢幕外的畫布:用於渲染軌跡的「主」畫布,以及用於繪製重點的「重點」畫布。接著,我們會將這些畫布複製到使用者在螢幕上看到的單一畫布上,以便進行算繪。我們可以在畫布內容上使用 drawImage 方法,這可使用其他畫布做為來源。

這表示移除醒目顯示不會導致主畫布重新繪製:我們可以清除畫面上的畫布,然後將主畫布複製到可見的畫布上。複製畫布的成本很低,繪製畫面才會耗費大量資源;因此,將醒目顯示移至另一個畫布,就能避免開啟和關閉醒目顯示時的成本。

全面測試追蹤記錄剖析

從頭開始建構新功能的好處之一,就是您可以反思先前做出的技術選擇,並加以改善。我們希望改善的其中一項內容,是明確將程式碼分成兩個幾乎完全不同的部分:

剖析追蹤記錄檔並提取所需資料。算繪一組音軌。

將剖析 (第 1 部分) 與 UI 作業 (第 2 部分) 分開,可讓我們建立穩固的剖析系統;每個追蹤記錄都會透過一系列 Handler 執行,這些 Handler 負責處理不同的問題:LayoutShiftHandler 會計算我們在版面配置位移作業中需要的所有資訊,而 NetworkRequestsHandler 則專門處理網路要求的提取作業。在這個明確的剖析步驟中,我們有不同的處理程序負責追蹤記錄的不同部分,這也是有益的做法:追蹤記錄剖析作業可能會變得非常複雜,因此我們可以一次專注於一項問題。

我們也能透過在開發人員工具中錄製、儲存,然後將錄製內容載入至測試套件的做法,全面測試追蹤剖析功能。這麼做很棒,因為我們可以使用實際的追蹤記錄進行測試,而不會累積大量可能過時的假追蹤記錄資料。

畫布 UI 的螢幕截圖測試

回到測試主題,我們通常會將前端元件轉譯至瀏覽器,並確保其行為符合預期,藉此測試前端元件;我們可以發送點擊事件來觸發更新,並斷言元件產生的 DOM 是否正確。這個方法對我們來說相當實用,但在考慮轉譯至無框畫時,就會失效,因為我們無法檢查無框畫並判斷其中繪製的內容!因此,我們通常採用的算繪及查詢方法並不適合。

為了讓我們有一定的測試涵蓋率,我們轉向螢幕截圖測試。每個測試都會啟動畫布、算繪要測試的軌跡,然後擷取畫布元素的螢幕截圖。系統會將這個螢幕截圖儲存在程式碼庫中,日後執行測試時,系統會將儲存的螢幕截圖與產生的螢幕截圖進行比較。如果螢幕截圖不同,測試就會失敗。我們也提供標記,可在我們刻意變更算繪作業並需要更新測試時,執行測試並強制更新螢幕截圖。

螢幕截圖測試並非完美無缺,而且有點直白;您只能測試整個元件是否如預期顯示,而非更具體的斷言。我們一開始過度使用這些斷言,以確保每個元件 (HTML 或畫布) 都能正確顯示。這會大幅減緩測試套件的速度,並導致以下問題:微小且幾乎無關的 UI 調整 (例如微妙的顏色變更,或在項目間增加一些邊距) 會導致多個螢幕截圖失敗,並需要更新。我們現在已縮減螢幕截圖的使用量,並將其用於純粹以畫布為基礎的元件,目前這項平衡做法對我們來說相當有效。

結論

團隊在建構全新「效能深入分析」面板時,獲得了非常有趣且實用的經驗。我們已瞭解許多關於追蹤記錄檔的知識,也學會如何使用畫布等等。希望你喜歡新的面板,也期待收到你的意見回饋。

如要進一步瞭解「效能深入分析」面板,請參閱「效能深入分析:取得可做為行動依據的網站效能洞察資料」。

下載預覽管道

建議您將 Chrome Canary開發人員版Beta 版設為預設開發人員版瀏覽器。這些預覽管道可讓您存取最新的 DevTools 功能,測試最新的網路平台 API,並在使用者發現問題前,協助您找出網站的問題!

與 Chrome 開發人員工具團隊聯絡

請使用下列選項討論新功能、更新或任何與開發人員工具相關的內容。