简体   繁体   中英

Can the performance of this canvas drawImage() test be improved?

I have a quite simple loop that draws an 8px by 8px image many times in a canvas in a tiling fashion. Currently it's drawing 7500 images each loop.

See the jsfiddle.

var img = new Image();
img.src = 'http://i.imgur.com/3dzaMlv.png';

var W = 8;
var H = 8;
var R = 800/W;
var C = 600/H

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

var fps = document.getElementById('fps');
var timePrev = new Date().getTime();
var fpsInterval = 30;
var i = 0;

window.setInterval(function() {

    ctx.clearRect(0, 0, 800, 600);

    for (var r=0 ; r<R ; r++) {
        for (var c=0 ; c<C ; c++) {
            ctx.drawImage(img, r*W, c*H);
        }
    }

    // fps
    if (i % fpsInterval == 0) {
        var timeNow = new Date().getTime();
        var spf = (timeNow - timePrev) / fpsInterval / 1000;
        fps.innerHTML = (1/spf).toFixed(2);
        timePrev = timeNow;
    }
    i++;

}, 1000/60);

On my I7-2700K (3.5GHz) processor and ATI Radeon HD7970, I am getting the following framerates:

  • Chrome 36.0.1985.143 m : ~40 FPS
  • Firefox 30.0 : ~55 FPS
  • IE 11.0.9600.17239 : ~35 FPS

Is there any way to improve FPS performance here, assuming I do actually need to draw this many tiles on each update?

EDIT: To clarify, I'm requiring that they be drawn as individual tiles on each update. So, rendering them all to an off-screen canvas wouldn't work. I am essentially disappointed in the number of drawImage() calls that seems to perform well.

Use requestAnimationFrame instead of setInterval , see http://www.w3.org/TR/animation-timing/ . Your code may be rewritten like this: http://jsfiddle.net/fv99o6jc/

在此处输入图片说明

Here's one way to use far fewer drawImage's:

// make a template column
for(var y=0;y<ch;y+=ih){
    ctx.drawImage(img,0,y);
}

// flood-fill with the template column
for(var x=iw;x<cw;x+=iw){
    ctx.drawImage(canvas,0,0,iw,ch,x,0,iw,ch);
}

A Demo:

 var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var cw=canvas.width; var ch=canvas.height; var img=new Image(); img.onload=start; img.src="http://i.imgur.com/3dzaMlv.png"; function start(){ var iw=img.width; var ih=img.height; // make a template column for(var y=0;y<ch;y+=ih){ ctx.drawImage(img,0,y); } // flood-fill with the template column for(var x=iw;x<cw;x+=iw){ ctx.drawImage(canvas,0,0,iw,ch,x,0,iw,ch); } } 
 body{ background-color: ivory; padding:10px; } #canvas{border:1px solid red;} 
 <canvas id="canvas" width=300 height=300></canvas> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM