深入理解为什么应该使用transform来替代top
话说,这个问题我们得从浏览器得渲染机制说起:
我们先来理解一下 重绘(Repainit)和 回流(Reflow):
重绘:当节点需要更改外观而不会影响布局得,比如改变 color 就称为重绘;
回流:布局或者几何属性需要改变就称为回流(换个说辞即是需要重新渲染Dom节点);
回流必定会发生重绘,重绘不一定会引发回流。回流所需得成本比重绘高得多,改变父节点里得子节点很可能会导致父节点得一系列回流。
以下几个动作可能会导致性能问题:
①.改变window大小;
②.改变字体;
③.添加或删除样式;
④.文字改变;
⑤.定位或者浮动;
⑥.盒模型;
通过查看HTML文档,学习到,重绘和回流其实也和 Eventloop 有关,为了系统学习,现摘录如下:
1.当 Eventloop 执行完 Microtasks 后,会判断 document 是否需要更新,因为浏览器是 60Hz 得刷新率,每 16.6 ms 才会更新一次;
2.然后判断是否有 resize 或者 scroll 事件,有的话会去触发事件,所以 resize 和 scroll 事件也是至少 16 ms 才会触发一次,并且自带节流功能;
3.判断是否触发了 media query;
4.更新动画并且发送事件;
5.判断是否有全屏操作事件;
6.执行 requestAnimationFrame 回调;
7.执行 IntersectionObserver 回调,该方法用于判断元素是否可见,可以用于懒加载上,但是兼容性不好;
8.更新界面;
9.以上就是一帧中可能会做的事情。如果在一帧中有空闲事件,就会去执行requestIdleCallback 回调;
综上可知,重绘和回流会影响页面性能,那么在实际开发中我们如何来尽量减少性能的损耗呢,如下:
使用transform后,页面的回流直接没有了,这就是使用transform性能更好的原因,如果我们使用定时器频繁改变 top 的时候,效果就会十分明显,其实在 css 类似的属性还有很多,这里只是以 transform 作为切入点进行讲解,其他优化的策略还有:
- opacity替代visibility ;
- 多个DOM统一操作(虽然 V8 会有缓存优化);
- 先将DOM离线,即 display:none;修改后显示;
- 不要把DOM放在已有循环中作为循环变量;
- 不要使用table;