Javascript context.clearRect()真的那么贵吗?

Javascript context.clearRect()真的那么贵吗?,javascript,html,performance,canvas,html5-canvas,Javascript,Html,Performance,Canvas,Html5 Canvas,我有一幅画布动画,展示了一些奇怪的特征: 我使用的是最新版本的Chrome。我正在使用Chrome内置的FPS监视器(您可以通过转到about:flags)来激活它)。 我在JavaScript部分标记了一行,我认为这是潜在的罪魁祸首: fallingctx.clear(); 这行没什么特别的。它调用一个函数,该函数依次调用clearRect() 我注意到的“奇怪”的事情是: clear()功能会在我的笔记本电脑(Core 2 Duo)上造成非常明显的FPS下降,但不会在我的桌面(i5 25

我有一幅画布动画,展示了一些奇怪的特征:

我使用的是最新版本的Chrome。我正在使用Chrome内置的FPS监视器(您可以通过转到
about:flags
)来激活它)。 我在JavaScript部分标记了一行,我认为这是潜在的罪魁祸首:

fallingctx.clear();
这行没什么特别的。它调用一个函数,该函数依次调用
clearRect()

我注意到的“奇怪”的事情是:

  • clear()功能会在我的笔记本电脑(Core 2 Duo)上造成非常明显的FPS下降,但不会在我的桌面(i5 2500k)上

  • 仅移除这条线路就足以在我的笔记本电脑上产生每秒60帧的速度。正如预期的那样,画布在每帧之后都不会清除,但仍然会产生稳定的60fps

  • 只有当我的Chrome窗口在较大的一侧时,FPS才会下降!当我缩小窗口并重新加载时,它不会发生!(清除较大的矩形是否更昂贵?)

  • 我试着用全白色JPEG的
    drawImage()
    替换
    clear()
    ,以覆盖画布。JavaScript能够为较小的图像粒子执行200次
    drawImage()。但是,当我为整个画布添加一个
    drawImage
    时,它又会滞后!(确保输出占据整个屏幕以再现结果。)

  • 为什么会发生这一切?如何修复它?

    这实际上取决于硬件,但请考虑调用
    clearRect
    必须做什么!基本上,某些东西必须将一段足够大的内存归零,以处理画布内容。这可能代价高昂。想想在高清分辨率下,RGBA需要多少内存。。。这是超过200万像素的数据,大约8 MB的字节。诚然,现在一般来说,这并不是很多,但是如果有任何带宽或缓存问题与将内存推送到视频卡或每秒执行60次的操作有关。。。好吧,期待问题

    我经常听到的是,只是为了弄清楚图像以前是在哪里画的。看

    我为您做了以下更改

        for (var i=0; i< noOfDrops; ++i)
        {
            fallingctx.clearRect(
              fallingDrops[i].x-1,
              fallingDrops[i].y-1,
              fallingDrops[i].image.width+2,
              fallingDrops[i].image.height+2);
        }
        for (var i=0; i< noOfDrops; ++i)
        {
            fallingDrops[i].y += fallingDrops[i].speed; //Set the falling speed
            fallingctx.drawImage (fallingDrops[i].image, fallingDrops[i].x, fallingDrops[i].y);
        }
    
    并替换了superinit

    function superinit()
    { 
        imgObj.onload = function(){
            flowerfallsetup();
            requestAnimFrame(flowerfall);
        }
        imgObj.onerror = function (){
            alert("could not load image");
        }
        imgObj.src = imgSource;
    }
    
    编辑:由于先前的图像设置,我忘记提及,我确实更改了
    设置中的行:

    有很多方法可以处理图像的异步加载,我只是在本例中选择了一种简单的方法


    编辑:我不得不承认,可能还有更多。它在桌面浏览器上运行良好,但在iPhone上存在剪辑问题。如果我能找出问题的原因,我将尝试发布更新。

    为什么将现有图像快速地显示在画布上要比清除它快?好的,这似乎解决了我的问题。但我发现:我的笔记本电脑清理画布的速度比整个画布快(135fps比80fps),但我的桌面清理整个画布的速度更快!(200fps对170fps)。知道为什么吗?感谢您提供的详细答案:)在我的Nexus S上测试过-它也能更快地清除图像(44Fps vs 31fps)。这是令人困惑的:|@viswa:您的桌面是否比其他两个有更好的加速图形?使用基于CPU的画布,只清除需要的内容可能会更快,而在图像中循环比在更现代的东西上使用加速清除要慢。不过,这只是一个猜测。请注意,
    window.requestAnimationFrame
    实际上不需要在函数中。另外,请不要使用
    new Object()
    ,使用点语法来访问属性而不是括号可能是个好主意。扩展这种东西的原型也可能是不应该做的事情。因此,在高性能设置中,您正在使用访问this.canvas的方法扩展本机对象。。。这可能会引起一些问题。这样更好吗@rynah谢谢你的帮助。可悲的是,没有。没有明显的改善。
    function superinit()
    { 
        imgObj.onload = function(){
            flowerfallsetup();
            requestAnimFrame(flowerfall);
        }
        imgObj.onerror = function (){
            alert("could not load image");
        }
        imgObj.src = imgSource;
    }
    
          fallingDr["image"] = imgObj;