如何判断 HTML5 Canvas 性能缓慢的原因是什么?
我如何判断画布的缓慢性能是由绘图本身引起的,还是由计算应该绘制什么以及在哪里绘制的底层逻辑引起的?
我的问题的第二部分是:如何计算画布 fps?这就是我的做法,对我来说似乎很合乎逻辑,但我也可能是完全错误的。这是正确的做法吗?
var fps = 0;
setInterval(draw, 1000/30);
setInterval(checkFps, 1000);
function draw() {
//...
fps++;
}
function checkFps() {
$("#fps").html(fps);
fps = 0;
}
编辑: 根据内森的评论,我将上面的内容替换为以下内容:
var lastTimeStamp = new Date().getTime();
function draw() {
//...
var now = new Date().getTime();
$("#fps").html(Math.floor(1000/(now - lastTimeStamp)));
lastTimeStamp = now;
}
那么这个怎么样?您还可以仅计算自上次更新以来以毫秒为单位的差异,也可以通过这种方式看到性能差异。顺便说一句,我还对两者进行了并排比较,它们通常几乎一起移动(最多相差 2),但是,当性能非常低时,后者有更大的峰值。
How can I tell if the canvas's slow performance is caused by the drawing itself, or the underlying logic that calculates what should be drawn and where?
The second part of my question is: how to calculate canvas fps? Here's how I did it, seems logical to me, but I can be absolutely wrong too. Is this the right way to do it?
var fps = 0;
setInterval(draw, 1000/30);
setInterval(checkFps, 1000);
function draw() {
//...
fps++;
}
function checkFps() {
$("#fps").html(fps);
fps = 0;
}
Edit:
I replaced the above with the following, according to Nathan's comments:
var lastTimeStamp = new Date().getTime();
function draw() {
//...
var now = new Date().getTime();
$("#fps").html(Math.floor(1000/(now - lastTimeStamp)));
lastTimeStamp = now;
}
So how's this one? You could also calculate only the difference in ms since the last update, performance differences can be seen that way too. By the way, I also did a side-by-side comparison of the two, and they usually moved pretty much together (a difference of 2 at most), however, the latter one had bigger spikes, when performance was extraordinarily low.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你的 FPS 代码绝对是错误的
没有人保证这个函数会每秒被调用一次(它可能超过 1000 毫秒,或更短 - 但可能更多),所以
是错误的(如果当时 fps 是 32,那么你可能会在 1.5 秒内有 32 帧(极端情况))
更好的是查看自上次更新以来的实时通过量并计算实时通过/帧(我确信 javascript 具有获取时间的功能,但我不确定如果它足够准确=毫秒或更好)
顺便说一句,fps不是一个好名字,它包含帧数(自上次更新以来),而不是每秒的帧数,因此帧将是一个更好的名称。
同样的方式
是错误的,因为你想要达到 30 的 FPS,但由于 setInterval 不是很准确(并且可能会等待比你说的更长的时间,即使 CPU 能够,你最终也会得到较低的 FPS处理负载)
Your FPS code is definitely wrong
No-one assures this function will be called exactly every second (it could be more than 1000ms, or less - but probably more), so
is wrong (if fps is 32 at that moment it is possible that you have 32 frames in 1.5s (extreme case))
beter is to see what was the real time passes since the last update and calculate the realtimepassed / frames (I'm sure javascript has function to get the time, but I'm not sure if it will be accurate enough = ms or better)
fps is btw not a good name, it contains the number of frames (since last update), not the number of frames per second, so frames would be a better name.
In the same way
is wrong, since you want to achieve a FPS of 30, but since the setInterval is not very accurate (and is probably going to wait longer than you say, you will end up with lower FPS even if the CPU is able to handle the load)
Webkit 和 Firebug 都提供分析工具来查看 JavaScript 代码中 CPU 周期的消耗情况。我建议从那里开始。
对于FPS计算,我认为你的代码不会工作,但我没有任何好的建议:(
原因是:大多数(全部?)浏览器使用专用线程来运行javascript,并使用不同的线程来运行UI 更新。如果 Javascript 线程繁忙,则不会触发 UI 线程。
因此,您可以运行一些 javascript 循环代码,连续“更新”UI 1000 次(例如,设置某些文本的颜色)。 ) - 但除非你添加一个 setTimeout 来允许 UI 线程绘制更改,否则在 1000 次迭代完成之前你不会看到任何更改,
也就是说,我不知道你是否可以在 FPS 计数器上自信地增加。 Draw() 例程结束了。当然,你的 JavaScript 函数已经完成了,但是浏览器真的绘制了吗?
Webkit and Firebug both provide profiling tools to see where CPU cycles are being spent in your javascript code. I'd recommend starting there.
For the FPS calculation, I don't think your code is going to work, but I don't have any good recommendation :(
Reason being: Most (all?) browsers use a dedicated thread for running javascript and a different thread for running UI updates. If the Javascript thread is busy, the UI thread won't be triggered.
So, you can run some javascript looping code that'll "update" the UI 1000 times in succession (for instance, setting the color of some text) - but unless you add a setTimeout to allow the UI thread to paint the change, you won't see any changes until the 1000 iterations are finished.
That said, I don't know if you can assertively increment your fps counter at the end of the draw() routine. Sure, your javascript function has finished, but did the browser actually draw?
检查您是否不使用某些innerHTML方法来调试您的项目。这会以你无法想象的方式减慢你的项目,特别是如果你做了一些像这样的串联:innerHTML += newDebugValues;
或者像 desau 所说,使用 firebug 或 webkit 内部调试器分析你的 cpu 使用情况。
Check if you dont use some innerHTML method to debug your project. This can slow your project in a way you can't imagine, especially if you do some concatenation like this innerHTML += newDebugValues;
Or like desau said, profile your cpu usage with firebug or webkit inner debugger.