前端工程优化之重绘、回流和图层的概念

重绘、回流和图层

在前面的学习中,我们知道浏览器在渲染一个页面的过程是这样的:

  1. 解析HTML构建DOM树

    渲染引擎使用HTML解析器(调用XML解析器)解析HTML(XML)文档,将各个HTML(XML)元素逐个转化成DOM节点,从而生成DOM树。

    接着渲染引擎使用CSS解析器解析外部CSS文件及style标签中的样式信息,构建出CSSOM 树。

  2. 构建渲染树

    渲染引擎使用上一步CSS解析器解析得到的样式规则,将其附着到DOM树上,从而构成渲染树,其实就是讲DOM树和CSSOM树合并成渲染树。

  3. 布局渲染树

    渲染树构建完毕之后,进入布局阶段,也就是为每个节点分配一个应出现在屏幕上的确切坐标。

  4. 绘制render树

    渲染引擎将遍历渲染树,并调用显示后端将每个节点绘制出来。

在这里插入图片描述

在整个页面被渲染的过程中,最后两个步骤是: layout(布局) 和 paint (绘制)。

重绘

其实就是触发浏览器的 paint 的过程。

只触发重绘的样式:

样式属性名样式属性名样式属性名
colorbackgroundoutline-color
border-stylebackground-imageoutline
border-radiusbackground-positionoutline-style
visibilitybackground-repeatoutline-width
text-decorationbackground-sizebox-shadow
回流

其实不仅仅是触发了 paint 的过程还触发 layout 的过程,所以回流必定触发重绘

能触发回流的样式:

样式属性名样式属性名样式属性名
widthtoptext-align
heightbottomoverflow-y
paddingleftfont-weight
marginrightoverflow
displaypositionfont-family
border-widthfloatline-height
borderclearvertival-align
min-heightfont-sizewhite-space

能触发回流的JS操作

JS属性或者方法JS属性或者方法JS属性或者方法JS属性或者方法JS属性或者方法
offsetTopscrollTopclientTopwidthgetComputedStyle()
offsetLeftscrollLeftclientLeftheightIE的:currentStyle
offsetWidthscrollWidthclientWidthgetBoundingClientRect()
offsetHeightscrollHeightclientHeight

另外,只要是获取元素位置相关的操作,都会触发回流。

可以避免重绘和回流的方式是启用CSS的硬件加速,硬件加速其实就是GPU加速,可以触发硬件加速的css属性有:

样式属性名样式属性名样式属性名样式属性名
transformopacityfiltersWill-change
图层(Layer)

浏览器的渲染策略是分层的,当遇到会增加图层的标签的时候,浏览器会生成一个新的图层(比如:div、canvas等),之后该元素内的重绘和回流的过程只存在于该图层中。之后再进行图层的合并,这样重绘和回流的效率就会提高,但是会增加一个图层的合并过程。

优化思路

明白了重绘和回流等知识,我们的优化思路其实就有了,其实就是:减少重绘和回流,因此我们以下几个地方入手:

  1. 在布局上可以使用:translate替代top/left…、opacity替代visibility
  2. 操作DOM的时候
    • 不要一条一条地修改 DOM 的样式,预先定义好 class,然后修改 DOM 的 className,可以减少重绘和回流的次数
    • 不要把 DOM 结点的属性值放在一个循环里当成循环里的变量,这将会导致页面一直处于回流的过程
    • 不要使用 table 布局,因为你改动一点点都将影响整个 table 的布局
    • 对于动画,放到新建的图层中进行,这样重绘和回流就都只在该图层中进行
    • 尽量少用JS去操作布局
<think>好的,我现在需要回答用户关于“(repaint)”构(reflow,可能用户指的是reflow或rebuild)”在编程或软件开发中的区别的问题,特别是在UI或DOM上下文中的区别。用户还提到了之前关于Vue路由模式的讨论,以及引用了两个关于SurfaceViewLayer处理的资料,但这些引用似乎与当前问题关联不大,可能需要暂时忽略,除非发现潜在联系。 首先,我需要明确用户的问题核心:在UI或DOM上下文中,repaint(re-render(渲染)、redraw(画)与rebuild(建)之间的区别。用户可能混淆了术语,比如“构”可能指的是reflow(回流),而rebuild可能涉及组件的新构建。需要先理清这些术语的定义。 1. **术语定义**: - **Repaint()**:当元素的外观发生变化,但不影响布局时,浏览器会元素。例如,改变颜色、背景、边框等样式属性。 - **Reflow(回流,或称为Layout)**:当元素的布局发生变化时,浏览器需要新计算元素的位置几何形状,这会触发回流。例如,改变宽度、高度、字体大小、元素位置等。 - **Re-render(渲染)**:这个术语可能在不同上下文中有不同含义。在DOM上下文中,可能指新渲染整个组件或部分UI,可能包括回流。在游戏或图形编程中,可能指制整个帧。 - **Rebuild(建)**:通常指新构建DOM结构或组件树,例如React中的组件新渲染导致子组件也新生成,或者虚拟DOM的差异计算后需要更新实际DOM。 2. **区分关键点**: - **影响范围**:回流影响布局,可能导致更多元素需要新计算;仅影响视觉表现,不涉及布局变化。 - **性能开销**:回流的开销通常比大,因为涉及布局计算。频繁的回流会导致性能问题。 - **触发条件**:不同的CSS属性会触发不同的行为。需要举例说明哪些属性触发回流,哪些触发。 - **框架中的概念**:如React中的rebuild可能涉及虚拟DOM的对比更新,而浏览器中的repaint/reflow是底层机制。 3. **用户可能的混淆点**: - 用户可能将“构”理解为reflow,而“”是repaint。需要确认术语的正确性。 - 在UI框架(如React、Vue)中,组件的更新(rebuild)是否会导致浏览器的回流,这两者的关系需要解释清楚。 4. **结合之前的回答**: 用户之前询问了Vue路由模式,可能对前端开发有基础,因此在解释时应结合前端开发的实际场景,比如DOM操作、CSS优化等。 5. **引用资料分析**: 用户提供的引用涉及Android的SurfaceViewLayer处理,虽然与当前问题不直接相关,但可能用户希望了解底层渲染机制。不过当前问题集中在UI/DOM,可能需要简要提及浏览器渲染流程,如浏览器渲染引擎的工作步骤(布局、制等),从而引出reflowrepaint的区别。 6. **可能的扩展问题**: 用户可能接下来会问如何优化回流,或是在特定框架中如何避免不必要的建,需要预判并准备相关问题。 7. **验证信息准确性**: 需要确认回流的标准定义,参考MDN文档或其他权威资源,确保回答正确。例如,MDN指出,回流一定触发,但不一定触发回流。 8. **结构安排**: 先定义每个术语,然后对比区别,接着讨论性能影响,最后给出优化建议。结合代码示例或实际场景帮助理解。 总结思考路径后,开始组织回答内容,确保清晰分点,术语准确,结合实际例子,并预判相关问题。</think>### (Repaint)与构(Reflow/Rebuild)的核心区别 在UI开发(尤其是浏览器DOM操作)中,**(Repaint)** **构(Reflow,或称为回流)** 是影响渲染性能的关键概念,而 **建(Rebuild)** 则更多出现在框架级组件更新中。以下是它们的区别与联系: --- #### 一、核心定义与触发条件 | **术语** | **触发条件** | **性能开销** | **示例场景** | |----------------|-----------------------------------------------------------------------------|-------------|--------------------------------------| | **Reflow(回流)** | 元素的**布局属性**(如尺寸、位置、内容变化)导致浏览器新计算布局树(Layout Tree) | 高 | 修改`width`、`height`、`offsetTop`、字体大小 | | **Repaint()** | 元素的**视觉属性**(如颜色、背景、边框)变化,但布局未改变,仅需制像素 | 中 | 修改`color`、`background`、`opacity` | | **Rebuild(建)** | 框架级组件树或DOM结构的**新生成**(如React/Vue的组件更新、虚拟DOM对比后更新实际DOM节点) | 取决于实现 | 列表数据变化导致组件新渲染 | --- #### 二、浏览器渲染流程中的角色 浏览器的渲染引擎处理步骤: $$ \text{解析HTML/CSS} \rightarrow \text{构建DOM/CSSOM} \rightarrow \text{生成渲染树(Render Tree)} \rightarrow \text{布局(Reflow)} \rightarrow \text{制(Repaint)} $$ 1. **Reflow(回流)** - 修改布局属性(如`width`、`margin`)会触发**新计算所有受影响元素的几何位置**,可能导致级联回流[^1]。 - **优化原则**:减少DOM深度,避免逐项修改样式(改用CSS类批量更新)。 2. **Repaint()** - 仅更新像素到屏幕(如`color`变化),**不涉及布局计算**,但可能因图层合成(Compositing)触发额外GPU操作[^2]。 - **优化原则**:使用`transform``opacity`触发GPU加速(跳过布局制阶段)。 3. **Rebuild(建)** - 在React中,父组件状态变化可能导致子组件**新生成虚拟DOM并对比差异**,最终触发实际DOM的**部分更新**(可能引发回流/)。 - **优化原则**:使用`React.memo`或`shouldComponentUpdate`避免不必要的子组件建。 --- #### 三、性能影响对比 | **操作** | **典型场景** | **性能开销排序** | |------------------|--------------------------------|---------------------| | 修改`position: fixed` | 脱离文档流的元素布局变化 | Reflow < Repaint | | 修改`background-color` | 仅颜色变化 | Repaint | | 动态加载列表数据 | 触发组件DOM插入 | Rebuild → Reflow → Repaint | | 使用CSS动画 | `transform`触发GPU合成 | 仅Composite阶段 | --- #### 四、代码示例与优化策略 ##### 1. **避免连续触发回流**(Bad vs Good) ```javascript // Bad: 触发多次回流 element.style.width = '100px'; element.style.height = '200px'; // Good: 使用CSS类或requestAnimationFrame批量更新 element.classList.add('resized'); ``` ```css .resized { width: 100px; height: 200px; } ``` ##### 2. **利用GPU加速减少** ```css /* 触发GPU合成层,跳过 */ .animated-box { transform: translateZ(0); /* 或使用will-change */ transition: transform 0.3s; } ``` ##### 3. **框架级Rebuild优化(React示例)** ```javascript // 使用React.memo避免子组件建 const ChildComponent = React.memo(({ data }) => { return <div>{data}</div>; }); ``` --- #### 五、常见误区 - **误区1**:`display: none`不触发回流? → 错误!`display: none`会触发回流元素从渲染树移除),而`visibility: hidden`仅触发。 - **误区2**:所有CSS属性修改都会触发回流? → 错误!现代浏览器通过**增量布局**优化,部分属性(如`transform`)可跳过布局阶段。 --- ### 相关问题 1. 如何通过Chrome DevTools检测页面中的强制同步布局(Forced Synchronous Layout)? 2. 虚拟DOM(如React/Vue)如何减少实际DOM的ReflowRepaint操作? 3. CSS属性`will-change`在优化渲染性能中的具体作用是什么? [^1]: 回流会触发子元素后续兄弟元素新布局。 [^2]: 使用GPU加速可避免主线程的制负担。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值