我正在研究其中一个渲染应用程序中的绘画问题。我创建了问题的简单版本,以了解为什么使用两个画布在每个框架上进行浏览器重画。该示例仅使用两个画布和2D上下文(此示例没有WebGL)。
我有一个HTML页面,设置如下:
+----------------------------+
| |
| CANVAS 1 |
| |
| |
+----------------------------+
| |
| CANVAS 2 |
|__________|
我为此示例分析的代码如下:
window.onload = init;
const image = document.getElementById('source');
const viewer = { canvas: null, context: null };
const thumbnail = { canvas: null, context: null };
function init() {
viewer.canvas = document.getElementById('viewer');
viewer.canvas.width = viewer.canvas.clientWidth;
viewer.canvas.height = viewer.canvas.clientHeight;
viewer.context = viewer.canvas.getContext('2d', { alpha: false });
thumbnail.canvas = document.getElementById('thumbnail');
thumbnail.canvas.width = thumbnail.canvas.clientWidth;
thumbnail.canvas.height = thumbnail.canvas.clientHeight;
thumbnail.context = thumbnail.canvas.getContext('2d', { alpha: false });
animate();
}
function animate() {
viewer.context.clearRect(0, 0, viewer.canvas.width, viewer.canvas.height);
viewer.context.drawImage(image, 0, 0, viewer.canvas.width, viewer.canvas.height);
thumbnail.context.clearRect(0, 0, thumbnail.canvas.width, thumbnail.canvas.height);
thumbnail.context.drawImage(image, 0, 0, thumbnail.canvas.width, thumbnail.canvas.height);
window.requestAnimationFrame(animate);
}
.body {
position: absolute;
width: 100%;
height: 100%;
margin: 0px;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: initial;
overflow: hidden;
}
.page {
width: 100%;
height: 100%;
}
.container {
position: relative;
height: 50%;
width: 100%;
}
.second {
position: absolute;
height: 50%;
width: 80%;
}
canvas {
width: 100%;
height: 100%;
}
<div class="page">
<img
style="display: none;"
id="source"
src="https://mdn.mozillademos.org/files/5397/rhino.jpg"
width="300"
height="227"
>
<div class="container">
<canvas id="viewer"></canvas>
</div>
<div class="container second">
<canvas id="thumbnail"></canvas>
</div>
</div>
这是Chrome分析器输出的内容:
如您所见,在每个requestAnimationFrame
之后,将重新绘制一次。在这里,它大约为0.4毫秒,这是“可以的”,但是在实际应用中,它可以为10毫秒左右,这显然是不可行的,因为一个框架的预算为16毫秒。
现在假设我将.second
CSS类的宽度更改为:
.second {
position: absolute;
height: 50%;
width: 80%;
}
该页面将按预期呈现,而无需进行过多的重新绘制:
显然,我不知道有关浏览器重绘机制的某些信息。如果有人对这里发生的事情有暗示,那么与我分享一下真是太棒了。