我一直在尝试在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/。该代码执行以下操作:
不幸的是,我正在重新渲染画布内容的时候看到可怕的janks。我似乎无法解释的是Chrome开发者工具时间表的样子:
丢帧似乎是由于requestAnimationFrame
未在帧开始时调用,而是在理想的16ms周期结束时调用。如果在前一帧完成渲染之后立即开始回调,则代码很可能会及时完成。
渲染到离屏画布(https://jsfiddle.net/fkfnjrc2/6/),然后将完整的图像复制到屏幕画布有一点帮助,但是jank仍然存在完全相同的特征(延迟执行rAF回调)。
该代码有什么问题?或者我的浏览器/机器可能有问题?我在Windows 10和Mac OS上的Chrome(49.0.2623.112)上看到了相同的行为。