DOM的重排(回流)和重绘(页面渲染过程、重排、回流和重绘概念及其触发操作、浏览器对重排和重绘的优化策略、其它优化方法(基于HTML、CSS方面优化、基于JavaScript方面优化))

本文介绍了网页渲染的过程,包括重排(回流)、重绘的概念及触发条件,并详细探讨了浏览器如何优化这些操作来提高性能。此外,还提供了一系列实用的HTML、CSS和JavaScript优化策略。

目录

页面的渲染过程

重排(回流)

触发操作

重绘

 触发操作

重排(回流)和重绘关系

浏览器本身优化策略

优化方法

HTML、CSS方面优化

Javascript方面优化


页面的渲染过程

(1)Javascript:通过JS实现动画效果或者操作DOM实现交互

(2)Style:计算样式,如果样式有改变将重新计算,并返回给DOM

(3)Layout:根据DOM的样式,重新布局(重排、回流)

(4)Paint:在多个渲染层上,对新的布局重新渲染(重绘)

(5)Composite:将绘制好的多个渲染层合并,显示到页面上

在页面生成时,至少进行一次布局和渲染,在后面用户不断地操作过程中会进行多次的重排和重绘,以至于影响页面的性能。
 

重排(回流)

浏览器下载完页面中的所有组件(HTML、JavaScript、CSS、图片)之后会解析生成两个内部数据结构(DOM 树和渲染树),DOM 树表示页面结构,渲染树表示 DOM 节点如何显示。重排是 DOM 元素的几何属性变化,DOM 树的结构变化,渲染树需要重新计算。

触发操作

  1. 页面渲染初始化时;(这个无法避免)
  2. 浏览器窗口改变尺寸;
  3. 元素尺寸改变时;
  4. 元素位置改变时;
  5.  元素内容改变时;
  6. 添加或删除可见的 DOM 元素时。
  7. 当获取一些属性值时,浏览器为了保证获取到正确的值也会引起重排。如元素的offsetTop,offsetLeft,offsetHeight,offsetWidth,scrollTop,scrollWidth,scrollLeft,scrollHeight等

重绘

重绘是一个元素外观的改变所触发的浏览器行为(元素的样式发生了变化,而大小和尺寸没有发生改变),例如改变 visibility、outline、背景色等属性。浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。由于浏览器的流布局,对渲染树的计算通常只需要遍历一次就可以完成。但 table 及其内部元素除外,它可能需要多次计算才能确定好其在渲染树中节点的属性值,比同等元素要多花两倍时间,这就是我们尽量避免使用 table 布局页面的原因之一。

 触发操作

只修改元素的样式,而未修改元素的大小和位置,引起重绘。

重排(回流)和重绘关系

 重绘不会引起重排,但重排一定会引起重绘,一个元素的重排通常会带来一系列的反应,甚至触发整个文档的重排和重绘,性能代价是高昂的。

浏览器本身优化策略

 浏览器会维护一个队列,将所有引起重排和重绘的操作都放在这个队列里,当操作达到一定的数量或者时间间隔时,浏览器会进行一个批处理。这样可以让多次的重排重绘,变成一次。但是有时候一些特殊的style属性会使这种优化失效,例如offsetTop,scrollTop,clientTop等属性,这些属性都是要实时返回给用户的几何属性或者布局属性,因此浏览器需要立即执行,触发重排返回正确的值。
 

优化方法

HTML、CSS方面优化

  1. 将多次改变样式属性的操作合并成一次操作,减少 DOM 访问,可以通过切换类名的方法实现。
  2. 如果要批量添加 DOM,可以先让元素脱离文档流,操作完后再带入文档流,这样只会触发一次重排。(fragment 元素的应用)
  3. 将需要多次重排的元素,position 属性设为 absolute 或 fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。
  4. 由于 display 属性为 none 的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的重排。如果要对一个元素进行复杂的操作时,可以先隐藏它,操作完成后再显示。这样只在隐藏和显示时触发两次重排。
  5. 在内存中多次操作节点,完成后再添加到文档中去。例如要异步获取表格数据,渲染到页面。可以先取得数据后在内存中构建整个表格的 html 片段再一次性添加到文档中,而不是循环添加每一行。
  6. 将原始元素拷贝到一个独立节点中去,然后操作这个独立的节点,覆盖原始元素。


Javascript方面优化

JavaScript代码优化(减少作用域链上的查找次数(函数尾调用、尾递归、全局查找)、使用原生方法、减少语句、减少页面重绘、使用事件委托)_AIWWY的博客-优快云博客

 补充:多次使用例如offsetTop,scrollTop,clientTop等属性(这些属性都是要实时返回给用户的几何属性或者布局属性)时,进行申明变量缓存。

