Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CSS] [2021-02-24 更新] 说一下什么是重绘重排,哪些操作会造成重绘重排Css ? #27

Open
jeddygong opened this issue Feb 24, 2021 · 1 comment
Labels

Comments

@jeddygong
Copy link
Owner

No description provided.

@jeddygong jeddygong added CSS CSS的类别 滴滴 58 labels Feb 24, 2021
@jeddygong
Copy link
Owner Author

1.重排、重绘

1.1 什么是重绘重排:

​ 当我们改变了一个元素的尺寸位置属性时,会重新进行样式 计算(computed style)布局(layout) 绘制(paint) 以及后面的所有流程,这种行为成为重排

​ 当改变了某个元素的颜色属性时不会重新触发布局,但还是会触发样式计算和绘制这就是重绘

​ 我们可以发现重排和重绘都会占用主线程,还有JS也会运行在主线程,所以就会出现抢占执行时间的问题,如果你写了一个不断导致重排重绘的动画,浏览器则需要在每一帧都运行样式计算布局和绘制的操作。

1.2 触发的一些因素:

  1. 页面首次进入的渲染;
  2. 浏览器resize;
  3. 元素位置和尺寸发生改变的时候
  4. 可见元素的增删;
  5. 内容发生改变;
  6. 字体的font的改变;
  7. css伪类激活;
  8. ......

1.3 如何优化:

​ 我们知道当前页面以每秒60帧的刷新率时才不会让用户感觉到页面卡顿,如果在运行动画是还有大量的JS任务需要执行,因为布局、绘制和js执行都是在主线程运行的,当在一帧的时间内布局和绘制结束后,还有剩余时间js就会拿到主线程的使用权,如果js执行时间过长,就会导致在下一帧开始时js没有及时归还主线程,导致下一帧动画没有按时渲染,就会出现页面的卡顿。

1.3.1 第一种优化方式:

​ requestAnimationFrame,它会在每一帧被调用,通过回调API的回调,可以把js运行任务分成-些更小的任务块,在每一帧事件用完前暂停js执行归还主线程,这样的话在下一帧开始时,主线程就可以按时执行布局和绘制。

1.3.2 第二种优化方式:

​ 栅格化的整个流程不占用主线程,只在合成器线程和栅格线程中运行,这就意味着它无需和js抢占主线程。如果反复进行重绘和重排可能会导致掉帧,这是因为有可能js执行阻塞了主线程,而CSS中有个动画属性transform, 通过该属性实现的动画不会经过布局和绘制,而是直接运行在合成器线程和栅格线程,所以不会受到主线程中js执行的影响。更重要的是听过transform实现的动画由于不需要经过布局绘制 样式计算等操作,所以节省了很多运算事件(方 便实现负责的动画)

1.4 避免重绘重排具体方案

1.4.1 CSS

  • 使用transform替代top等位移 ;
  • 使用visibility替换display: none ;
  • 避免使用table布局 ;
  • 尽可能在DOM树的最末端改变class;
  • 避免设置多层内联样式,尽量层级扁平;
  • 将动画效果应用到position属性为absolute或fxed的元素上;
  • 避免使用CSS表达式;
  • 将频繁重绘或者回流的节点设置为图层,比如 video, iframe ;
  • CSS3硬件加速(GPU加速) ,可以是transform: translateZ(0)、opacity、 flters、 will- change,Will-change提前告诉浏览器元素会发生什么变化;

1.4.2 JS

  • 避免频繁操作样式,合并操作;
  • 避免频繁操作DOM,合并操作;
  • 防抖节流控制频率;
  • 避免频繁读取会引发回流/重绘的属性,比如上面的C、O、S属性
  • 对具有复杂动画的元素使用绝对定位。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant