浏览器渲染过程中的reflow和repaint

115 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情

重排Reflow

  • 定义

    • DOM中各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式来计算并根据计算结果将元素放到它该出现的位置,这个过程称为reflow
    • 以上提到的只是在页面加载时必然会出现的repaint和reflow,除此之外,在页面加载完成后,用户的一些操作、脚本的一些操作都会导致浏览器发生这种行为
  • 什么时候触发reflow

    • 需要调整布局时

      • 增加,删除,修改DOM节点时,会导致reflow和repaint
      • 移动DOM位置,或加个动画
      • 修改CSS某些样式
      • 修改网页默认字体
      • resize窗口,滚动页面时(仅pc端),可能触发
  • 如何避免reflow

    • 尽量减少DOM操作,对DOM操作的代价是高昂的,这在网页应用中的通常是一个性能瓶颈
    • 如果做复杂的表现变化,如动画,让它脱离文档流。用绝对定位或 fixed 定位来完成。
    • 避免不必要的复杂的 CSS 选择器,尤其是后代选择器(descendant selectors),因为为了匹配选择器将耗费更多的 CPU

重绘Repaint

  • 定义

    • 当各种盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来后,浏览器于是便把这些元素都按照各自的特性绘制了一遍,于是页面的内容出现了,这个过程称之为repaint
  • 触发repaint

    • 页面显示内容不一样了,就会触发repaint,无法完全避免
    • DOM改动
    • CSS改动
  • 如何最大程度降低repaint的频率

    • 避免在document上直接进行频繁的DOM操作

      • 如果需要创建多个DOM节点,可以使用DocumentFragment创建完后一次性的加入document
    • 集中修改样式

      • 尽可能少的修改元素style上的属性,如el.style.color = 'red'一定会触发重新渲染
      • 尽量通过修改className或者cssTexts属性来修改样式
    • 设置元素的position为absolute或fixed

      • 在元素的position为static和relative时,元素处于DOM树结构当中,当对元素的某个操作需要重新渲染时,浏览器会渲染整个页面。将元素的position设置为absolute和fixed可以使元素从DOM树结构中脱离出来独立的存在,而浏览器在需要渲染时只需要渲染该元素以及位于该元素下方的元素,从而在某种程度上缩短浏览器渲染时间,这在当今越来越多的Javascript动画方面尤其值得考虑。