requestAnimationFrame()ガイド

予測可能な方法でアニメーションを実行し、イベントをスケジュールするAPIを学習します

requestAnimationFrame()は比較的最近のブラウザAPIです。これにより、ブラウザのレンダリングサイクルにフックするためのより予測可能な方法が提供されます。

現在、すべての最新のブラウザー(およびIE 10以降)でサポートされています。

Browser support

これはアニメーションに固有のAPIではありませんが、最もよく使用される場所です。

JavaScriptにはイベントループがあります。 JavaScriptを実行するために継続的に実行されます。

過去には、アニメーションはを使用して実行されていましたsetTimeout()またはsetInterval()。アニメーションを少し実行して、setTimeout()今から数ミリ秒後にこのコードをもう一度繰り返すには:

const performAnimation = () => {
  //...
  setTimeout(performAnimation, 1000 / 60)
}
setTimeout(performAnimation, 1000 / 60)

または

const performAnimation = () => {
  //...
}
setInterval(performAnimation, 1000 / 60)

タイムアウトまたは間隔の参照を取得し、それをクリアすることで、アニメーションを停止できます。

let timer

const performAnimation = () => { //… timer = setTimeout(performAnimation, 1000 / 60) }

timer = setTimeout(performAnimation, 1000 / 60)

//… clearTimeout(timer)

ザ・1000 / 60間の間隔performAnimation()呼び出しは、モニターのリフレッシュレートによって決定されます。これは、ほとんどの場合60 Hz(1秒あたり60回の再描画)です。これは、モニターが制限のために再描画を表示できない場合、再描画を実行することは無意味だからです。すべてのフレームを表示するために自由に使える時間は約16.6ミリ秒になります。

このアプローチの問題は、この精度を正確に指定しても、ブラウザーが他の操作の実行でビジー状態になり、setTimeout呼び出しが再描画に間に合わず、次のサイクルに遅れる可能性があることです。

これは悪いことです。1つのフレームが失われ、次のアニメーションは2回実行され、目が不格好なアニメーションに気付く原因になります。

グリッチのこの例を確認してくださいsetTimeout()を使用して作成されたアニメーション

requestAnimationFrameはアニメーションを実行するための標準的な方法であり、コードはsetTimeout / setIntervalコードと非常によく似ていますが、非常に異なる方法でイベントで機能します。

let request

const performAnimation = () => { request = requestAnimationFrame(performAnimation) //animate something }

requestAnimationFrame(performAnimation)

//… cancelAnimationFrame(request) //stop the animation

グリッチのこの例requestAnimationFrame()を使用して構築されたアニメーションショーショー。

最適化

requestAnimationFrame()その導入は非常にCPUフレンドリーであったため、現在のウィンドウまたはタブが表示されていない場合はアニメーションが停止します。

requestAnimationFrame()が導入されたとき、タブが非表示になっていてもsetTimeout / setIntervalが実行されていましたが、このアプローチはバッテリーの節約にも成功することが証明されたため、ブラウザーはこれらのイベントのスロットリングも実装し、1秒あたり最大1回の実行を可能にしました。

使用するrequestAnimationFrameブラウザは、リソース消費をさらに最適化し、アニメーションをよりスムーズにすることができます。

タイムラインの例

setTimeoutまたはsetIntervalを使用する場合、これは完璧なタイムラインです。

Perfect timeline

ペイント(緑)イベントとレンダリング(紫)イベントのセットがあり、コードは黄色のボックスにあります-ちなみに、これらはブラウザDevToolsでもタイムラインを表すために使用される色です。

The devtools timeline

イラストは完璧なケースを示しています。 60ミリ秒ごとにペイントとレンダリングが行われ、その間にアニメーションが完全に定期的に実行されます。

アニメーション関数に高頻度の呼び出しを使用した場合:

Too frequent timeline

レンダリングが行われる前に、各フレームで4つのアニメーションステップを呼び出す方法に注意してください。これにより、アニメーションが非常に途切れ途切れになります。

他のコードがイベントループをブロックしているためにsetTimeoutを時間どおりに実行できない場合はどうなりますか?フレームを見逃してしまいます:

Missed frame

アニメーションのステップに予想よりも少し時間がかかる場合はどうなりますか?

Delay in the timeline

レンダリングイベントとペイントイベントも遅延します。

こうやってrequestAnimationFrame()視覚的に機能します:

Delay in the timeline

すべてのアニメーションコードが実行されますレンダリングとペイントのイベント。これにより、コードがより予測可能になり、自由に使用できる16ミリ秒の時間を超えることを心配せずにアニメーションを実行する時間がたくさんあります。

小切手JakeArchibaldによるこの素晴らしいビデオ話題になっている。

私の無料ダウンロードJavaScriptビギナーズハンドブック


その他のブラウザチュートリアル: