Web页面Repaint和Reflow

1. Repaint

repaint(重绘)是在一个元素的外观被改变,但没有改变布局的情况下发生,如改变visibility、outline、前景色。当repaint发生时,浏览器会验证DOM树上的所有其它结点的visibility属性。

2. Reflow

如果变化涉及元素布局 (如 width), 浏览器则抛弃原有属性, 重新计算并把结果传递给 render 以重新描绘页面元素, 此过程称为 reflow。reflow(回流)是导致DOM脚本执行低效的关键因素之一。页面上任何一个结点触发reflow,都会导致它的子结点及祖先结点重新渲染。

以下操作会引起reflow:

  • 改变窗囗大小
  • 改变文字大小
  • 添加/删除样式表
  • 内容的改变,如用户在输入框中敲字
  • 激活伪类,如:hover
  • 操作class属性
  • 脚本操作DOM
  • 计算offsetWidth和offsetHeight
  • 设置style属性

Reflow是不可避免的,只能将reflow对性能的影响减小到最小,以下是一些建议:

  • 尽可能限制reflow的影响范围。有时 reflow 页面中的一个元素会 reflow 它的父元素(译注:这里是复数)以及所有子元素。
  • 通过设置style属性改变结点样式的话,每设置一次都会导致一次reflow。所以最好通过设置class的方式。
  • 实现元素的动画,它的position属性应当设为fixed或absolute,这样不会影响其它元素的布局。
  • 权衡速度的平滑。比如实现一个动画,以1个像素为单位移动这样最平滑,但reflow就会过于频繁,CPU很快就会被完全占用。如果以3个像素为单位移动就会好很多。
  • 不要用tables布局的另一个原因就是tables中某个元素一旦触发reflow就会导致table里所有的其它元素reflow。在适合用table的场合,可以设置table-layout为auto或fixed,这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围。
  • 很多情况下都会触发reflow,如果css里有expression,每次都会重新计算一遍。
  • 避免在document上直接进行频繁的DOM操作,如果确实需要可以采用off-document的方式进行
    • 先将元素从document中删除,完成修改后再把元素放回原来的位置
    • 将元素的display设置为”none”,完成修改后再把display修改为原来的值
    • 如果需要创建多个DOM节点,可以使用DocumentFragment创建完后一次性的加入

参考文档

  • Minimizing browser reflow
  • Rendering: repaint, reflow/relayout, restyle
  • 页面重构应注意的repaint和reflow

如需转载,请注明来自: BorisHuai前端修炼 > Repaint and Reflow

你可能感兴趣的:(Web页面Repaint和Reflow)