キャンバス canvas の高速化手法 その1


キャンバスを使った二次元グラフィックを提供する際に、利用者のマシンの性能や利用しているブラウザによっては、パフォーマンスに影響が出ることがあります。
この改善のための手法をいくつか紹介します。

座標指定を浮動小数点から整数に

キャンバスの高速化手法の第一弾です。
一番手頃で簡単な手法の、座標指定を浮動小数点から整数に変換する方法から説明します。

浮動小数点が高速化に影響する理由

キャンバスで整数値以外の値を使用するとアンチエリアス処理が発生し、ブラウザが複雑な演算処理を行います。
結果、簡単な描画を行っているつもりが何故か処理が重くなる現象が発生します。
エンジニアが意図しない現象であれば、簡単に防げる対策を入れた方がいいでしょう。

《script》

var a = 0.7;
var b = 3;
var x = 8 * a;
var y = 8 / b;
ctx.drawImage(myImage, x, y);

上が配慮しないで座標に小数点を使った例です。

高速化に配慮した書き方

計算結果などで浮動小数点になってしまうのは、設計上で仕方がない事だと思います。
そこで登場するのが Math.floor() 関数です。
Math.floor() 関数は与えられた数値以下の最大の整数を返します。

《script》

var a = 0.7;
var b = 3;
var x = 8 * a;
var y = 8 / b;
ctx.drawImage(myImage, Math.floor(x), Math.floor(y));

こちらが高速化に配慮して、座標を整数に変換してから使った例です。
今回は座標だけを対象にしていますが、幅や高さの指定に対しても Math.floor() 関数を使うことが好ましいでしょう。

Math.floor() 関数を使用するタイミングですが、上記のXやYの変数は他の場所でも使用する可能性があり、計算と整数化を繰り返し行うと微妙に設計者の意図とズレてしまう可能性もあります。
このため、上記の例のように関数の引数にするタイミングで使用するというのは、一つの目安として好ましいと思います。
絶対に他で使用しない、もしくは重ねての演算処理はしないと分かっている変数であれば、この限りではありません。

Math.floor() 関数の注意点

先ほど、Math.floor()関数は与えられた数値以下の最大の整数を返すという説明をしましたが、言い方が分かり難いと思いますので、もう少しだけ見ておきましょう。

《script》

console.log(Math.floor(5.95));	// Expected output: 5
console.log(Math.floor(5.05));	// Expected output: 5
console.log(Math.floor(5));		// Expected output: 5
console.log(Math.floor(-5.05));	// Expected output: -6

一番上の 5.95 から 5 まではイメージ通りで全て 5 を出力し、ここまでは切り捨てと呼んでいいと思います。
きちんと理解すべきは一番下の負の数字に対して使用した場合で、先ほどの関数の定義通り、『与えられた数値以下の最大の整数を返す』ために、-5.05 の入力に対して出力は -6 となります。

ここまでがキャンバスの高速化手法 その1 になります。