今天看到一篇文章,《前端性能优化(CSS动画篇)》,里面提及到CSS3的一个新属性transform: translate,我之前也见过这属性,但没用过,就亲自去用用。在进入主题前我想分享一句来自上述文章中的一句话:
“我们通过节点的transform可以修改节点的位置、旋转、大小等。我们平常会使用left和top属性来修改节点的位置,但正如上面所述,left和top会触发重布局,修改时的代价相当大。取而代之的更好方法是使用translate,这个不会触发重布局。”
我看完之后在想,既然它可以移动、放大缩小、旋转,为什么不会触发页面重布局呢?用了transform的元素,会不会脱离正常文本流?因为百度搜不到这个答案,有些说脱有些说不脱,因此我自己去实践了一下。我们先来看一个对比。
如此可见,为第一个p元素设置了transform属性后,没有脱离文本流,因为它把下面的p元素也顶了下去了,那么它又为什么没有发生重布局呢?答案是因为第一个p元素,它还是在它原本的位置,没有放大缩小旋转偏移,我们看到的只是视觉上的效果。怎么说呢,就比如你看3D电影,里面的子弹飞出来,你看得很爽,但实际上那些画面都还是在那块2d的荧幕上。
因此,使用transform属性,没有发生重布局,也没有脱离文本流。
最后针对那段引文补充一下,改变节点的位置用transform好还是top、left好,是要看使用场景的,transform是用来做动画用的,left、top是用来基于一个参考物定位用的,各有所用武之地。所以我觉得原文作者是想说,如果只是想做CSS动画让某个结点移动,最好用transform,而不是会导致重布局的left、top,因为重布局需要重新计算其他被影响的节点的位置和大小,被影响的DOM树越大(可见节点),重绘所需要的时间就会越长,而渲染一帧动画的时间也相应变长。所以需要尽力避免这些属性。