web裡計算FPS

發表於2015-10-23

幀率(FPS)用於描述成像裝置產生連續影像的頻率 動畫其實就是顯示連續幀產生的錯覺。如果FPS太低,動畫將不平滑,甚至人眼都能看到每一幀影像。 一般運動影像的幀率為24 FPS,電視使用30 FPS。在現代遊戲中,玩家必須在視覺跟蹤動畫物件 ,並迅速作出反應,幀速率一般是每秒30幀和60幀之間。然而,快速移動的物體,可能需要更高的幀速率 ,以避免不希望的視覺假象(閃現)。雖然從理論上講,我們可以達到極高的幀速率,在FPS由顯示器的重新整理速率的限制 。現代的液晶電視能120 FPS,甚至240 FPS。在手機,顯示器是最有可能限制為60 FPS。

 

圖1:1秒內不同動畫幀速率比較

usage

HTML5提供的Web開發人員提供了新的工具來建立動態和互動式內容,如動畫和遊戲。 幀速率仍作為開發人員的重要指標,fps太低會帶來差勁的使用者體驗。所以開發人員希望有可靠的方式來計算HTML5頁面的FPS。 但是問題是,沒有辦法得到可靠的FPS。 Web開發人員通常通過每次loop和上次loop的間隔來時間time,再通過1000/time來算fps。 微軟釋出了許多HTML5效能基準測試.如FishIE演示,該演示主要是能夠計算Canvas中影像的fps。 。Facebook的JSGamebench主要是計算使用WebGL中展示大量動畫的fps。 但是他們沒有辦法知道瀏覽器整個網頁(整個網頁可能包含dom、canvas、webgl、svg..)的FPS。 那麼通過JavaScript能否計算出整個網頁的fps?

JavaScript的動畫

製作動畫效果,可以使用的setInterval / setTimeout和requestAnimationFrame。 後者用於製作動畫的首選方法。它將告知瀏覽器你馬上要開始動畫效果了,瀏覽器會在下次repaint前呼叫特定的方法來更新動畫以達到優化的結果。

瞭解定時器在JavaScript中是如何工作是很重要的。 定時器延遲是沒法保證的,不準確的,因為所有的JavaScript在單個執行緒中執行,只有當前面佇列執行完畢且輪到了自己才能被執行。 如下圖: usage

如上圖所以,不僅時間不夠精確,而且由於排隊,導致setInterval的一次回撥被延遲到了下一輪迴調,為了避免同一時間執行多次setInterval的回撥, 上次次的將被瀏覽器放棄執行。

FishIE

所以從上面可以知道,使用setInterval(function(){},16.7)是有可能達不到60fps,是什麼導致了回撥的延遲?

  • 畫布的大小
  • 魚的數量的位置計算
  • 魚的大小
  • 平移,縮放,轉換的計算
  • 背景(魚缸)

結論

因為瀏覽器還沒有提供通過JavaScript測量真正的FPS一種標準的方法, Web benchmarks測試出來的FPS本質上是不可信的(它可以測試SVG、Canvas、WebGL等渲染的FPS,而沒法測試整個網頁)。 Mozilla已經提供了一個方法來解決這個問題:mozPaintCount變數; 返回的次數文件已paint到螢幕的數目。理想情況下,我們會希望這個有待規範 ,使所有的現代瀏覽器將提供衡量FPS的標準介面。隨著富媒體網站越來越多,保持FPS穩定的是很重要的事情, 在流暢的30幀執行的動畫比跳動的50 FPS受歡迎得多。在webkit系列的瀏覽器中,解決這個問題的辦法是公開一個webkitPaintCount變數。 我們可以通過webkitPaintCount的變化得到真正意義上的FPS.

相關文章