requestAnimationFrameの仕組みと使い方!うまく使ってパフォーマンスを改善しよう!

記事の前半では実例を交えながらrequestAnimationFrameの仕組みと使い方をご説明します。
また、記事の後半ではrequestAnimationFrameを使った繰り返し処理、setTimeoutsetIntervalのように時間指定を行って使用する方法もご説明します。

requestAnimationFrameとは

Javascriptでアニメーションを行う時にrequestAnimationFrameを使うとパフォーマンスの低下を防ぐことができます。
簡単にいうとrequestAnimationFrameは渡した関数をブラウザの表示を邪魔しないタイミングで処理されるようにする関数です。

基本文法

引数に実行したい関数を渡すだけでその関数が、ブラウザにとって最適なタイミングで処理されるようになります。言葉ではなかなか伝わりづらいので、requestAnimationFrameのメリットがわかる例を2つ用意しました。

requestAnimationFrameを使うメリット

メリット1. 関数実行タイミングの最適化

この使い方がrequestAnimationFrameの一般的な用途です。従来よく使われるsetTimeoutsetIntervalなどの時間指定の関数はブラウザのフレーム(画面)を更新するタイミングでも関係なく実行されます。その結果、フレーム更新とJavascriptの実行が重なり、フレームレートの低下をもたらします。

フレームの更新を邪魔してしまう例

setTimeout、setIntervalを使った際にフレームの更新を邪魔してしまう例

*アニメーションやスクロールをスムーズに表示するためには、画面のフレームレート(更新頻度)を60fps(16msに一回)に保つことが重要です。

処理タイミングを最適化した例

requestAnimationFrameでアニメーションタイミングを最適化した例

一方、requestAnimationFrameを利用した場合はフレーム更新の処理直後に引数に渡した処理が実行されます。そのためフレームの更新を邪魔することがなく、フレームレイトを最適に保つことができます。

メリット2. 関数の分割実行

Javascriptの処理が長すぎる場合には、requestAnimationFrameが利用できるケースがあります。

Javascriptの処理が長すぎて処理が更新できない
下図のような場合、Javascriptの処理がおもすぎるため、最適なフレームレートが保てません。

Javascriptの処理が長すぎて処理が更新できない

Javascriptの処理を分割して1フレームの処理量を削減
長過ぎる処理の一部をrequestAnimationFrameで処理を分割して、最適なフレームレートを保つ事ができます。

Javascriptの処理を分割して1フレームの処理量を削減

requestAnimationFrameを使ってみよう

フレームごとに繰り返し実行する場合

使い方によってsetIntervalのような処理を実装できます。(この繰り返し処理はブラウザのフレーム更新ごとに行われます。)
また、戻り値をhandlerに保存しておくことで、後にキャンセルをすることが可能となります。

requestAnimationFrameのキャンセル処理のデモ
このデモではrequestAnimationFrameで数字をカウントアップして、画面上のどこかをクリックすると処理が停止するように作成されています。

See the Pen
Countup w/ requestAnimationFrame interval Demo
by Masahiro Tonomura (@M-Tonomura)
on CodePen.

setTimeout, setIntervalのように時間を指定して実行する

先程の例では時間指定はできませんでしたが、時間を考慮した実装にすることによってrequestAnimationFramesetTimeout, setIntervalの様に時間指定で実行することもできます。

こちらは@joyrexusさんがコード公開しているので、興味のある方はそちらをご確認ください。

Githubを開く

ブラウザ対応状況

基本的にメジャーなブラウザでは使用可能です。IEは10以上で使用可能です。

まとめ

setTimeout, setIntervalはブラウザの状況を考えず時間が来たら実行されるため、ブラウザのレンダリングを邪魔してしまうことがあります。
なるべく、requestAnimationFrameを使用して、ブラウザに優しい実装を行いましょう。

おすすめ記事

レンダリングのパフォーマンス対策入門〜アニメーション、JSで困った時に

最新記事