無線效能優化:FPS測試
時間回到幾周前,這天,女神突然來找我,“我這裡有幾個頁面想測量下頁面滾動的順暢性,你有啥辦法不?”。Are you kidding me?這麼簡單,簡直是道送分題啊,於是當著女神面,開啟 Chrome 開發者工具,勾選上 Show FPS meter,醒目的 FPS 監控皮膚就出來了,滑動頁面時 FPS 的曲線就基本反映出了頁面滾動的順暢性,坐等女神的誇獎~~
“這個我知道啊,但是我有好多頁面,難道要一個一個人工看嗎?而且這個也沒有一個記錄的匯出,如果能有個方法幫我自動的測量,有問題再通知我,我再仔細排查就好了”。
這個需求開始有點技術含量了,不過應該也難不倒我,頁面都接入了 UITest,在頁面做 UI 測試的時候,跑一下測量 FPS 的測試用例就 ok 了,那如何測量呢?女神等我~~
mozPaintCount
mozPaintCount 變數是 Mozilla 提供的方法,其返回的是當前文件 paint 到螢幕上的數量,通過計算單位時間 paint 數量變化,即可計算出頁面的 FPS,so easy。
等等,這個變數目前好像只有 Firefox 支援,Chrome 上並沒有一個 webkitPaintCount 或者 paintCount 變數,而我們的 UITest 是跑在 ChromeDriver 或者 PhantomJS 上,並沒有 Firefox 環境,好吧,這個可以做備選方案,依賴於 UITest 支援 Firefox 環境。為了完成女神的需求,我們還要考慮其他方案了。
requestAnimationFrame
在頁面重繪前,瀏覽器會執行傳入 requestAnimationFrame 的入參函式,一般多用來實現連貫的逐幀動畫。那我們基於 requestAnimationFrame 不就可以獲得頁面的繪製頻率,計算出 FPS,而且瀏覽器支援情況也不錯,說幹就幹,示例程式碼如下(簡單示例,沒做相容等處理):
var lastTime = performance.now(); |
用例結果如下:
大功告成,可以去找女神答覆了,等等,這樣是不是太簡單了點,無法讓女神刮目相看啊(在女神面前裝逼),我們是不是再深入點。
Chrome 瀏覽器渲染頁面時,涉及了兩個執行緒,Render 主執行緒和 Compositor 合成執行緒,且兩個執行緒通過名為 Commit 的訊息來保持同步,而每一幀消耗時間應該是包含兩部分,Render 主執行緒消耗的時間和 Compositor 執行緒消耗的時間。典型的狀態如下(以下三張圖片來自 frame-timing-polyfill):
主執行緒 Commit 訊息提交給合成執行緒,任務都在 16.66ms 內完成。當然,對於一些輸入事件,比如滾動,是先轉移給合成執行緒進行處理,然後通知給主執行緒,這樣可以保證對使用者的輸入操作做及時的響應,同時,對於一些頁面更新,如 CSS 動畫和 CSS 濾鏡,只需合成執行緒處理,而無需請求主執行緒,如下所示:
當然,也有可能,主執行緒處理耗時較多,導致提交給合成執行緒的時間推遲到了下一幀,如下所示:
針對以上三種情況,那流暢性如何定義呢?就需要因地制宜,不同環境分別分析了。
-
對於滾動和 CSS 動畫,由於不涉及主執行緒的影響,我們會更關心合成執行緒的繪製頻率,而合成執行緒的繪製頻率也反映了滾動和 CSS 動畫的流程性。
-
對於 JS 幀動畫而言,我們期望主執行緒和合成執行緒的消耗加起來到能在 16.66ms 內,且不丟幀。因此我們需要同時關注主執行緒的 Commit 頻率和合成執行緒的繪製頻率,並且我們期望每個主執行緒的 Commit 都對應唯一一個合成執行緒的繪製(保證不丟幀)。
那是否有方法可以讓我們分別取到 Render 主執行緒和 Compositor 合成執行緒的資料呢?答案是 Frame Timing。
Frame Timing
Frame Timing API 目前還只是草案,暫時還沒發現有瀏覽器支援,不過我們可以先實現,萬一瀏覽器支援了呢~~,目前的 API 如下:
var rendererEvents = window.performance.getEntriesByType("renderer"); |
獲取 Render 主執行緒和合成執行緒的記錄,每條記錄包含的資訊基本如下:
{ |
每個記錄都包括唯一的 Frame Number、Frame 開始時間以及持續時間。根據 duration 就可以知道該幀是否達到 16.66ms 的標準,同時根據單位時間記錄數(Frame)的個數就能算出主執行緒或者合成執行緒每秒的幀率。
同時,對於主執行緒 Commit 給合成執行緒繪製的情況,可以根據唯一的 sourceFrameNumber 將 renderEvents 的記錄和 compositeEvents 的記錄做關聯,得出每個主執行緒 Commit 所對應的合成執行緒繪製的次數,如前所說,這也是判斷 JS 動畫流程性的一個可檢測指標~~(具體實現程式碼較多且比較簡單,就不貼了,小夥伴們動動腦筋,分分鐘就寫出來了~)
至此,終於可以向女神交差了,想想女神崇拜的目光,還有點小激動呢~~
再等等,既然 Chrome 能開啟 FPS meter,而且我們的 UI 測試也是跑在 ChromDriver 中的,那是不是可以通過配置開啟 Chrome 的 FPS meter 獲取到 FPS 呢,女神,再等我下~
Show FPS Counter or Performance Log
果不其然,查詢 ChromeDriver 的配置設定
–show-fps-counter: Draws a heads-up-display showing Frames Per Second as well as GPU memory usage. If you also use –vmodule=”head*=1” then FPS will also be output to the console log.
只要能輸出到 console log 裡,我們就能方便的取到了,於是果斷在 UITest 的 ChromeDriver 配置里加上裡這兩項:
chromeOptions["args"] = [
// 其他配置省略
`--show-fps-counter`,
`--vmodule="head*=1"`
];
滿心歡喜的一試,FPS meter 是出來的,但是說好的 console log 並沒有,具體的討論可以參見這個 issue。
難道沒有別的辦法了嗎?既然 Chrome 的 Timeline 那麼強大,其中也包含了每一幀的耗時,那是不是可以取到 Timeline 的資料?當然沒問題,我們使用 selenium-webdriver就能方便的獲取到頁面的 Performance Log,示例如下所示:
var webdriver = require(`selenium-webdriver`); |
其中,traceCategories 的配置和 chrome://tracing/
的配置一樣,開啟 Chrome,位址列輸入 chrome://tracing/
,點選 record
按鈕,會出現如下所示的配置項:
其中的配置就是我們可以獲取的。獲取到 Performance Log 後匯出成 JSON 檔案,匯入到 Chrome 的 Timeline 裡,你會驚奇的發現,這和直接用 Timeline 效果是一樣一樣的,如下所示:
但是接下來,我發現真正頭疼的問題來了,Performance Log 是一堆密密麻麻的資料,而且還沒找到相關文件,目前只是可以取出平均的 FPS,計算方法如下,首先解析資料,取出型別為 DrawFrame 的記錄個數,然後除以整個統計的持續時間,即可大體得出整體平均的 FPS,如何解析出更具體的資料,還在持續研究中,希望這下可以讓女神滿意,嘿嘿嘿~
參考文件
- Measuring FPS
- frame-timing-polyfill
- ChromeDriver Config
- issue: need FPS data in console log
- selenium-webdriver
- selenium-webdriver api
相關文章
- 測量、基線和效能優化之三:基於測量、基線和變化的效能優化優化
- 測量、基線和效能優化之三:基於測量、基線和變化的效能優化v優化
- 測量、基線和效能優化之二:基線和效能優化
- Redis Enterprise新版優化線性擴充套件,效能測試有點厲害!Redis優化套件
- 效能測試之測試分析與調優
- 【效能調優】效能測試、分析與調優基礎
- 效能測試瓶頸調優
- postgresql無序uuid效能測試SQLUI
- JICMAIL:2021年A/B測試優化郵件效能報告AI優化
- ClickHouse 效能優化?試試物化檢視優化
- ClickHouse效能優化?試試物化檢視優化
- 軟體效能測試的優勢
- 功能測試、自動化測試、效能測試的區別
- Flinkx Logminer效能探測&優化之路優化
- 【前端效能優化】vue效能優化前端優化Vue
- 面試題:webpack之效能優化面試題Web優化
- 效能測試調優應該注意哪些要點,一般效能測試調優的步驟-Alltesting|澤眾雲測試
- ACK G2-TA-KT執行無線效能測試操作步驟
- Flutter 應用效能檢測與優化Flutter優化
- 前端面試題(五)(安全、效能優化)前端面試題優化
- 一次效能測試調優總結
- 效能測試公開課來啦!從效能測試方案到效能調優,從負載均衡到中介軟體測試,全方位講解效能測試核心內容負載
- Oracle案例10——HWM(高水位線)效能優化Oracle優化
- 效能優化優化
- 【OC梳理】效能檢測及優化彙總優化
- android效能評測與優化-記憶體Android優化記憶體
- 拳頭FPS新作《Valorant》6月2日正式上線 測試月底結束
- 前端面試之路四(web效能優化篇)前端面試Web優化
- Gse v0.20.0 釋出了, Go 高效能分詞, 優化效能和程式碼, 更多測試GseGo分詞優化
- PerfDog 助力自動化效能測試探索
- 測試平臺後端優化後端優化
- locust 與 jmeter 效能測試對比會更優?JMeter
- 效能測試
- 測試面試題集錦(五)| 自動化測試與效能測試篇(附答案)面試題
- 前端效能優化(JS/CSS優化,SEO優化)前端優化JSCSS
- Android效能優化——效能優化的難題總結Android優化
- Jmeter介面測試+效能測試JMeter
- [效能優化]DateFormatter深度優化探索優化ORM
- 前端效能優化 --- 圖片優化前端優化