Я исследую проблемы рисования в одном из моих приложений рендеринга.Я создал простую версию своей проблемы, чтобы понять, почему с двумя холстами перерисовка браузера происходит на каждом кадре.В этом примере используются только два холста и 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 Profiler:
Как видите, после каждого requestAnimationFrame
происходит перекраска.Здесь она составляет около 0,4 мс, что «хорошо», но в реальном приложении она может составлять около 10 мс, что, очевидно, совсем не нормально, поскольку бюджет кадра составляет 16 мс.
Теперь скажемЯ изменяю ширину .second
CSS-класса на:
.second {
position: absolute;
height: 50%;
width: 80%;
}
Страница будет отображаться, как и ожидалось, без чрезмерной перерисовки:
В механизме перерисовки браузера есть что-то, о чем я не знаю.Если у кого-то есть подсказка о том, что здесь происходит, было бы здорово поделиться этим со мной.