Web性能API - 幫你分析Web前端性能
開發一個現代化的互聯網網站是一項復雜的任務,需要各種職能的密切合作以應對用戶日新月異的需求。其中,網頁的性能直接決定了用戶的體驗,而隨著新型客戶端瀏覽設備的出現與網站功能的日益復雜化,對于性能的專注也達到了前所未有的高度。
傳統的網站性能監測通常有以下幾種方式:
- 借助傳統的開發者工具查看網絡請求,例如瀏覽器的F12工具、 Fiddler 、 Charles 等等。基本方式是通過追蹤HTTP請求與響應的時間,以圖形的方式列出所有資源的下載情況。這種方式依賴于人為操作,難以實現批量測試與統計。
- 使用侵入式的JavaScript代碼檢測DOM事件的發生時間。例如DOMContentLoaded和 document.onreadystatechange等等。這種方式會在頁面中引入額外的代碼,加重了開發者與測試人員的負擔,還有可能因為檢測代碼 本身的潛在問題影響頁面的性能。
- 使用第三方的服務與工具,例如 WebPagetest 、Pingdom等等,這些服務通常能夠實現在不同瀏覽器和不同地域進行測試,并且為用戶提供一些優化建議。但某些服務需要排隊等待,并且多次測試結果之間往往區別較大。第一條方式的問題也同樣存在。
除此之外,以上各種方式的測量指標都比較單一,基本只能起到計時和流量計算的作用。對于其它一些指標,例如電池狀態等無能為力。并且難以實現自動化,以及在持續集成流程中統計測試結果。
W3C Web性能工作小組與各瀏覽器廠商都已認識到性能對于web開發的重要性,為了解決當前性能測試的困難,W3C推出了一套 性能API 標準,各種瀏覽器對這套標準的支持如今也逐漸成熟起來。這套API的目的是簡化開發者對網站性能進行精確分析與控制的過程,最終實現性能的提高。其中還包括了一些新協議與HTML元素的提議,目的是讓內容的展現更快、更加優化。
性能API示例
整套標準包含了10余種API,各自針對性能檢測的某個方面。為了保證整套標準的質量與互操作性,W3C按照慣例對它們應用了 規范成熟度 流程,這些API各自處于流程的不同階段。在下圖中可以看到它們當前的進展:
以下將通過簡單的示例介紹目前已屬于W3C推薦標準(REC)的三個API。
Navigation Timing (導航計時)
Navigation Timing API 能夠幫助網站開發者檢測真實用戶數據(RUM),例如帶寬、延遲或主頁的整體頁面加載時間。開發者可以用以下JavaScript代碼檢測頁面的性能:
varpage = performance.timing, plt = page.loadEventStart - page.navigationStart, console.log(plt); // Page load time (PTL) output for specific browser/user in ms
需要注意的是,Navigation Timing的目的是用于分析頁面整體性能指標。如果要獲取個別資源(例如JS、圖片)的性能指標,請使用Resource Timing API。
W3C剛剛宣布了 Navigation Timing 2 ,它將替代之前的版本。
High Resolution Timing(高精度計時)
該API 規范所定義的JavaScript接口能夠提供精確到微秒級的當前時間,并且不會受到系統時鐘偏差或調整的影響。對于性能分析來說,精確的測量結果意義重大。
varperf = performance.now(); // console output 439985.4570000316
Page Visibility (頁面可見性)
通過這一 規范 ,網站開發者能夠以編程方式確定頁面的當前可見狀態,從而使網站能夠更有效地利用電源與CPU。
當頁面獲得或失去焦點時,文檔對象的 visibilitychange 事件便會被觸發。
document.addEventListener('visibilitychange', function(event){if(document.hidden){ // Page currently hidden.} else{// Page currently visible.}});
這一事件對于了解頁面的可見狀態十分有用,舉例來說,用戶可能會同時打開多個瀏覽器標簽,而你希望只在用戶顯示你的網站頁面時才進行某些操作(比 如播放一段音頻文件、或是執行一段JavaScript動畫),就可以通過這一事件進行觸發。對于移動設備來說,如果用戶在某個標簽中打開了你的網站,但 正在另一個標簽中瀏覽其它內容時,這一特性能夠節省該設備的電池消耗。(雖然對于你的網站性能來說意義不大……)
其它部分API功能簡介
- Resource Timing (資源計時)——對單個資源(如圖片)的計時,可以對細粒度的用戶體驗進行檢測。
- Performance Timeline (性能時間線)——以一個統一的接口獲取由Navigation Timing、Resourcing Timing和User Timing所收集的性能數據。
- Battery Status (電池狀態)——能夠檢測當前設備的電池狀態,例如是否正在充電、電量等級等等。可以根據當前電量決定是否顯示某些內容(例如視頻、動畫等等),對于移動設備來說非常實用。
- User Timing (用戶計時)——可以對某段代碼、函數進行自定義計時,以了解這段代碼的具體運行時間,類似于stop watch的作用。
- Beacon (燈塔)——可以將分析結果或診斷代碼發送給服務器,它采用了異步執行的方式,因此不會影響頁面中其它代碼的運行。對于收集測試結果并進行統計分析來說是一種十分便利的工具。
- Animation Timing (動畫計時) - 通過requestAnimationFrame函數讓瀏覽器精通地控制動畫的幀數,能夠有效地配合顯示器的刷新率,提供更平滑的動畫效果,減少對CPU和電池的消耗。
- Resource Hits (資源提示) - 通過html屬性指定資源的預加載,例如在瀏覽相冊時能夠預先加載下一張圖片,加快翻頁的顯示速度。
- Frame Timing (幀計時)——通過一個接口獲取與幀相關的性能數據,例如每秒幀數和TTF。該標準目前尚未被支持。
- Navigation Error Logging (導航錯誤日志記錄)——通過一個接口存儲及獲取與某個文檔的導航相關的錯誤記錄。該標準目前尚未被支持。
瀏覽器支持
下表列舉了當前主流瀏覽器對性能API的支持,其中標注星號的內容并非來自于Web性能工作小組。
規范 | Internet Explorer | Firefox | Chrome | Safari | Opera | iOS Safari | Android |
Navigation Timing | 9 | 31 | 全部 | 8 | 26 | 8 (不包括 8.1) | 4.1 |
High Resolution Timing | 10 | 31 | 全部 | 8 | 26 | 8 (不包括 8.1) | 4.4 |
Page Visibility | 10 | 31 | 全部 | 7 | 26 | 7.1 | 4.4 |
Resource Timing | 10 | 34 | 全部 | - | 26 | - | 4.4 |
Battery Status* | - | 31 (部分支持) | 38 | - | 26 | - | - |
User Timing | 10 | - | 全部 | - | 26 | - | 4.4 |
Beacon | - | 31 | 39 | - | 26 | - | - |
Animation Timing | 10 | 31 | 全部 | 6.1 | 26 | 7.1 | 4.4 |
Resource Hints | - | - | 僅限Canary版 | - | - | - | - |
Frame Timing | - | - | - | - | - | - | - |
Navigation Error Logging | - | - | - | - | - | - | - |
WebP* | - | - | 全部 | - | 26 | - | 4.1 |
Picture element and srcset attribute * | - | - | 38 | - | 26 | - | - |
其它
DZone.com在《Performance & Monitoring 2015》這份白皮書中專門介紹了性能API以及W3C所推薦的新協議、標準及HTML元素,并提供了簡單的示例。可以在 這里 下載完整的白皮書(需要注冊)。本文中的示例代碼即來自于該白皮書。
如果想了解有關Web性能API的更多內容,可以參考 W3C官方文檔 或這篇 博客 。