Using drawImage with Canvas is very slow on Chrome
Asked Answered
A

1

12

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;
Amu answered 15/4, 2013 at 18:57 Comment(0)
D
8

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:

jspref chrome results

Notice the difference in 255x255 to 100x100 and 260x260 to 100x100.

Dc answered 23/5, 2013 at 15:44 Comment(2)
This was true for me as well. I saw huge amounts of lag until I made the canvases the exact same size.Palfrey
Although the bug tracker says the bug is fixed, Sam's point that there's a slowdown when the canvases are different sizes still holds. I have updated the answer to reflect this.Sybil

© 2022 - 2024 — McMap. All rights reserved.