requestAnimationFrame
はJavaScriptで繰返し処理をするために新たに追加されたメソッドです。
全てのブラウザでサポートされていないので実装するためには下位互換を施さなければなりません。
http://caniuse.com/#search=requestAnimationFrame
上記caniuse.comのリポートだと実装されている方が圧倒的に少ない状況です。
実装されていても-webkit, -mozなどのprefixが必要だったりします。
なぜrequestAnimationFrameを使った方が良いの?
今までの繰返し(loop)処理はtimeベースを使っていました。
setTimeout, setIntervalのどちらかです。
この方式だと、ユーザーがアニメーションしているサイトを表示したまま別のタブ、ウインドウを開いてもタイマーが動いたままになり不必要なメモリを浪費してしまいます。
対策として開発者はユーザーのfocusが外れblurになったらループを止め、focusが戻ったらループを開始する処理を組み込む必要があります。
そこでrequestAnimationFrame
です。
jQuery開発メンバーの一人Paul Irishさんのブログによれば、requestAnimationFrameを使うとCPU, GPU, メモリ消費を抑えバッテリーライフをのばせるとのことです。
requestAnimationFrame for smart animating
if you’re running the animation loop in a tab that’s not visible, the browser won’t keep it running
こちらでは2種類の対策コードが公開されています。
ひとつはPaul Irishさんによるもの
// shim layer with setTimeout fallback window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function( callback ){ window.setTimeout(callback, 1000 / 60); }; })(); // usage: // instead of setInterval(render, 16) .... (function animloop(){ requestAnimFrame(animloop); render(); })(); // place the rAF *before* the render() to assure as close to // 60fps with the setTimeout fallback. |
function renter () {}
が描画部分になります。上記コード中には実行部分しか記述されていないので、作っておく必要があります。
次はOpera開発エンジニアのErik Möllerさんによるもの
(function() { var lastTime = 0; var vendors = ['ms', 'moz', 'webkit', 'o']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; } if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { clearTimeout(id); }; }()); |
requestAnimationFrame for smart(er) animating
ふむふむ、Erik MöllerさんのコードはrequestAnimationFrame
だけでなくcancelAnimationFrame
も実装してるのね。
これはステキすぎる。
キャンセルできるのはありがたい。
まだ試してないけど、コードを見るとこんな使い方かな。
var id; function animloop(){ id = requestAnimFrame(animloop); render(); }; window.onclick = function () { cancelAnimationFrame(id); } animloop(); |
MDN: requestAnimationFrame
MDN: cancelAnimationFrame
ピンバック: 超個人的メモ, JavaScript関連の投稿リンクをまとめておく « イナヅマTVログ
ピンバック: [JavaScript] requestAnimationFrame, cancelAnimationFrame はこう使ってる « イナヅマTVログ
ピンバック: [JavaScript] 今さらながらrequestAnimationFrameをもう一度 « イナヅマTVログ