通俗易懂的重排 和 重绘

87 阅读2分钟

三个概念,三分钟搞清楚,不过面试现在不怎么问了,但也有面试官会提到,记录一下

概念

重绘:元素外观发生改变,不影响布局,重新绘制元素外观,改变元素的color、background、box-shadow等。

重排:刚开始我以为这是两个概念,原来重排和回流是一个概念,这里就用重排吧。

   重排是当 DOM 的变化影响了元素的几何信息,浏览器需要重新计算元素的几何属性,将其安放在界面的正确 位置,找个过程叫做重排,表现为重新生成布局,重新排列元素

说的这么不是很难懂,但也不是很好懂

用一句话重排就是,重新计算元素尺寸大小,重新定位元素位置,重新生成布局

那么,有这么一句话: 重排一定会重绘,但重绘不一定会重排。 对,很浅显易懂,

问题

如何防止重排呢,需要先弄清楚,哪些css属性会导致重排,

比如,宽高,上下间距,定位,浮动,居中显示等

Vue 和 react 其实已经帮我们做了很好的兼容处理,因为虚拟dom的原理,频繁的操作dom,不会是直接操作浏览器的真实dom,而是直接变动虚拟dom,在确定操作完成后,会通过patch方法将虚拟dom渲染到浏览器上。这里面不做过多阐述patch方法。

有下面的几种方法 防止重绘 和 重排:

  • 尽量减少重排的范围,尽可能在修改低层级的布局,尽量不要影响全局的范围

  • 尽量减少使用 table 布局。如果一定要用 table 时,可以设置 table-layout:auto 或者是 table-layout:fixed 可以让 table 一行一行的渲染,尽量限制 reflow 的影响范围

  • 样式集中改变

  • 分离读写操作,多个读或者多个写应该放在一起

  • DOM 隐藏

    • display:none,一旦设置 none 时,只会触发一次重排重绘,元素便不会再渲染树中,相当于将其从页面中拿掉,之后再对元素做样式修改后再显示,这样只会触发两次重排。
    • visibility:hidden 的元素只对重绘有影响,不影响重排
    • 通过 documentFragment 创建一个 dom 碎片,在它上面批量操作 dom,操作完成之后,再添加到文档中,这样只会触发一次重排
    • 复制节点,在副本上工作,然后再替换
  • 使用 absolute 或者 fixed

  • 动画采用 GPU 加速,translate 使用 3d 变化

  • 提升为合成层,合成层的位图都会交由 GPU 合成,比 CPU 处理要快,可采用 css 的 will-change: transform

如有错误或者问题,请帮忙支持,万分感谢。

image.png