我一直在尝试在HTML5画布上实现无卡顿渲染复杂场景的效果。这个想法是将渲染分成多个批次,每个批次最多花费12毫秒的时间,这样同时运行的动画(非常廉价的执行)就不会被中断。
在概念上,批量渲染是这样实现的:
function draw(ctx) {
var deadline = window.performance.now() + 12; // inaccurate, but enough for the example
var i = 0;
requestAnimationFrame(function drawWithDeadline() {
for (; i < itemsToRender.length; i++) {
if (window.performance.now() >= deadline) {
requestAnimationFrame(drawWithDeadline);
return;
}
var item = itemsToDraw[i];
// Draw item
}
});
}
完整的代码在这个JSFiddle链接中:https://jsfiddle.net/fkfnjrc2/5/。该代码执行以下操作:
- 在每一帧上,修改画布的CSS变换属性(这是一个同时运行的快速执行动画示例)。
- 偶尔,按照上面所示的批处理方式启动重新渲染画布。
requestAnimationFrame
没有在帧开始时立即调用,而是在理想的16ms周期朝着结束方向调用。如果回调函数在上一帧完成渲染后立即开始,则代码很可能会及时完成。将图像渲染到离屏画布中(https://jsfiddle.net/fkfnjrc2/6/),然后将完整的图像复制到屏幕画布中可以稍微帮助一下,但是仍然存在与之前完全相同的卡顿(rAF回调延迟执行)。
那段代码有什么问题?或者我的浏览器/机器有问题吗?我在Windows 10和Mac OS上的Chrome(49.0.2623.112)上看到了相同的行为。