読み書きプログラミング

日常のプログラミングで気づいたことを綴っています

JavaScriptパフォーマンスベストプラクティスその7

Nokia Developerより

アニメーション

アニメーションは控えめにすること
  • ハードウェアサポートのないアニメーションは遅い。本当の有用性の価値をもたらさない余分なアニメーションを避けるようにすること。少なくともユーザーにアニメーションを無効にする機会を与えること。
  • Animation without hardware support is slow. Try to avoid excessive use of animations which do not bring any real usability value. At least give users an opportunity to disable animations.
スクロールをアニメーションするのにscrollTo()を使うこと
  • scrollTo()を介してネイティブのスクロースを使うと、リフローの引き金にならないのでとてもよく動く。
  • Using native scrolling via scrollTo() performs significantly better as it does not trigger reflow.
アニメーションする要素はabsoluteかfixedで位置すること
  • デフォルトでは、要素はスタイルプロパティposition: staticを持ち、そんな要素をアニメーションすると、レイアウトのリフローが起こり、高価だ。
  • スムーズなアニメーションやより少ないCPU負荷のためにリフローが必須ではないなら、アニメーションする要素はposition: absoluteかposition: fixedに設定すべき。そんな要素は他の要素のレイアウトに影響せず、完全なリフローではなく再描画のみを起こし、いいパフォーマンス向上になる。
  • positionプロパティに関するCSS位置決めスキーム:
Positionの値 説明
static デフォルト。position: staticの要素は常にページの通常のフローがそれに与える位置になる。(static要素はtop, bottom, left, right宣言のいずれも無視する。)
relative position: relativeの要素は通常の位置から相対的に要素を移動させる。なので、left: 20pxは20ピクセルを要素の左の位置に加える。
absolute position: absoluteの要素はそれを含むブロックに相対に特定の座標で位置される。要素の位置はleft, top, right, bottomプロパティで指定される。
fixed position: fixedの要素はブラウザウィンドウに相対に特定の座標で位置される。要素の位置はleft, top, right, bottomプロパティで指定される。要素はスクロールに関わらずその位置に居続ける。
  • By default elements have style property position: static and animating such elements causes reflowing of the layout and is expensive.
  • Elements to be animated should be set as position: absolute or position: fixed if reflowing is not mandatory for smoother animation and lesser CPU load. Such elements do not affect other elements layout, so they will only cause a repaint rather than a full reflow with a nice performance boost.
  • CSS positioning schemes for position property:
Position value Description
static Default. An element with position: static always has the position the normal flow of the page gives it (a static element ignores any top, bottom, left, or right declarations)
relative An element with position: relative moves an element relative to its normal position, so left:20 adds 20 pixels to the element's left position
absolute An element with position: absolute is positioned at the specified coordinates relative to its containing block. The element's position is specified with the left, top, right, and bottom properties.
fixed An element with position: fixed is positioned at the specified coordinates relative to the browser window. The element's position is specified with the left, top, right, and bottom properties. The element remains at that position regardless of scrolling.

ソース:

同時に複数の要素をアニメーションする時にタイマーを1つだけ使うこと
  • setTimeout()とsetInterval()タイマーはアニメーションを実装する2つの基本メソッドだ。(すなわち、引き金が時間をおって、要素のサイズや位置、見た目を変更する。)
  • 複数の要素を同時にアニメーションするなら、1つのループ内でアニメーションする要素すべてに渡って繰り返すことによって最高のフレームレートが実現される。複数のタイマーを使うと、おそらくはタイマー呼び出しのオーバーヘッドのせいで、アニメーションが非効率で一貫性のないものになる。
  • setTimeout() and setInterval() timers are two basic methods used to implement animation (i.e. trigger changes to element size, position and/or appearance over time).
  • If multiple elements are animated at the same time, the best frame rate is achieved by iterating across all animated elements inside a single loop. Using multiple timers makes animation less efficient and consistent, presumably due to timer invocation overhead.

遅い:

setInterval(function() {
    animateFirst(arg);
}, 50);
setInterval(function() {
    animateSecond(arg);
}, 50);
function animateFirst(arg) {};
function animateSecond(arg) {};

速い:

setInterval(function() {
    animateFirst(arg);
    animateSecond(arg);
}, 50);
function animateFirst(arg) {};
function animateSecond(arg) {};

ソースと次の読み物:

アニメーションの滑らかさを速度と交換すること

滑らかさを速度と交換することは、1度に1ピクセルのアニメーションを動かしたい一方で、その場合、アニメーションと続いて起こるリフローはCPUを100%使用するかもしれず、フローを更新するために、ブラウザが強制的にフレームを落とされるのでアニメーションがガタガタしたものになるだろう。例えば一度に5ピクセルずつアニメーションする要素を動かせば、速いマシンでは少し滑らかではなくなるかもしれないが、モバイルデバイスでのCPUののたうちを引き起こさないだろう。

To trade smoothness for speed means that while you may want to move an animation 1 pixel at a time, the animation and subsequent reflows may in that case use 100% of the CPU and the animation will seem jumpy as the browser is forced to drop frames to update the flow. Moving the animated element by e.g. 5 pixels at a time may seem slightly less smooth on faster machines, but won’t cause CPU thrashing that easily on mobile devices.