<think>嗯,用户让我详细解释浏览器渲染机制,特别是重排过程。首先,我需要确保自己对这一块的理解是正确的。记得浏览器渲染页面有几个主要步骤,比如解析HTMLCSS,构建DOMCSSOM树,然后合并成渲染树,再布局制。不过具体每个步骤的细节可能需要再回忆一下。 重排这两个概念经常被提到,但有时候容易混淆。重排应该涉及到布局的改变,也就是几何属性的变化,比如宽度、高度或者位置变化,这样浏览器需要新计算元素的位置大小,这个过程比较耗费性能。而则是当元素的外观发生变化,但不影响布局时发生的,比如颜色、背景色的改变,这时候不需要新布局,直接制即可。不过具体哪些属性会触发重排,哪些触发,可能需要进一步确认。 另外,用户可能想知道如何优化,减少重排的次数。比如合并多次DOM操作,使用文档碎片(DocumentFragment),或者使用CSS的transform属性来做动画,因为这些不会触发重排。可能还需要提到现代浏览器渲染队列机制,它们会批量处理重排,但某些操作会强制刷新队列,比如获取布局信息(offsetTop等),这时候需要注意避免在修改样式后立即读取这些属性。 还有,CSS的某些属性如transformopacity可以利用GPU加速,这样可以在合成层进行处理,避免重排,提升性能。这也是优化的一部分。另外,隐藏元素(display:none)进行操作后再显示,可以避免中间状态的重排,也是一个技巧。 不过,我需要确保这些信息是准确的,可能需要回顾一下浏览器渲染流程的具体步骤,以及各个阶段触发的条件。比如,在渲染树构建完成后,布局阶段计算每个节点的位置大小,制阶段填充像素。当元素变化影响到布局时,会触发重排,进而导致后续元素也需要新布局,这称为“回流”。而如果只是不影响布局的变化,比如颜色,就只需要。 用户可能在实际开发中遇到性能问题,比如频繁操作DOM导致页面卡顿,这时候了解重排的机制就能帮助优化代码。比如使用class一次性修改多个样式,而不是逐个修改,或者将元素脱离文档流(比如使用绝对定位),这样它的变化不会影响其他元素,减少重排的范围。 总结起来,我需要分步骤解释渲染流程,明确重排的定义,触发条件,以及优化方法。可能还需要举一些例子,比如修改width会触发重排,修改color触发,使用transform则不会触发重排。同时,强调两者对性能的影响,尤其是重排的开销更大,应该尽量减少。</think>浏览器渲染机制是通过多阶段流水线将HTML/CSS代码转换为可视化页面,其中(Repaint)重排(Reflow)是影响性能最关键的环节。以下是完整技术解析: $$ \begin{aligned} &\text{关键渲染路径} \\ &1. \text{解析HTML构建DOM树} \rightarrow \text{Parse HTML} \\ &2. \text{解析CSS构建CSSOM树} \rightarrow \text{Parse CSS} \\ &3. \text{合并成渲染(Render Tree)} \rightarrow \text{Attachment} \\ &4. \text{布局计算(Layout)} \rightarrow \text{Reflow阶段} \\ &5. \text{(Painting)} \rightarrow \text{Repaint阶段} \\ &6. \text{合成显示(Composite)} \rightarrow \text{GPU加速} \end{aligned} $$ **重排(Reflow)触发条件**: - 几何属性变更:$width$, $height$, $padding$, $margin$等 - 布局相关操作:添加/删除DOM节点、修改$display:none$ - 获取布局信息:$offsetTop$, $scrollHeight$等强制同步布局 **(Repaint)触发条件**: - 非几何样式变更:$color$, $background$, $visibility$等 - 不改变元素在文档流中的位置 **性能对比**: $$ \text{重排成本} \gg \text{成本} \gg \text{合成层操作} $$ **优化策略**: 1. 使用`documentFragment`批量DOM操作 2. 避免逐行读取布局属性(强制同步布局) 3. CSS优化: ```css .box { transform: translateZ(0); /* 启用GPU加速层 */ will-change: transform; /* 预声明变化类型 */ } ``` 4. 使用`requestAnimationFrame`集中样式变更 5. 复杂动画使用`position: absolute`脱离文档流 **现代浏览器优化机制**: - 渲染队列:浏览器会合并连续的重排请求 - 增量重排:仅新计算受影响区域(Dirty Rect) - 合成层:通过`transform``opacity`实现独立光栅化 **调试工具**: - Chrome DevTools > Performance面板可捕获详细渲染过程 - Rendering面板开启`Paint flashing`高亮区域 通过理解这些机制,开发者可以编写出性能提升$3\text{x}$以上的Web应用,特别是在处理动态内容更新时效果显著。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值