HTML5のCanvasとSVGについて、様々な観点から比較していきたいと思います。
動作環境
今回の比較は下記の環境で行います。
OS:Windows7 64bit
メモリ:4GB
CPU:Intel Core2Duo E8400 3.00GHz
描画速度
単純に円を描画するだけの速度を比較してみます。
ちなみにソースコードはこんな感じ↓
window.onload = function() {
var time = new Date().getTime();
var div_canvas = document.getElementById("canvas");
var canvas = document.createElement("canvas");
div_canvas.appendChild(canvas);
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
var r = radius;
for( var i=0; i<width; i+=(r*2) ){
for( var j=0; j<height; j+=(r*2) ){
ctx.beginPath();
ctx.arc( i, j, r, 0, Math.PI*2, false);
ctx.fillStyle = '#FF0000';
ctx.fill();
}
}
console.log( new Date().getTime() - time );
}
window.onload = function() {
var time = new Date().getTime();
svg = document.createElementNS("http://www.w3.org/2000/svg","svg");
svg.setAttribute('width', width);
svg.setAttribute('height', height);
var div_svg = document.getElementById("svg");
div_svg.appendChild(svg);
var r = radius;
for( var i=0; i<width; i+=(r*2) ){
for( var j=0; j<height; j+=(r*2) ){
var circle = document.createElementNS("http://www.w3.org/2000/svg","circle");
circle.cx.baseVal.value = i;
circle.cy.baseVal.value = j;
circle.r.baseVal.value = r;
circle.style.strokeWidth = 0;
circle.style.fill = "#FF0000";
svg.appendChild(circle);
}
}
console.log( new Date().getTime() - time );
}
ブラウザ | Canvas | SVG |
---|---|---|
Chome | 21 | 185 |
IE9 | 207 | 258 |
FireFox | 192 | 460 |
ブラウザ | Canvas | SVG |
---|---|---|
Chome | 1 | 2 |
IE9 | 2 | 3 |
FireFox | 42 | 6 |
ブラウザ | Canvas | SVG |
---|---|---|
Chome | 46 | 184 |
IE9 | 140 | 256 |
FireFox | 114 | 456 |
上から順に、
・大量オブジェクト且つ描画領域大
・少量オブジェクト且つ描画領域大
・大量オブジェクト且つ描画領域小
を検証しています。
表を見て分かるように、下記のような結果になりました。
・全体的にSVGよりもCanvasの方が描画が早い。
・SVGはオブジェクト数に速度が依存している。
・Canvasはオブジェクト数・描画領域サイズに速度が依存している。
メモリ使用量
ソースコードは上記と同様です。
ブラウザ | Canvas | SVG |
---|---|---|
Chome | 12244 | 34316 |
ブラウザ | Canvas | SVG |
---|---|---|
Chome | 12272 | 26916 |
ブラウザ | Canvas | SVG |
---|---|---|
Chome | 12020 | 35140 |
表を見て分かるように、下記のような結果になりました。
・全体的にSVGよりもCanvasの方がメモリ使用量が少ない。
・SVGはオブジェクト数にメモリ使用量が依存している。
各円に対するクリック
円をクリックした際に、円の色を青色に変えるコードを比較してみます。
var Circle = function(x, y, r, fill) {
this.x = x;
this.y = y;
this.r = r;
this.fill = fill;
};
Circle.prototype.draw = function(ctx){
ctx.beginPath();
ctx.arc( this.x, this.y, this.r, 0, Math.PI*2, false);
ctx.fillStyle = this.fill;
ctx.fill();
};
window.onload = function() {
var time = new Date().getTime();
var div_canvas = document.getElementById("canvas");
var canvas = document.createElement("canvas");
div_canvas.appendChild(canvas);
canvas.width = 2000;
canvas.height = 2000;
var ctx = canvas.getContext('2d');
var circles = new Array();
var r = 10;
for( var i=0; i<2000; i+=(r*2) ){
for( var j=0; j<2000; j+=(r*2) ){
var circle = new Circle(i, j, r, '#FF0000');
circles.push(circle);
circle.draw(ctx);
}
}
var click = function(e){
var x = e.layerX;
var y = e.layerY;
for (var i = 0; i < circles.length; i++){
var dx = x - circles[i].x;
var dy = y - circles[i].y;
var d = Math.sqrt(dx*dx+dy*dy);
if(d <= circles[i].r){
circles[i].fill = '#0000FF';
circles[i].draw(ctx);
break;
}
}
};
canvas.addEventListener('click', click, false);
console.log( new Date().getTime() - time );
}
window.onload = function() {
var time = new Date().getTime();
svg = document.createElementNS("http://www.w3.org/2000/svg","svg");
svg.setAttribute('width', '2000');
svg.setAttribute('height', '2000');
var div_svg = document.getElementById("svg");
div_svg.appendChild(svg);
var r = 10;
for( var i=0; i<2000; i+=(r*2) ){
for( var j=0; j<2000; j+=(r*2) ){
var circle = document.createElementNS("http://www.w3.org/2000/svg","circle");
circle.onclick = function(){
this.style.fill = "#0000FF";
}
circle.cx.baseVal.value = i;
circle.cy.baseVal.value = j;
circle.r.baseVal.value = r;
circle.style.strokeWidth = 0;
circle.style.fill = "#FF0000";
svg.appendChild(circle);
}
}
console.log( new Date().getTime() - time );
}
SVGは各円がオブジェクトになっているため簡単に実装できますが、
Canvasは座標からどの円がクリックされたかを割り出す必要があるため、
SVGに比べると手間がかかります。
結論
今回は単純な円の描画なので単純に結論は出せませんが。。。
個人的には膨大な数のオブジェクトを描画する必要がある場合は、
パフォーマンス的にCanvasの方がいいのかなと感じています。
ただ、SVGには拡大しても画質が劣化しないという強みがあるため、
きれいに描画したい場合はSVGの方がいいですね。