我假设 HTML5 中的所有这些硬件加速动画实际上并未渲染在视口之外运行的动画。我希望能够检测到这种情况是否正在发生。
我尝试webkitCSSMatrix
在一个每秒上下移动 100px 的对象上循环使用,以尝试确定每个刻度移动了多少像素,但是如果我将动画移出视图,则没有区别。
有任何想法吗?
我假设 HTML5 中的所有这些硬件加速动画实际上并未渲染在视口之外运行的动画。我希望能够检测到这种情况是否正在发生。
我尝试webkitCSSMatrix
在一个每秒上下移动 100px 的对象上循环使用,以尝试确定每个刻度移动了多少像素,但是如果我将动画移出视图,则没有区别。
有任何想法吗?
您可以使用单独的计时器测试来查看伪经验方面在外部与内部绘制的对象之间的差异(计时器实际上并不能证明任何事情,但会给您一个强大的indisium)。
但是,了解画布的工作方式也可以为您提供可靠的指导。例如,画布是一个简单的位图,没有任何内部管理(除了屏幕刷新)。这意味着您实际上不可能在其范围之外写入任何内容,因为这会破坏内存。换句话说,剪裁确实是出于这个非常基本的原因。
对于计时器测试,您可以运行一个简单的测试,在该测试中在边界内绘制一些东西,然后在边界外绘制相同的偏移量:
更新:似乎我误解了这个问题是在画布位图之外而不是在一般视口之外。
因此,无论是否是画布,关于外部视口的一个小更新-
描述浏览器更新比仅仅描述画布要复杂一些,但原则上:屏幕上不可见的所有内容都被剪裁(未绘制)。似乎很明显,而且有点像,但这并不意味着其他地方没有任何更新。
浏览器可能会或可能不会保留要绘制到屏幕上的元素的内部位图(如果部分在视图中,则剪辑,如果在视图外,则根本不剪辑)。
主要区别在于,如果需要,浏览器可以(取决于实现)更新这个内部位图,即使它不可见,即。受此元素的位置、尺寸和堆栈位置影响的 DOM 重新流动。
因此,您可能会在某些浏览器中看到性能下降。浏览器还可以选择仅在可见时更新位图内容,而仅在不可见时调整大小。
不幸的是,没有准确的方法来衡量这种情况是否发生,因为它取决于许多因素(固定/绝对元素与非固定/绝对元素、什么内容、浏览器实现、硬件加速与否等等)。
画布元素很简单,因此很容易预测,但是如果您在画布位于视口之外时在画布上绘制一些东西,它将被绘制到其位图并在画布再次在视图中时显示。但是,尝试调整窗口大小,画布的内容会消失(在某些浏览器中),您需要重新绘制。这意味着与其他元素相比,使用画布的过程中至少少了一层。
我希望这是有道理的——我很抱歉,我有点没有准备好做这个解释,因为我刚刚意识到我误解了这个问题。
更新结束
在这个测试中,我们绘制了 10,000 个填充矩形,在里面的一个按钮处,在里面的另一个按钮处。这不是一个科学准确的测试,但它清楚地显示了一个区别,因为当绘图超出它所做的一切是检查边界并且不更新位图数组中的任何内容 -
function draw(x) {
console.time('timer');
var cnt = 10000, w = ez.width, h = ez.height;
while(cnt--) {
ctx.fillRect(x, 0, w, h);
}
console.timeEnd('timer');
}
inside.addEventListener('click', function(){draw(0)}, false);
outside.addEventListener('click', function(){draw(ez.width)}, false);
在我的蜗牛电脑上使用控制台计时器和 Chrome 的结果是:
定时器:3156.000ms
定时器:112.000ms
这是(内部:外部)3156:112 的比率 - 或者 - 在实际绘制某些东西时花费了 28 倍的时间。这表明浏览器只花时间检查边界,但如果超出边界,实际上不会移动内存中的任何数据。
另一种方法类似于已经回答的方法,使用内置工具。但是为此使用探查器:
转到控制台并选择配置文件和 CPU 配置文件:
现在您可以比较两个配置文件 - 对于内部图纸,我得到了这个结果:
在这里您可以看到它使用大约 9.92% 来绘制填充的矩形(未针对空闲时间进行调整)。
在第二个配置文件中,我得到了这个:
这里只有 1.24% 用于“绘制”。
这里的比率是 9.92:1.24 或 8 倍。在这两种情况下,您都可以看到当某些内容更新到内存(位图缓冲区)而不是更新时,性能存在巨大差异。
那么离屏画布呢?这些情况也是如此,因为需要在屏幕外画布的缓冲区中更新某些内容。它保存的“唯一”内容是对浏览器主缓冲区的更新,可能会或可能不会优化。
如果您使用 Chrome DevTools 可以使用Timeline面板查看页面性能。
另一个选项是启用 Web 检查器中的“显示绘制矩形”选项。这将在重新绘制的区域周围绘制一个正方形。Web Inspector > Settings > General > Rendering : 显示绘制矩形
Paul Irish 有一篇非常好的博客文章,为什么用 Translate() 移动元素比 Pos:abs Top/left 更好。