無線性能優化:FPS 測試

2021-02-24 前端大全

(點擊上方公眾號,可快速關注)

作者:淘寶前端團隊(FED)- 冬萌

網址:http://taobaofed.org/blog/2016/01/13/measuring-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();

var frame = 0;

var lastFameTime = performance.now();

 

var loop = function(time) {

  var now =  performance.now();

  var fs = (now - lastFameTime);

  lastFameTime = now;

  var fps = Math.round(1000/fs);

  frame++;

  if (now > 1000 + lastTime) {

    var fps = Math.round( ( frame * 1000 ) / ( now - lastTime ) );

    frame = 0;    

    lastTime = now;    

  };          

  window.requestAnimFrame(loop);  

}

用例結果如下:

大功告成,可以去找女神答覆了,等等,這樣是不是太簡單了點,無法讓女神刮目相看啊(在女神面前裝逼),我們是不是再深入點。

Chrome 瀏覽器渲染頁面時,涉及了兩個線程,Render 主線程和 Compositor 合成線程,且兩個線程通過名為 Commit 的消息來保持同步,而每一幀消耗時間應該是包含兩部分,Render 主線程消耗的時間和 Compositor 線程消耗的時間。典型的狀態如下(以下三張圖片來自 frame-timing-polyfill):

主線程 Commit 消息提交給合成線程,任務都在 16.66ms 內完成。當然,對於一些輸入事件,比如滾動,是先轉移給合成線程進行處理,然後通知給主線程,這樣可以保證對用戶的輸入操作做及時的響應,同時,對於一些頁面更新,如 CSS 動畫和 CSS 濾鏡,只需合成線程處理,而無需請求主線程,如下所示:

當然,也有可能,主線程處理耗時較多,導致提交給合成線程的時間推遲到了下一幀,如下所示:

針對以上三種情況,那流暢性如何定義呢?就需要因地制宜,不同環境分別分析了。

那是否有方法可以讓我們分別取到 Render 主線程和 Compositor 合成線程的數據呢?答案是 Frame Timing。

Frame Timing

Frame Timing API 目前還只是草案,暫時還沒發現有瀏覽器支持,不過我們可以先實現,萬一瀏覽器支持了呢~~,目前的 API 如下:

var rendererEvents = window.performance.getEntriesByType("renderer");

var compositeEvents = window.performance.getEntriesByType("composite");

獲取 Render 主線程和合成線程的記錄,每條記錄包含的信息基本如下:

{

  sourceFrameNumber: 120,

  startTime: 1342.549374253,

  duration: 10.654313323

}

每個記錄都包括唯一的 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');

var chrome = require('selenium-webdriver/chrome');

 

// ...

 

// 配置需要跟蹤記錄的數據

var options = new chrome.Options();

var traceCategories = [

    'blink.console',

    'devtools.timeline',

    'toplevel',

    'disabled-by-default-devtools.timeline',

    'disabled-by-default-d.evtools.timeline.frame'

];

options.setLoggingPrefs({ performance: 'ALL' });

options.setPerfLoggingPrefs({

    'traceCategories': traceCategories.join(',')

});

 

// ...

 

// 傳入 chromedriver 實例

function getTrace(browser) {

    return (new webdriver.WebDriver.Logs(browser))

        .get('performance')

        .then(function(logs) {

         // performance log

     });

}

其中,traceCategories 的配置和 chrome://tracing/ 的配置一樣,打開 Chrome,地址欄輸入 chrome://tracing/,點擊 record 按鈕,會出現如下所示的配置項:

其中的配置就是我們可以獲取的。獲取到 Performance Log 後導出成 JSON 文件,導入到 Chrome 的 Timeline 裡,你會驚奇的發現,這和直接用 Timeline 效果是一樣一樣的,如下所示:

但是接下來,我發現真正頭疼的問題來了,Performance Log 是一堆密密麻麻的數據,而且還沒找到相關文檔,目前只是可以取出平均的 FPS,計算方法如下,首先解析數據,取出類型為 DrawFrame 的記錄個數,然後除以整個統計的持續時間,即可大體得出整體平均的 FPS,如何解析出更具體的數據,還在持續研究中,希望這下可以讓女神滿意,嘿嘿嘿~

參考文檔

【今日微信公號推薦↓】

