I've been trying to draw a large number of instances of an SVG file to a canvas using drawImage. By creating a single image element using the SVG as the source, then using drawImage for each instance on the canvas, I was hoping I could produce a composite image in the canvas very quickly even with a large number of instances.
Performance-wise, this works well in Firefox - I can draw 60,000 instances in about 300ms. But on Chrome it is terribly slow: 16,000 instances is taking over 5 seconds. I've put a version of the code on jsfiddle, which demonstrates the problem on Chrome.
I've got an example of how I'm calling drawImage below, where the canvas is filled with as many size x size images as possible. I had read a suggestion to try using a second, hidden canvas to buffer all the instances, then update the visible canvas with one call. But that didn't impact performance, the individual drawImage calls still appear to be bogging things down.
Any thoughts on what's going wrong and what I can do to fix it?
svgImg = new Image;
can.width = 1800; can.height = 900;
svgImg.onload = function () {
if (internalSize == size)
return;
internalSize = size;
var timeBefore = new Date().getTime();
var tot = 0;
var canWidth = can.width;
var canHeight = can.height;
for (var x = 0; x < canWidth; x += size) {
for (var y = 0; y < canHeight; y += size) {
ctx.drawImage(svgImg, x, y, size, size);
tot++;
}
}
document.getElementById('count').innerHTML = "Total Count: " + tot;
var timeAfter = new Date().getTime();
};
svgImg.src = "http://www.w3.org/Icons/SVG/svg-logo.svg";
svgImg.width = size;
svgImg.height = size;
Slowdown 1: Occurs when either the source or destination canvas is in RAM and the other canvas is on GPU.
Slowdown 2: Occurs when src and dest canvases are different sizes
Relevant bug: http://code.google.com/p/chromium/issues/detail?id=170021
I have noticed the same issue, and simplified the case to drawing one blank canvas to another. It doesn't seem to be an issue when the canvases are the same size, but at a certain point performance takes a nose dive. Here is the jspref, and my results:
Notice the difference in 255x255 to 100x100 and 260x260 to 100x100.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With