效能觀察工具 - 有效率地存取成效資料

Marc Cohen

漸進式網頁應用程式可讓開發人員打造新型應用程式,提供可靠、高效能的使用者體驗。但為了確保網頁應用程式能達到想要的成效目標,開發人員需要存取高解析度的效能評估資料。W3C 效能時間軸規格定義了這類瀏覽器的介面,以透過程式輔助的方式存取低階資料。進而開拓更多有趣的用途:

  • 離線和自訂效能分析
  • 第三方成效分析和視覺化工具
  • 整合至 IDE 和其他開發人員工具的效能評估

在大部分的主要瀏覽器中,現在都針對導覽時間資源時間使用者時間存取這類時間資料。最新的新增項目是效能觀察器介面,基本上是一種串流介面,可將瀏覽器收集到的資訊以非同步方式收集。相較於先前的方法,這個新介面提供許多重要優點,以利存取時間軸:

  • 如今,應用程式必須定期進行輪詢,並比較儲存的測量結果,而這會產生高昂成本。此介面提供回呼。(換句話說,不需要進行輪詢)。因此,使用這個 API 的應用程式反應速度更快,效率也更高。
  • 這項機制不受緩衝區限制 (多數緩衝區預設會設為 150 個項目),並避免需要修改緩衝區的不同消費者之間的競爭狀況。
  • 效能觀測器通知會以非同步方式傳送,且瀏覽器可在閒置期間分派通知,避免與重要的轉譯工作相互競爭。

自 Chrome 52 版起,效能觀察器介面預設為啟用。一起來看看如何運用這項功能。

<html>
<head>
    <script>
    var observer = new PerformanceObserver(list => {
        list.getEntries().forEach(entry => {
        // Display each reported measurement on console
        if (console) {
            console.log("Name: "       + entry.name      +
                        ", Type: "     + entry.entryType +
                        ", Start: "    + entry.startTime +
                        ", Duration: " + entry.duration  + "\n");
        }
        })
    });
    observer.observe({entryTypes: ['resource', 'mark', 'measure']});
    performance.mark('registered-observer');

    function clicked(elem) {
        performance.measure('button clicked');
    }
    </script>
</head>
<body>
    <button onclick="clicked(this)">Measure</button>
</body>
</html>

這個簡單的網頁是以定義一些 JavaScript 程式碼的指令碼標記開頭:

  • 我們會將新的 PerformanceObserver 物件例項化,並將事件處理常式函式傳遞至物件建構函式。建構函式會初始化該物件,讓系統在每次有一組新的測量資料可供處理時 (以物件清單的形式傳遞測量資料) 呼叫處理常式。處理常式在此定義為匿名函式,只會在主控台中顯示格式化的測量資料。在實際情境中,這類資料可能會儲存在雲端進行後續分析,或填入互動式視覺化工具。
  • 我們會透過 observe() 方法註冊我們感興趣的時間事件類型,並呼叫 mark() 方法以標記我們註冊的即時事件,這會將時間間隔的開始納入考量。
  • 我們會為頁面主體中定義的按鈕定義點擊處理常式。這個點擊處理常式會呼叫 measure() 方法,擷取按鈕點選時間的相關時間資料。

請在頁面的主體中定義按鈕,將點擊處理常式指派給 onclick 事件,接著就可以開始作業了。

現在,如果我們載入網頁並開啟 Chrome 開發人員工具面板來觀看 JavaScript 控制台,每當我們點選按鈕時,系統就會測量一次效能。由於我們註冊觀察這類測量數據,因此會以非同步的方式轉送到事件處理常式,而不需要輪詢時間軸,在主控台顯示測量結果時:

效能觀察工具。

start 值代表 mark 類型事件 (這個應用程式只有一個事件) 的開始時間戳記。measure 類型的事件沒有本身的開始時間;代表相對於最後一個 mark 事件進行的時間測量。因此,此處顯示的時間長度值代表呼叫 mark() 之間的時間長度值,做為一般間隔的起點,以及多次呼叫 measure() 之間的經過時間。

如您所見,這個 API 非常簡單,且可讓您收集經過篩選的高解析度即時效能資料,而無需輪詢,這應該能為網頁應用程式提供更有效率的效能工具。