相關焦點

  • Webpack 教程:性能優化
    Webpack 默認的優化措施對於一些小項目來說已經足夠了。
  • 性能測試:Surface Pro 3擊潰iPad Air 2/安卓平板
    ,在一項性能基準測試中,遠壓蘋果iPad Air 2和一眾Android平板。使用綜合性測試工具,將Surface Pro 3、iPad Air 2、iPad mini 3、谷歌Nexus 9、三星Galaxy Tab Pro 10.1和其他平板進行比較,得益於英特爾Core i5處理器,12英寸的Surface Pro 3理所當然地拔得頭籌。
  • 實測:易衝無線充電技術支持三星Galaxy S8+無線快充
    在得悉該消息後,深圳市易衝無線科技有限公司(簡稱「易衝無線」)第一時間拿到三星Galaxy S8+,把易衝無線發射板與三星Galaxy S8+原裝無線充電器進行測試對比,以下是兩組對比視頻。三星Galaxy S8+通過原裝無線充電器充電:三星Galaxy S8+通過易衝無線發射板充電:對比發現,經過優化的易衝無線發射板支持三星Galaxy S8+的無線快充,不存在「斷充」現象,並且部分測試指數優於三星Galaxy S8+原裝無線充電發射器。
  • 性能測試:Firefox 73 vs Chrome 80
    該測試主要是為了研究 Firefox 73 的性能,並展望其性能如何在初始 Beta 版本中對 Firefox 74 產生影響,作者測試了在有/無 WebRender 的 Ubuntu Linux 上 Firefox 72/73/74 的最新基準以及與 Chrome 當前狀態進行比較。以下是其中的一些結論。
  • New Surface Pro 測評:足夠輕薄且性能夠用
    (4)USB 3.0接口,這個用來連接無線滑鼠插口了。(5)Surface Connect接口,這個可以連接拓展塢,但是對我沒用,我單純把它當成充電口。(6)背部microSD讀卡器接口,這個對我也完全沒用。    所以對我個人而言,用得到的接口也就一個USB 3.0接口和一個充電接口,接口方面我不會感覺不夠。
  • 國服吃雞難優化,8G與16G實測測試對比
    作為一款對戰遊戲,為了公平,如此寬廣的視野中,某些特效是不能因為優化而關掉的。如果降低特效就大幅縮減樹木、草叢、陰影等模型/特效的渲染,那對於開了高畫質的玩家來說就很尷尬了——花錢買了好配置,反而到處是樹木草叢看不到人,頻頻被打黑槍,哪能有這樣的道理!
  • iPhone SE防水性能測試:蘋果有良心
    蘋果iPhone SE在近日也與我們見面了,從我們IT之家的實測當中可以看出蘋果在這款「沒有改變的新手機」當中也花費了不少的心力,客觀來說,iPhone SE也可以稱得上是目前性能最強的四英寸手機
  • 外媒:蘋果正在為 iPhone 開發一款無線電池組 道阻且長
    【環球網科技綜合報導】2月20日消息,據彭博社報導稱,蘋果公司正在為最新的 iPhone 開發一款通過磁性連接的無線電池組——MagSafe,這款配件將為
  • 不服跑個分:PC 端 VR 性能測試軟體 VRMark 正式上架
    如果你熱衷於壓榨 PC 的性能上限,又或者想要了解最新的軟硬體能幫你在 VR 這條道路上走多遠,那麼來自知名跑分軟體公司 Futuremark 的新工具可以量化對虛擬實境的性能測試。這家總部位於芬蘭的工作室於昨天(2016 年 11 月 3 日)通過 Steam 以及官方網站發布了 VRMark 工具。
  • 我公司順利通過華潤燃氣集團擴頻無線遠傳表新標準互聯互通測試
    10月27日上午9點,成都燃氣會議室,華潤燃氣集團八家入圍供應商針對擴頻無線遠傳表新標準的互聯互通測試正如火如荼的進行著。
  • 性能測試:iPhone 6s/SE 升級 iOS 13 流暢嗎?
    為了測試此性能,我們上述兩款設備上升級了 iOS 13,登錄到測試用 iCloud 帳戶中。每個應用程式均打開 3 次,對結果取平均值。如果打開應用並等待加載的過程緩慢,這通常意味著手機的其餘部分(包括等待鍵盤彈出,等待頁面加載以及其他任務)也會同樣變慢,尤其是當您下載更多內容並連接更多帳戶時。
  • iPhone 8性能要上天:A11這表現驚豔全場!
    添加微信號可直接搜索我們的名稱: iPhone頻道  (微信號:iphone-apple-ipad)iPhone 8的曝光看多了,我們今天看點不一樣的,那就是它的性能,大家覺得A11實力到底是怎麼樣的,繼續掀翻整個安卓陣營?
  • 索尼A6300測評:實拍測試視頻+第一印象
    A6300在僅售1000美元(約合人民幣6531元)前提下,提供了以前在這個價格區間中我們從未聽過的特性,包括4K解析度(超高清)、S-Log2與S-Log3、APS-C畫幅成像器尺寸、內置可換鏡頭系統、全高清慢動作鏡頭——最高幀率高達120fps(NTSC模式下)。價格親民,配置入流,強烈推薦!
  • 揭秘三星實驗室:Note 7電池是如何測試的?
    同時,三星也向部分媒體開放了位於韓國龜尾市的大型電池檢測工廠,在這裡Note 7經歷了更多頻繁的電池測,包括過充測試、穿釘刺測試、極端溫度壓力測試等等。圖片中正在進行電池測試,確認無線充電對Galaxy Note 7的影響
  • 媒體評測:最大程度發揮安卓性能!雷電OS全面提升安卓體驗
    如何才能最大程度發揮安卓手機的性能呢?其實只要換一個OS就可以。今日小編要給大家安利一款最近很火的雷電OS,可以全面提升安卓體驗,讓安卓從此輕、快、好、省。有網友打趣,雷電OS很像《琅琊榜》裡守衛梅長蘇的飛流,武功高強,時刻保護手機。
  • 研發知識:材料如何測試UL94燃燒性能?
    auto.anytesting.com電子電氣專欄http://ee.anytesting.com醫療器械專欄http://med.anytesting.com醫藥專欄http://drug.anytesting.com以下為正文:UL94 是應用最廣泛的塑料材料阻燃性能評價標準
  • Xbox One S試玩:更小更輕薄 性能無提升
    硬體Xbox One S是一款輕薄版機型,所以性能方面與老版本Xbox One並沒有區別。不過,它支持4K及HDR視頻播放,包括流媒體及藍光碟片,同時最高硬碟容量達2TB,這都是相比老版本的提升。雖然有相關媒體認為,Xbox One S從技術上來說可以實現4K遊戲輸出,但由於處理器、顯卡方面並未升級,其實是無法實現穩定幀速率的4K遊戲畫面的。