HTML页面重绘和重排(回流)

本文深入探讨了浏览器如何解析HTML和CSS构建DOM树和渲染树,解释了布局渲染树和绘制渲染树的过程,以及重绘和重构的概念。同时,提供了优化网页性能的策略,帮助开发者减少不必要的重排和重绘。

HTML页面重绘和重排(回流)

##浏览器运行机制
1.构建DOM树( parse )

渲染引擎解析HTML文档,首先将标签转换成DOM树中的DOM node(包括js生成的标签)生成内容树

2.构建渲染树(construct)

解析对应的CSS样式文件信息,构建渲染树,每一个NODE都有自己的style,render tree不包含隐藏的节点,因为这些节点不会用于呈现。

3.布局渲染树(reflow/layout)

从根节点递归调用,计算每一个元素的大小、位置等,给出每个节点所应该在屏幕上的精确坐标.

4.绘制渲染树(paint/repaint)

遍历渲染树,使用UI层来绘制每个节点.

重绘(repaint redraw)

当盒子的位置、大小及其他属性确定下来之后,浏览器便将这些原色都按照各自的特性再次绘制,将内容呈现在页面上,
 重绘是指一个元素外观的改变所触发的浏览器行为。
触发条件:改变元素外观

重构

因为规模尺寸大小、布局、隐藏等改变而重新构建,就为重构。

重构与重绘的关系
重排必定触发重构

##优化
减少对渲染树的操作,合并多次的DOM和样式的修改,并减少对style样式多的请求
1.直接改变元素的className
2.先设置display:none,进行页面布局,设置后再设置为block
3.使用cloneNode 和 replaceChild 触发一次回流和重绘
4.将多次重排的元素 position设置为absolute \fixed 使其脱离文档流
5.创建多个DOM节点,可以使用DocumentFragment创建后一次性加入document

### 什么是浏览器的重排? 在网页渲染过程中,**重排(reflow)** 是指浏览器新计算页面中 DOM 元素的位置几何信息,并更新渲染树的过程。任何影响元素布局的操作都会触发重排,例如修改元素的尺寸、位置、内容或字体大小等 [^3]。重排是一个相对昂贵的操作,因为它可能会影响到整个页面的布局结构,尤其是当根节点发生改变时。 而**(repaint)** 则是在不改变元素布局的前提下,仅对元素的外观进行更新,比如更改背景颜色、字体颜色、可见性等非几何属性 [^1]。通常发生在重排之后,但并非所有都会伴随重排。 --- ### 浏览器渲染流程 浏览器在接收到 HTML CSS 资源后,会依次完成以下步骤: 1. **HTML 解析生成 DOM 树** 2. **CSS 解析生成 CSS 规则** 3. **DOM CSSOM 合并生成渲染树** 4. **排列(Layout):计算每个元素页面中的具体位置** 5. **制(Painting):将元素制到屏幕上** 其中,**排列对应的是重排制对应的是** [^4]。 --- ### 常见触发重排/的行为 以下行为会触发重排: - 页面首次加载 - 添加或删除可见的 DOM 元素 - 元素位置或尺寸的变化(如 `width`、`height`、`margin` 等) - 内容变化(如文本或图片引起的尺寸变化) - 字体大小变化 - 浏览器窗口大小调整(触发 `resize` 事件) - 使用 JavaScript 动态设置 `style` 属性 [^3] 以下行为只会触发: - 修改非几何属性,如 `color`、`background-color`、`outline`、`visibility` 等 [^1] --- ### 如何优化重排? 为了提高网页性能,可以采取以下策略来减少重排的发生频率及影响范围: #### 1. 减少重排范围 应尽量以局部布局的方式组织 HTML 结构,避免对整个文档树造成影响。这样即使发生重排,也只会影响部分区域 [^3]。 #### 2. 避免频繁操作 DOM 频繁地读取写入 DOM 会导致多次重排。可以使用以下方式优化: - 批量操作 DOM,先将元素从文档中移除,完成所有修改后再插入。 - 使用 `DocumentFragment` 来构建复杂的 DOM 片段后再插入。 #### 3. 使用 `CSS3` 硬件加速 某些 CSS 属性(如 `transform`、`opacity`、`filters` `will-change`)能够触发 GPU 加速,从而避免引起重排。这在动画效果中尤为有效 [^5]。 ```css .element { transform: translateZ(0); will-change: transform; } ``` 但需要注意,过度使用硬件加速可能导致内存占用过高,甚至影响字体渲染质量。 #### 4. 使用防抖节流技术 对于频繁触发的事件(如 `resize`、`scroll`),可以通过防抖(debounce)节流(throttle)控制执行频率,减少不必要的重排。 ```javascript function debounce(fn, delay) { let timer; return function () { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, arguments), delay); }; } window.addEventListener('resize', debounce(() => { // 处理 resize 逻辑 }, 300)); ``` #### 5. 避免强制同步布局 JavaScript 中某些操作会强制浏览器立即执行重排,如访问 `offsetWidth`、`offsetHeight` 等属性。应尽量避免在循环或高频函数中使用这些方法。 --- ### 总结 重排是浏览器渲染过程中的关键环节,直接影响网页性能。通过合理使用 CSS 技术、减少 DOM 操作频率以及优化事件处理机制,可以显著提升页面响应速度与用户体验。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值