多个画布会导致浏览器在“ requestAnimationFrame”中重新绘制

时间:2019-06-28 13:54:09

标签: javascript html html5-canvas repaint

我正在研究其中一个渲染应用程序中的绘画问题。我创建了问题的简单版本,以了解为什么使用两个画布在每个框架上进行浏览器重画。该示例仅使用两个画布和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: Massive Repaint

如您所见,在每个requestAnimationFrame之后,将重新绘制一次。在这里,它大约为0.4毫秒,这是“可以的”,但是在实际应用中,它可以为10毫秒左右,这显然是不可行的,因为一个框架的预算为16毫秒。

现在假设我将.second CSS类的宽度更改为:

.second {
  position: absolute;
  height: 50%;
  width: 80%;
}

该页面将按预期呈现,而无需进行过多的重新绘制:

Profiler: No Repaint

显然,我不知道有关浏览器重绘机制的某些信息。如果有人对这里发生的事情有暗示,那么与我分享一下真是太棒了。

0 个答案:

没有答案