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