Test name | Executions per second |
---|---|
fillRect/concat | 107.3 Ops/sec |
fillRect/join | 109.0 Ops/sec |
1×1 Image Data | 655.8 Ops/sec |
fillRect/template literal | 109.4 Ops/sec |
getImageData/putImageData | 363.0 Ops/sec |
getImageData/putImageData - set px.rgba | 344.7 Ops/sec |
getImageData/putImageData - set [px.r, px.g, px.b, px.a] | 338.2 Ops/sec |
getImageData/putImageData - set - no getImageData | 285.3 Ops/sec |
<canvas id="c" width="800" height="600"></canvas>
$c = document.getElementById('c');
$ctx = $c.getContext('2d');
$ctx.clearRect(0, 0, 800, 300);
$px = $ctx.createImageData(1, 1);
$id = $ctx.getImageData(0, 0, 800, 600);
$pxls = [];
for (var i = 0; i < 1000000; ++i) {
const pxl = {
x: Math.random() * 800 << 0,
y: Math.random() * 300 << 0,
r: Math.random() * 255 << 0,
g: Math.random() * 255 << 0,
b: Math.random() * 255 << 0,
a: Math.random() * 128 << 0 + 128
};
pxl.rgba = [pxl.r, pxl.g, pxl.b, pxl.a];
$pxls.push(pxl);
};
$i = 0;
$iterations = 5000;
/*
At 1500+ $iterations the putimagedata/getimagedata starts to win and at 5000 it slaughters. Below that the other methods win
So it depends on how many you plan on drawing each frame
*/
for (var i=$iterations;i--;){
var px = $pxls[$i++ % 10000];
$ctx.fillStyle = 'rgba(' + px.r + ',' + px.g + ',' + px.b + ',' + (px.a / 255) + ')';
$ctx.fillRect(px.x, px.y, 1, 1);
}
for (var i=$iterations;i--;){
var px = $pxls[$i++ % 10000];
$ctx.fillStyle = 'rgba(' + [px.r,px.g,px.b,px.a/255].join() + ')';
$ctx.fillRect(px.x, px.y, 1, 1);
}
for (var i=$iterations;i--;){
var px=$pxls[$i++ % 10000], d=$px.data;
d[0] = px.r;
d[1] = px.g;
d[2] = px.b;
d[3] = px.a;
$ctx.putImageData($px, px.x, px.y);
}
for (var i=$iterations;i--;){
var px = $pxls[$i++ % 10000];
$ctx.fillStyle = `rgba(${px.r},${px.g},${px.b},${px.a/255}})`;
$ctx.fillRect(px.x, px.y, 1, 1);
}
var canvasWidth = $c.width;
var canvasHeight = $c.height;
var id = $ctx.getImageData(0, 0, canvasWidth, canvasHeight);
var pixels = id.data;
for (var i=$iterations;i--;){
var px = $pxls[$i++ % 10000];
var off = (px.y * canvasWidth + px.x) * 4;
pixels[off] = px.r;
pixels[off + 1] = px.g;
pixels[off + 2] = px.b;
pixels[off + 3] = px.a;
}
$ctx.putImageData(id, 0, 0);
var canvasWidth = $c.width;
var canvasHeight = $c.height;
var id = $ctx.getImageData(0, 0, canvasWidth, canvasHeight);
var pixels = id.data;
for (var i=$iterations;i--;){
var px = $pxls[$i++ % 10000];
var off = (px.y * canvasWidth + px.x) * 4;
pixels.set(px.rgba,off);
}
$ctx.putImageData(id, 0, 0);
var canvasWidth = $c.width;
var canvasHeight = $c.height;
var id = $ctx.getImageData(0, 0, canvasWidth, canvasHeight);
var pixels = id.data;
for (var i=$iterations;i--;){
var px = $pxls[$i++ % 10000];
var off = (px.y * canvasWidth + px.x) * 4;
pixels.set([px.r,px.g,px.b,px.a],off);
}
$ctx.putImageData(id, 0, 0);
var canvasWidth = $c.width;
var canvasHeight = $c.height;
//var id = $ctx.getImageData(0, 0, canvasWidth, canvasHeight);
var pixels = $id.data;
pixels.fill();
for (var i=$iterations;i--;){
var px = $pxls[$i++ % 10000];
var off = (px.y * canvasWidth + px.x) * 4;
pixels.set(px.rgba,off);
}
$ctx.putImageData($id, 0, 0);