Redrawing HTML5 canvas incredibly slow

canvas, html

Solution

Here's the code made much better.

http://jsfiddle.net/zHpgV/3/

Here's a breakdown of the things that you should take into consideration that I changed:

- Continuous adding to a path instead of stopping and creating a new path with `beginPath`. This is by far the biggest performance killer here. You're ending up with a path with thousands and thousands of line segements that never gets cleared.

- Continuously making the same path over and over when it only needs to be made once, on initialization. That is, the only thing you need to call inside of `render` is `stroke`. You do not need to call `lineTo/moveTo` ever again, and certainly not continuously. See note 1.

- Stroking twice for one path

- Stroking inside a for loop

- Redrawing a background instead of setting CSS background

- Setting the line cap over and over

Note 1: If you plan to have more than one path in your application then you should probably cache paths like this one since they never change. I have a a tutorial on how to do that here.

Of course, if you are doing all of this to just make a background, it should be saved as a png and you should be using a CSS background-image.

Like so: http://jsfiddle.net/zHpgV/4/

Then suddenly your render routine is rather small:

function render() {
    c.clearRect(0, 0, scale, scale);
    c.fillText('{0}, {1}'.format(mouseX, mouseY), 0.5, 1.5);
}

Problem

I just started playing with the HTML5 canvas and I was hoping to make a couple games with it. However, as soon I started rendering the mouse coordinates to it, it grinded to a near halt: http://jsfiddle.net/mnpenner/zHpgV/ All I did was render 38 lines and some text, it should be able to handle that, no? Am I doing something wrong? I'd like to be able to render at least 30 FPS, but for something like this I would expect it to be able to draw 1000s of times. Or am I just using the wrong tool for the job? Is WebGL up for the task? Why would one be so much slower than the other? ``` String.prototype.format = function() { var args = arguments; return this.replace(/\{(\d+)\}/g, function(m, n) { return args[n]; }); }; var $canvas = $('#canvas'); var c = $canvas[0].getContext('2d'); var scale = 20; var xMult = $canvas.width() / scale; var yMult = $canvas.height() / scale; var mouseX = 0; var mouseY = 0; c.scale(xMult, yMult); c.lineWidth = 1 / scale; c.font = '1pt Calibri'; function render() { c.fillStyle = '#dcb25c'; c.fillRect(0, 0, scale, scale); c.fillStyle = '#544423'; c.lineCap = 'square'; for (var i = 0; i <= 19; ++i) { var j = 0.5 + i; c.moveTo(j, 0.5); c.lineTo(j, 19.5); c.stroke(); c.moveTo(0.5, j); c.lineTo(19.5, j); c.stroke(); } c.fillStyle = '#ffffff'; c.fillText('{0}, {1}'.format(mouseX, mouseY), 0.5, 1.5); } render(); $canvas.mousemove(function(e) { mouseX = e.clientX; mouseY = e.clientY; render(); }); ``` ``` <canvas id="canvas" width="570" height="570"></canvas> ```

Original source

Related problems