javascriptでアニメーション操作を行う際は以下の3つの関数のどれかで行うことができる。
1. setInterval
2. setTimeout
3. requestAnimationFrame
この3つのどれを使用するかによって、システムの性能が変わる場合があるが、メリット・デメリットがあるので、
それを理解しておく必要があるので、きちんと覚えて設計に役立てよう。
setInterval
# 構造
var si = setInterval(*function* , *delay*);
この関数は、初回に一度セットしたら、delayのタイミングでfunctionを都度起動してくれる処理です。
特徴としては、function処理の内容に関わらず、必ずdelayのタイミングをキープしてくれるので、
メリットは時間配分が一定で行えるという事ですが、
デメリットは、function処理が重くその処理時間がdelayを超えてしまう場合には、とても処理効率が悪くCPU負荷の高い仕組みになってしまいます。
ちなみに、「var si」に引数として入れているのは、この連続処理を停止したい場合に、この「si」をclearIntervalすることで、アニメーション処理を停止することができるという使い方です。
setTimeout
# 構造
setTimeout(*function* , *delay*);
この関数は、delay時間経過後に一度だけfunctionを実行してくれるという事で、最近よく見る使い方として、function内に再度setTimeoutでself-functionを指定して、setIntervalと同じような動作をするようにしています。
特徴としては、単一処理をdelay後に実行とすることで分かりやすい処理が作れる点で、function処理が終わった後でsetTimeoutすることで、delayよりも処理が遅くなった場合に、処理が重複実行されるような事を防ぐことができます。
モバイル端末などの実行を考えると、低速にも対応できるという点がメリットですが、
定期実行するという点においては、functionの処理時間分のタイムロスが発生する事になるので、時刻連動するような処理では、誤差が生じてしまいます。
アニメーション設定をした場合に、別途フラグ変数を用いて、読み込むfunctionを随時切り替えるような柔軟な処理も行えるのでアニメーション処理では、一番スタンダードな関数といえます。
requestAnimationFrame
requestAnimationFrame(*function*);
あまり聞かないこの命令ですが、旧ブラウザ(特にIE)が対応していないということもあり、HTML5からの機能と理解しておいたほうがいいですね。
スマホ系では使用してもいいんですが、PCがブラウザは使えないリスクもあるので、危険かもしれません。
ただ、各ブラウザの最新バージョンでは動作対象になっているのですが、jQueryでも過去に使えてた時期はあるが、今現在では、使用できなくなっているようで、コンフリクトしてしまう場合もあるようです。
この関数の特徴として、delayというセットがなく、描画処理に基いて、次の描画タイミングの際にfunctionを実行してくれるイベントのような使い方ができます。
animation命令の中では、CPU負荷が一番軽いという事で、その点においては、他の2つの命令よりもモバイルで使用するメリットが高い関数です。
ただし、この関数だけ非常に大きなデメリットがあり、各ブラウザ毎にベンダープレフィックスが設けられており、使用できる関数名が違うので、下記のサンプルのように事前に関数をwrapする必要があります。
(function() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
})();
サンプル
下記のコードを保存したファイルをブラウザで表示すると、3つの命令での数値加算状況を描画するようになっています。
レスポンススピードや、それぞれのdelayバランス間隔や比較などが見て分かるので、参考になると思います。
<!DOCTYPE html>
<html lang="js">
<head>
<meta charset="utf-8">
<title>labo</title>
</head>
<body>
<h1>JS Animation</h1>
<div id="hoge-0"></div>
<div id="hoge-1"></div>
<div id="hoge-2"></div>
<script src="sample.js"></script>
</body>
</html>
(function(){
//setInterval
var num0 = 1;
function loop0(){
num0++;
document.getElementById("hoge-0").innerHTML = num0;
}
setInterval(loop0,20);
//setTimeout
var num1 = 1;
function loop1(){
num1++;
document.getElementById("hoge-1").innerHTML = num1;
setTimeout(loop1,20);
}
loop1();
//setTimeout
var num2 = 1;
function loop2(){
num2++;
document.getElementById("hoge-2").innerHTML = num2;
requestAnimationFrame(loop2);
}
loop2();
})();
以下のリンクでも見られるようになっています。
http://ideacompo.com/javascript/animation/
まとめ
CPU処理を気にする場合「requestAnimationFrame」が有利に思えますが、setTimeoutとsetIntervalではdelayでタイミングコントロールすることができるので、処理の負荷計算や端末スペックなどを考慮できれば、設計でカバーできるという事を考えれば、ベンダープレフィックス問題があるrequestAnimationFrameを使うことのデメリットが目立つ感じです。
setIntervalとsetTimeoutについては、使用用途により異なりますが、基本的にsetTimeoutで構築することを念頭に置けば設計の安定化が図れるのではないでしょうか?
個人の好き嫌いもあるかもしれませんが、こういった特性を理解して構築するように心がけましょう。
0 件のコメント:
コメントを投稿