问题
I've been using the createjs Easeljs library for a few canvas game projects. In all I am impressed, but I have recently encountered a problem within chrome that is holding me back.
When the left mouse button is down and the mouse moves the FPS is dropped to 30 on chrome (as reported by the developer tools). This is painfully obvious against the 60FPS the game normally runs at.
To try to understand this I have stripped down a bare canvas and ticker, and the problem persists. So I am lost. The problem can be reproduced by me with this code:
<html>
<head>
<script src="./javascript/easeljs-0.8.1.combined.js"></script>
<script>
function init() {
canvas = document.getElementById("gameCanvas");
createjs.Ticker.setFPS(60);
createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNC;
stage = new createjs.Stage(canvas);
createjs.Ticker.on("tick", tick);
};
function tick(evt)
{
stage.update();
}
</script>
</head>
<body onLoad="init();" bgcolor="#ffffff">
<canvas id="gameCanvas" width="1136px" height="640px" style="border: thin black solid; margin: 0 auto;"></canvas>
</body>
</html>
I am aware of the question: Html Canvas lag when Left Mouse is down and moving on Chrome but I can't see how it can help in this case.
Does anyone have any ideas or resources to help with this?
EDIT:
Apologies, I have found one work-around by setting the ticker to
createjs.Ticker.timingMode = createjs.Ticker.RAF;
This solves these problems and the intermitted frame drops I was getting (but didn't mention)
Regardless, can anyone shed any light on why this is happening, and why on earth I would use a synced Ticker if it results in this?
回答1:
RAF provides a non-deterministic framerate (ie. you are not guaranteed any particular framerate), which means the browser is free to throttle or increase the fps arbitrarily in response to any number of things. It seems like Chrome may be firing extra RAF events when the mouse is down in order to repaint more frequently and offer smoother mouse interactions.
RAF_SYNC
works by trying to line up a specified framerate with the arbitrary framerate. It has some tolerances to allow it work when the framerate isn't lining up well, but this works a lot better when the specified framerate is significantly lower than the real-world RAF framerate (ex. targeting 20 or 30 fps).
From the docs:
Variance is usually lowest for framerates that are a divisor of the RAF frequency. This is usually 60, so framerates of 10, 12, 15, 20, and 30 work well.
In this case, because your target fps is quite high (basically the maximum RAF is likely to go), it doesn't have much wiggle room. When Chrome gets too far above 60fps, RAF_SYNC starts having trouble lining up the frames to the framerate its trying to hit. Not enough time has passed between the previous frame and the current one, so it waits an extra frame. The result is that the framerate drops to a little over half your specified rate. At 20 or 30 fps, you likely wouldn't notice this at all, because it could align fairly well.
For example, say Chrome jumps to 80fps, and you're targeting 60fps in RAF_SYNC mode:
- Chrome fires RAF event.
- Ticker looks at elapsed time since last tick, sees it's only 12ms, decides that's not close enough to its target of 16.67ms, and waits for the next RAF event
- Chrome fires another RAF event.
- Ticker looks and sees more than 16.67ms have passed since last tick, and immediately fires tick, but at this point 25ms have elapsed.
- Repeat. You're now running at ~40fps instead of 60fps, even though real framerate is at ~80fps.
I hope that makes sense.
来源:https://stackoverflow.com/questions/33024854/mouse-down-and-moving-drops-chrome-canvas-to-30fps-using-createjs