HTML5 Canvas slow on Chrome, but fast on FireFox

前端 未结 2 1290
星月不相逢
星月不相逢 2021-01-03 04:28

I\'m testing Chrome 15.0.874.106m on a dual-core 2.8 GHz Pentium Windows 7 system with 4 GB RAM (and a highly accelerated video card with lots of memory) and I\'m testing F

相关标签:
2条回答
  • 2021-01-03 04:42

    Edit: Issue was not down to the issues raised in this answer. I've also edited the code to be a little more informative.


    BlueMonkMN: From this comparison, it looks to me like Chrome's OnHandleInputEvent implementation is eating up all the time here. What's going on?

    The effect is visible, just not as pronounced even on much smaller/simpler projects. Here's an example that's only about 700K which is a much more manageable thing to test with than the 30+ MB project. If you click and drag you can see is scrolls slightly choppily, but if you release the mouse button it will continue scrolling much more smoothly.

    Looking at your code (below), I can see that your event handler code is calling redraw methods (this is why a lot of the cpu time is spent in event handlers). All it should be doing is updating state. Your redraw should take place in your Game Loop, which would make it much easier to manage as a whole.

    Consider removing the use of instanceof in MapLayer.prototype.draw and instead finding another way to get the frames. instanceof is a costly operation, and there is often a much more elegant approach that does not require that. Some of those Tile/Map objects should be accessed through function calls rather than array indexes, then you can have more freedom on the type of object returned, frames can be updates, and that whole MapLayer.prototype.draw method can be a lot cleaner.

    Also, why is there a loop rendering every frame if typeof frames !== 'number'? When debugging it tends to only be rendering two frames, but it stood out.

    Again, you really ought to be rendering in the game loop, nothing major should ever take place in event handlers. And to make it easier, try constructing a benchmark for a single frame on jsperf.com, that way you will know how much time it spent in that function. And you can narrow down on the bottleneck by benchmarking different aspects of your code.

    // Section of our code
    function beginDrag(e) {
       dragX = e.clientX;
       dragY = e.clientY;
       var srcEl = e.srcElement ? e.srcElement : e.target;
       srcEl.onmousemove = processDrag;
       return false;
    }
    // **Note** called on mouseout, not mouseup
    function endDrag(e) {
       var srcEl = e.srcElement ? e.srcElement : e.target;
       srcEl.onmousemove = null;
    }
    function processDrag(e) {
       e = e || window.event;
       drag(e.clientX, e.clientY);
       return false;
    }
    function drag(newX, newY) {
       currentMap.scroll(currentMap.scrollX + newX - dragX, currentMap.scrollY + newY - dragY);
       dragX = newX;
       dragY = newY;
       // --- this should not be executed during an event handler, draw takes place in game loop.
       currentMap.draw(gameViewContext);
    }
    
    0 讨论(0)
  • 2021-01-03 05:00

    The bug I reported (https://code.google.com/p/chromium/issues/detail?id=103148) has since been remarked on as "unable to reproduce" if I read correctly, so I'm going to run on the assumption that this was a bug in Chrome and has been fixed (intentionally or not) by other updates. In any case, I don't have the issue any more myself.

    0 讨论(0)
提交回复
热议问题