var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var colors=['red','green','blue','gold'];
var playersOnscreen=[];
var playersOffscreen=[];
for(var c=0;c<colors.length;c++){
var color=colors[c];
for(var p=0;p<100;p++){
playersOnscreen.push({x:50,y:50,r:10,color:color});
}
}
for(var c=0;c<colors.length;c++){
var color=colors[c];
for(var p=0;p<100;p++){
playersOffscreen.push({x:-50,y:50,r:10,color:color});
}
}
var count=100;
var t1=performance.now();
for(var i=0;i<count;i++){ drawIndividualPaths(playersOnscreen); }
var t2=performance.now();
for(var i=0;i<count;i++){ drawIndividualPaths(playersOffscreen); }
var t3=performance.now();
for(var i=0;i<count;i++){ drawColorPaths(playersOnscreen); }
var t4=performance.now();
for(var i=0;i<count;i++){ drawColorPaths(playersOffscreen); }
var t5=performance.now();
alert('onscreen/individual='+parseInt(t2-t1)+', offscreen/individual='+parseInt(t3-t2)+', onscreen/by color='+parseInt(t4-t3)+', offscreen/by color='+parseInt(t5-t4));
function drawIndividualPaths(players){
var len=players.length;
var PI2=Math.PI*2;
for(var i=0;i<len;i++){
var p=players[i];
ctx.beginPath();
ctx.arc(p.x,p.y,p.r,0,PI2);
ctx.fillStyle=p.color;
ctx.fill();
}
}
function drawColorPaths(players){
var len=players.length;
var PI2=Math.PI*2;
var clen=colors.length;
for(var c=0;c<clen;c++){
var color=colors[c];
ctx.fillStyle=color;
ctx.beginPath();
for(var i=0;i<len;i++){
var p=players[i];
if(p.color==color){
ctx.moveTo(p.x,p.y);
ctx.arc(p.x,p.y,p.r,0,PI2);
}
}
ctx.fill();
}
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<h2>Please wait for perf tests to complete</h2>
<canvas id="canvas" width=300 height=300></canvas>