繁体   English   中英

浏览器究竟何时重绘和重排?

[英]When exactly does the browser repaint and reflow?

我试图更好地理解在浏览器中发生 DOM 操作时会发生什么。 我找不到很多资源的事情是浏览器何时执行重绘和重排(有很多文献说明重绘或重排是什么,但几乎没有关于何时发生)。

非常具体地说,我想知道这样的代码:

function clickHandler() {
    domElement1.textContent = 'Hello';
    domElement2.textContent = 'World';
}

假设有两个 DOM 元素存储在变量domElement1domElement2中。 clickHandler附加到一个按钮,并且在单击它时应该更新两个 DOM 元素的内容。

现在的问题是:这是否可能导致两次重绘? 即浏览器仅更新domElement1 ,显示屏幕上的更改导致重绘/回流/等,然后更新domElement2导致另一个重绘/回流/等? 或者是否保证按钮的事件处理程序将在实际 DOM 中发生任何更改之前完全执行?

我的猜测是浏览器试图保持每秒 60 帧,理论上这两种变化可能发生在两个不同的帧中。 那是对的吗?

浏览器重排和浏览器重绘是两个不同但相关的想法。


回流本质上是计算给定元素的偏移量和尺寸,以了解什么来自哪里以及占用多少空间等等。

重绘是回流后的下一个阶段。 这是在回流阶段进行的计算实际用于在屏幕上绘制像素的时候。 这个过程有时也称为光栅化


第一件事是:重绘仅在主线程空闲时发生,即当没有事件侦听器、没有回调时,只是当前没有任何内容等待执行。 而且,根据我的直觉,重绘仅在先前触发重排时才会发生。

与此相反,每个 DOM 突变都可能触发重排,具体取决于底层代码。

正如您可以推理的那样,对于任何浏览器来说,最天真的方法是在每个DOM 突变后触发重排(例如,您在上面共享的domElement1.textContent = 'Hello';语句)。 但正如您可能同意的那样,这将是非常低效的。

如果一行中有一大堆这样的语句怎么办? 显然,在这种情况下,浏览器最好在整个语句块的最后只进行一次重排,从而避免浪费计算资源。

现在要记住一件事。 如您所知,浏览器引擎,尤其是 JavaScript,在过去几年中变得极其复杂、精密和智能。 如今,他们可以对代码的精确要求做出极其智能的猜测,然后最终对其进行多种优化,以便以最快的速度运行它。

这些优化包括在不需要时保持回流算法的执行。 每个浏览器究竟如何做到这一点超出了这个答案的 scope 并且显然取决于实现。 Chrome 可能依赖于一种方法,Firefox 依赖于另一种方法,Safari 依赖于另一种方法,依此类推。

深入挖掘每个人的代码库并找到它的确切工作方式并没有任何意义。

但是,如今所有浏览器之间都有一个共同点,那就是它们试图做最少的不必要的工作。 这就是现代 JavaScript 成功的原因之一 — 强大的引擎就在其背后。

因此,要结束这个答案,我会说不,以下代码几乎不可能触发两次重排:

function clickHandler() {
    domElement1.textContent = 'Hello';
    domElement2.textContent = 'World';
    // Reflow should happen at the end of this function.
}

但是,以下语句可能会触发它两次,因为第二个语句想知道一些事情(即domElement1与视口上边缘的距离),只有在浏览器运行了回流算法后才能获得:

function clickHandler() {
    domElement1.textContent = 'Hello';
    console.log(dom1Element.getBoundingClientRect().top); // Should trigger reflow.
    domElement2.textContent = 'World';
    // Reflow should happen at the end of this function.
}

注意上面句子中“几乎”“可能”的用法。 我用它们来强调我不是 100% 确定的事实。 我所说的在每一个浏览器上确实发生的概率超过 50%,但概率仍然不是 100%。 正如我之前所说,发动机的工作方式不同,我不能盲目地告诉你一些我自己从未检查过的事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM