こんにちは!ケインコスゲです。
JavaScriptのrequestAnimationFrameについて改めて理解を測ってみたいと思います。
JavaScriptで一定間隔で特定のプログラムを実行したい場合によく使われるのが、setTimeoutやsetIntervalといったものになります。
今回はそれ以外の選択肢として、requestAnimationFrameを使ったプログラムの紹介をしたいと思います。
目次
requestAnimationFrameとは?基本的な書き方も紹介
まずはrequestAnimationFrameとは何かについて、setIntervalやsetTimeoutとの違いも見ながら書いていきたいと思います。
requestAnimationFrameは、定期的に特定のプログラムを実行することができるものになっています。
書き方でよくあげられるのが上記画像に掲載したようなコード例です。
window.requestAnimationFrame()と記述した上で、丸括弧の中に繰り返し繰り返し実行したい関数(プログラムのかたまり)の名前を記述します。
また、指定する関数は、requestAnimationFrameの部分が記述されている関数そのものの名前を指定してあげます。
こうすることで、何度も何度も繰り返し同じプログラムを実行することができるようになっているのです。
(上記画像のコードであれば、一定間隔でブラウザのconsoleの部分に、「動いた?」という文字が表示されるようになります。consoleって何?という方は、ショートカットで覚えるGoogle Chromeデベロッパーツールの使い方・ JavaScript編をぜひご覧になってみてください!)
requestAnimationFrameとsetIntervalやsetTimeoutとの違い
requestAnimationFrameと似たようなものとして、setIntervalやsetTimeoutというものがJavaScriptには存在しています。
setIntervalは、一定時間間隔で特定のプログラムを繰り返し実行するために使用されるものになります。
setTimeoutは、元々の使い方としては、「何秒後に特定のプログラムを指定する」といったようなことができるものになっていますが、書き方を工夫することで、setIntervalと同じように「一定時間間隔で特定のプログラムを繰り返し実行する」ような使い方もできるようになっています。(具体的には、http://cly7796.net/wp/javascript/loop-processing-with-settimeout/さんなどでご紹介されているので、気になる方は参考にしてみてください!)
じゃあrequestAnimationFrameとsetIntervalやsetTimeoutって一体何が違うのか?という話になってくると思うのですが、これらには大きな違いがあります。下記をご覧ください!
- setIntervalやsetTimeout・・・繰り返し実行するプログラムの実行間隔(時間)を直接数字でプログラムに書いて指定する。
- requestAnimationFrame・・・繰り返し実行するプログラムの実行間隔(時間)を直接数字で指定することができない。60fpsの間隔(たいていの場合1秒間に60回の速さ)でプログラムを実行する仕様になっている。
requestAnimationFrameとsetIntervalやsetTimeoutには、このような違いがあります。
setIntervalやsetTimeoutは、「setInterval(function(){}, 1000)」のようにプログラムの実行間隔を数字で指定することができるので、わかりやすい印象がありますよね。
また、requestAnimationFrameのところで書かれていた「60fps」については、ブラウザやPC・スマホのプログラム処理速度などによってはその間隔が遅くなる場合があるので、必ずしも1秒間に60回のプログラム実行が保障されるというものではありません。
他にも、requestAnimationFrameとsetIntervalやsetTimeoutには違いがあります。
代表的なものとして「そのページが開かれていない時( PCブラウザで別タブなどを開いている時)」は、アニメーションの実行間隔をわざと遅くしてくれるという特徴がrequestAnimationFrameには存在しています。
そう考えると、requestAnimationFrameは表示パフォーマンス的には非常に良いものということなんですね!
requestAnimationFrameでプログラムの実行間隔を数値で指定したい場合の方法
前の章で、requestAnimationFrameとsetIntervalやsetTimeoutの違いについてご紹介をさせていただきました。
ここまでお読みいただいた方の中には「requestAnimationFrameのように表示パフォーマンスに優しくて、かつsetIntervalやsetTimeoutのようにプログラムの実行間隔を数値でわかりやすく指定可能、両方のいいとこ取りができたらいいなぁ」と思った方もいらっしゃるかもしれません。
いいとこ取りなやり方にできるだけ近づける方法について、ここでは見ていきたいと思います。
今回は実際のサンプルコードを交えてご紹介してみたいと思います!
プログラムの中でperformance.now()というものが出てきました。このperformance.now()を使うことによって、requestAnimationFrameでプログラムの実行間隔を数値で指定するのに近い方法を見出すことができます。
Vue.jsでストップウォッチを作成してみたよ!filtersとcomputedについても言及という記事でもご紹介させていただきましたが、performance.now()は、事実上ブラウザでそのページが表示されてからの経過時間を、ミリ秒単位で取得することができるというものになっています。
上記サンプルコードでは、1番最初に表示された時間をstartTimeと定義して、アニメーションが実行されたタイミングで再びブラウザが表示されてからの経過時間を取得し(currentTime)、currentTimeからstartTimeを引き算して1000で割って、小数点以下を切り捨てした計算結果が1になったら「●秒経過」と表示している、簡単にいうとそんなロジックになっています。
まとめ
ということで、今回はJavaScriptのrequestAnimationFrameについてご紹介させていただきました!
今回のように基本を改めてブログにまとめてみると、新しい発見をすることもあったりして、自分にとっても為になるなと感じました。
今後も定期的に基本を抑えるシリーズを続けていきたいと思います!