RequestAnimationFrame,絕對的大名鼎鼎。相信做HTML5的同學們,都聽到過這個函數。再重復一下它的好處:
游戲頁面在不被顯示的時候,RequestAnimationFrame暫停執行,不會占用CPU時間
RequestAnimaitonFrame會將JS產生的動畫以及CSS產生的動畫,放到同一個Repait和Reflow的循環中。
對于第二點,很少有人提及,但是非常重要,如果沒有RequestAnimationFrame,而用setTimeout,很有可能在每次繪制的時候,JS產生的動畫和CSS產生的動畫,沒有同時發生,相信這個肯定不是你想要的結果。對于第二點,有點晦澀,不太容易懂,讓我們更進一步解釋一下,這就要從瀏覽器的渲染流程說起。大體上,瀏覽器的渲染流程有以下四步:
更新Dom的結構:每次你執行JS改變Dom結構,或者修改CSS相關屬性,都會對Dom結構進行改變。現在HTML5中,多了Canvas元素,對于Canvas對象,執行某個操作,比如畫一條線,也屬于對Dom結構的改變。但是Canvas有個比較特殊的操作,比如對Canvas對象執行getImageData操作,會強制瀏覽器立即跳到第四步,將渲染好的瀏覽器窗口,繪制到屏幕。
渲染每個元素:在所有JS和CSS執行完畢之后,瀏覽器按照要求,開始對每個元素進行渲染。
- 將所有元素渲染到窗口:按照窗口大小的要求,將所有的元素,繪制到一個平面上。
- 通過操作系統窗口管理器,將渲染好的窗口,輸出到屏幕。
通常,執行完第四步,稱為一幀。目前,大部分的顯示器,都會將顯示控制在每秒六十幀,瀏覽器處于優化的目的,通常的顯示頻率也不會超過六十幀。
講到這里,大約可以清楚一點,如果不用RequestAnimationFrame,而是用傳統的SetTimeout,很難要求瀏覽器將同一次SetTimeout里面執行的Dom或者CSS操作放到同一幀中,也就會隨機的出現,某個JS操作的動畫和CSS或者Canvas的動畫,不能同步。因為隨機的,每次行為不一致,相信這是所有開發者都不愿意碰到的情況。沒有開發人員怕Bug,但是害怕的是Bug不可以重現。
2) 計算游戲的幀率(FPS)
衡量游戲性能的重要指標就是幀率(FPS),因為瀏覽器的實現不一,有些瀏覽器出于優化的目的,沒有嚴格的按照第一部分介紹的四步,有些時候,在某一幀沒有完成的時候,就開始執行下一幀,所以理論上,很難嚴格的記錄瀏覽器顯示的幀率。如果你可以有個高速的攝像機,對著屏幕拍攝,是可以嚴格的記錄屏幕顯示的幀率,但是相信這個方法,很難被大規模使用。
目前也有一些第三方類庫,可以幫助你衡量游戲的幀率,比如比較著名的https://github.com/mrdoob/stats.js,但是這個是非常不嚴格的,以StatsJS為代表的類庫,是利用很衡量setTimeout或者setInterval每秒鐘被執行的次數或者時間,來衡量幀率的。但是seTimeout函數被執行的次數和時間,和RequestAnimationFrame沒有特別嚴格的對應關系,只可以作為參考。或者,簡單一點說,每一幀被渲染的過程中,setTimetout函數很有可能被執行一次或者兩次,甚至更多次。
理論上,為了監控RequestAnimationFrame幀率,需要開發者hook RequestAnimaitonFrame這個函數,在函數每次執行完畢的時候,執行Canvas的getImageData操作,強制瀏覽器渲染本次RequestAnimationFrame的所有操作,計算兩次渲染操作的時間差,從而得出幀率。
幸運的是,Firefox瀏覽器已經開發了得到幀率的接口,可以省去很多周折。比如window.mozPaintCount這個接口,可以直接告訴開發者,瀏覽器渲染的幀率。
(未完待續)
接上文:HTML5 游戲開發 之 資源加載篇(2)
【網站聲明】本站除付費源碼經過測試外,其他素材未做測試,不保證完整性,網站上部分源碼僅限學習交流,請勿用于商業用途。如損害你的權益請聯系客服QQ:2655101040 給予處理,謝謝支持。