渲染优化分享--dom优化
渲染优化分享--dom优化
dom渲染优化
减少dom节点
dom cssom
什么是 DOM?可能很多人第一反应就是 div、p、span 等 html 标签(至少我是),但要知道,DOM 是 Model,是 Object Model,对象模型,是为 HTML(and XML)提供的 API。HTML(Hyper Text Markup Language)是一种标记语言,HTML 在 DOM 的模型标准中被视为对象,DOM 只提供编程接口,却无法实际操作 HTML 里面的内容。但在浏览器端,前端们可以用脚本语言(JavaScript)通过 DOM 去操作 HTML 内容。
实质上还存在 CSSOM:CSS Object Model,浏览器将 CSS 代码解析成树形的数据结构,与DOM 是两个独立的数据结构。
接下来说一说浏览器渲染。过程。
https://blog.csdn.net/CSDNWuZhiChun/article/details/119786163
DOM 操作成本
讨论 DOM 操作成本,肯定要先了解该成本的来源,那么就离不开浏览器渲染。
- 解析 HTML,构建 DOM 树(这里遇到外链,此时会发起请求)
- 解析 CSS,生成 CSS 规则树
- 合并 DOM 树和 CSS 规则,生成 render 树
- 布局 render 树(Layout/reflow),负责各元素尺寸、位置的计算
- 绘制 render 树(paint),绘制页面像素信息
- 浏览器会将各层的信息发送给 GPU,GPU 将各层合成(composite),显示在屏幕上
构建dom树
构建CSSOM 树
生成render 树
Layout 布局
Paint 绘制
何时触发 reflow 和 repaint
reflow(回流):根据 Render Tree 布局(几何属性),意味着元素的内容、结构、位置或尺寸发生了变化,需要重新计算样式和渲染树; repaint(重绘): 意味着元素发生的改变只影响了节点的一些样式(背景色,边框颜色, 文字颜色等),只需要应用新样式绘制这个元素就可以了; reflow 回流的成本开销要高于 repaint 重绘,一个节点的回流往往会导致子节点以及同级节点的回流
引起 reflow 回流 现代浏览器会对回流做优化,它会等到足够数量的变化发生,再做一次批处理回流。
- 页面第一次渲染(初始化)
- DOM 树变化(如:增删节点)
- Render 树变化(如:padding 改变)
- 浏览器窗口 resize
- 获取元素的某些属性: 浏览器为了获得正确的值也会提前触发回流,这样就使得浏览器的优化失效了,这些属性包括 offsetLeft、offsetTop、offsetWidth、offsetHeight、 scrollTop/Left/Width/Height、clientTop/Left/Width/Height、调用了 getComputedStyle()或者 IE 的currentStyle
引起 repaint 重绘
- reflow 回流必定引起 repaint 重绘,重绘可以单独触发
- 背景色、颜色、字体改变(注意:字体大小发生变化时,会触发回流)
优化 reflow、repaint 触发次数
- 避免逐个修改节点样式,尽量一次性修改
- 使用 DocumentFragment 将需要多次修改的 DOM 元素缓存,最后一次性 append 到真实 DOM 中渲染
- 可以将需要多次修改的 DOM 元素设置 display: none,操作完再显示。(因为隐藏元素不在 render 树内,因此修改隐藏元素不会触发回流重绘)
- 避免多次读取某些属性(见上)
- 将复杂的节点元素脱离文档流,降低回流成本
优化 CSS 样式转换。
如果需要动态更改 CSS 样式,尽量采用触发 reflow 次数较少的方式。
如以下代码逐条更改元素的几何属性,理论上会触发多次 reflow。
可以通过直接设置元素的 className 直接设置,只会触发一次 reflow。
减少 DOM 元素数量
在 console 中执行命令查看 DOM 元素数量。 document.getElementsByTagName( '*' ).length 正常页面的 DOM 元素数量一般不应该超过 1000。 DOM 元素过多会使 DOM 元素查询效率,样式表匹配效率降低,是页面性能最主要的瓶颈之一。
DOM 操作优化 DOM 操作性能问题主要有以下原因。 DOM 元素过多导致元素定位缓慢。 大量的 DOM 接口调用。 JAVASCRIPT 和 DOM 之间的交互需要通过函数 API 接口来完成,造成延时,尤其是在循环语句中。
DOM 操作触发频繁的 reflow(layout)和 repaint。
layout 发生在 repaint 之前,所以 layout 相对来说会造成更多性能损耗。 reflow(layout)就是计算页面元素的几何信息。 repaint 就是绘制页面元素。 对 DOM 进行操作会导致浏览器执行回流 reflow。