jQueryで破棄されたrequestAnimationFrameとJSでのアニメーション実装で注意すること

自己紹介

requestAnimationFrame

requestAnimationFrame < よーしおまえらー、アニメーションにsetInterval使うなよーでおなじみの、setIntervalnい代わるアニメーション向けAPI

setIntervalの問題点としてそもそもアニメーション向けのmethodではないのでintervalの呼び出し単位とブラウザの描画更新単位が一致しない

それを解決するためブラウザの描画更新単位と同じ単位で呼び出されるrequestAnimationFrameが登場した

上がsetTimeout、下がrequestAnimationFrameの実行単位の概念

jQueryでも1.6.0から採用

jQuery: » jQuery 1.6 Releasedでも、「Synced Animations」とか「Smoother Animations」とか「the best possible animation experience.」とかって宣伝

が、しかし。。。

突然の別れ

jQuery 1.6.3でrequestAnimationFrameが削除され、setIntervalでのanimationに戻る

jQuery 1.7b1でもanimateはsetIntervalのまま

何があったのか

requestAnimationFrameの目的は悪くない

ちゃんと使えば普通に使えます

ただ、jQueryで実際使ってみると色々と問題が

jQuery自体の問題も大きい

問題1

requestAnimationFrame使用時にjQuery.fx.intervalが効かない

jQuery.fx.intervalを使うとrequestAnimationFrameサポートブラウザと非サポートブラウザで動きが変わることに

問題2

setIntervalとrequestAnimationFrameが衝突してqueueの実行が溜まる

以下ブログでも紹介されてますが、実際タブのアクティブ、非アクティブを行うとanimateが複数同時に実行される感じになる
非アクティブなときのsetTimeout/setIntervalとrequestAnimationFrame - hokaccha.hamalog v2

問題3

思ったほど速度も変わらない

そもそもsetTimeout(func, 0);でanimateするよりはいいってものなので、ちゃんと組むならsetTimeoutでも十分

問題4

タブが非アクティブなときのsetTimeoutも速度が落ちることになった

タブが非アクティブなときはsetTimeoutは1000ms、requestAnimationFrameは実行されない。1sなら十分遅い

というわけで

そもそもjQueryではサポートしてもそんなに得るものはなかった

「jQuery.support.rafで切り替えられるようにしては?」という提案もありましたが

「APIもまだfixしてないし、一旦放置で」ということになりました

じゃあどんな時なら使えるの?

「setTimeout(func, 0);の代わり」

「連続で呼び出されるイベントの間引き」

こういう目的であれば割と簡単に置き換えて使える

こんなコードを入れとけば未サポートブラウザも安心

(function (w, r) {
	w['r'+r] = w['r'+r] || w['webkitR'+r] || w['mozR'+r] || w['msR'+r] || w['oR'+r] || function(c){ w.setTimeout(c, 1000 / 60); };
})(window, 'equestAnimationFrame');

以上 ご静聴ありがとうございました

KAYACでは面白法人で働きたい技術者を募集しています!