为什么在许多浏览器中drawImage()的性能略好于createPattern()

Why does drawImage() perform slightly/noticeably better than createPattern() in many browsers?

本文关键字:性能 createPattern 浏览器 drawImage 为什么 许多      更新时间:2023-09-26

在研究如何在<canvas>上绘制重复的图像背景时(是的,我是<canvas>的新手),我发现有两种方法可以做到:

  1. for循环中使用drawImage()<canvas>上手动重复图像
  2. 使用context.createPattern()创建一个图案,将<canvas>fillStyle设置为该图案,然后使用fillRect绘制一个包含整个<canvas>的图案的矩形

显然,我做的第一件事就是创建一个JSPerf测试,看看哪个更快("过早优化™ —有效"):

  • http://jsperf.com/createpattern-vs-drawimage

drawImage()方式似乎优于createPattern()方式,尽管这种差异随着最近的浏览器而减少,并且在最近的浏览器中似乎消失了。

不过,我预计createPattern()的方式会更快。我认为createPattern()基本上会做与手动drawImage()方法相同的事情,但它是内置的,会做得更快。

有什么想法为什么createPattern()方法较慢吗?createPattern()除了在所应用的形状上重复绘制图案图像之外,还会做其他事情吗?我是不是在写试卷时犯了一个错误?

经过一些测试,我得到了相反的结果。

你做性能测试的方式有点奇怪。我对它进行了规范化,并将javascript代码从setup移动到prep(它应该在哪里)

http://jsperf.com/createpattern-vs-drawimage/2

填充图案似乎比chrome、IE、Firefox(略)、移动chrome(galaxy nexus)、iPad safari中的loop-drawImage更快。

此外,简单地制作图案(使用带有图案的fillRect或其他方式)并将其缓存到屏幕外画布上并从中绘图应该同样快。这两种方法都应该比使用循环多次调用drawImage更快。我添加了第三种方式作为测试中的第三个片段。

更重要的是,一个模式或缓存模式的好处应该随着图像重复次数的增加而显著增加。参见此处,例如:

http://jsperf.com/createpattern-vs-drawimage/3

其中绘制数百次图像会使createPattern的效率比drawinimage循环高100-200倍

我在试图了解Javascript中的闭包和循环嵌套时感到非常沮丧——我对VB更有经验,并开始使用JS制作有趣的小游戏。

总之,长话短说,我不确定效率水平,但这对我来说起到了作用:

function body_onload(){
var canvas = document.getElementById('canvas-id');
var context = canvas.getContext('2d');
var width = canvas.width;
var height = canvas.height;
var image = new Image();    
function drawBackground(){
    context.fillStyle=context.createPattern(image, "repeat");;
    context.fillRect(0,0,width,height);
    }
image.src="grass.jpg";
image.onload = drawBackground;

}

第一次为我工作。甚至尝试引用一个实际的<img>,而不是仅仅使用JS创建一个新的图像,我在这里发布的方法似乎更容易使用,尤其是如果我想更改图像,我可以很容易地做到这一点。

我相信这会更有效率。如果有人知道怎么做,我很想听听!