Reflow 与 Repaint 这两个东西跟浏览器有著密切的关系, Repaint 是指浏览器重新绘出一张新的页面,通常发生在网页中的 HTML Element Style 遇到变更;而 Reflow 则是指浏览器重新计算 HTML Element 的坐标位置。
以网页效能的观点来看,Reflow 必需重新计算 Elements 的相对座标位置与长宽,然后再触发 Repaint 行为,所以会比单纯的 Repaint 用掉更多的效能。
Repaint
Repaint 事件发生於 HTML Element 外观有变化,但是宽、高、坐标没有变更,例如 color (文字颜色),background-color (背影色),visibility 等 CSS 属性。
以下是会触发 Repaint 的行为:
- Scrolling - 移动视窗卷轴
- 修改 CSS 属性 - visibility, color, background-color
Reflow
Reflow 是指浏览器重新计算 HTML Element 的坐标位置与宽,高,当下一次的 re-rendering 发生,就能够重新定位页面上的 HTML Element,当 Reflow 发生时,它会中断 Browser 的所有行为,有利於工程师了解如何优化 Reflow 时间与 Reflow 对页面操作的影响。
当一个 HTML Element 发生 Reflow 事件时,它的 "Parent Element" 以及 "Parent's Parent Element" 或是 "Child Element" 都有可能会一并发生 Reflow 事件来重新计算坐标,所以 Reflow 次数太多,会严重影响效能。
大部分 User 的操作行为与 HTML Element 的变更,都会触发 Reflow 事件,例如下列几种:
- Window Resizing - 变更 window 的尺寸
- 用 JavaScript 修改 CSS computed styles or inline styles
- 在 DOM 中新增、移除 HTML Element
- 修改 Element 的 className,并包含下列其中一种 style 变更
- display
- padding
- margin
- width
- height
- font-size
优化网页效能
Reflow 与 Repaint 太多会影响效能,那么我们就要想办法减少 Reflow & Repaint 的发生机会。
- 减少 HTML Element 的深度
- 减少 CSS 规则
- 不要一行一行的设定 css style ,改用 CSS ruleset (className) 取代 inline styles.
- 针对 Animation 的使用,建议用绝对座标来定位如 position: absolute, fixed
- 使用 JS 建立 Element 时,一定要用 documentFragment
- 不要使用太大型的 Table , 因为 Table 中的任何一个 Element 被修改,都会导致整个 Table 重新 render
备注
- DOM : Document Object Model
- Computed styles & inline styles