一、问题
今天在使用css3的transition做动画过渡时,发现动画会卡顿,特此记录我发现卡顿的一些原因和笔记。
先给出结论:
在使用css3 transtion做动画效果时,transform实现的动画是与合成器线程相关的,不需要等待主线程样式计算或者 JS 执行,计算速度是很快的;而使用height,width,margin和padding做动画过渡时,会导致浏览器发生布局和绘制的调整,主线程需要重新计算样式并且执行JS,计算速度自然就慢了。
二、以height为过渡属性时
当一个元素的过渡属性为height:从100px,过渡到200p时,
div {
height: 100px;
transition: height 1s linear;
}
div:hover {
height: 200px;
}
主线程和合成线程将按照下面的流程图执行相应的操作。注意在橘黄色方框的操作会比较耗时,在蓝色框中的操作是比较快速的。
(搬运了别人的图片来解释一下~~)
从图中可以看出,主线程将运行100次(101px => 102px => 103px => …),合成线程将运行100次(101px => 102px => 103px => …)。并且每次主线程运行时,都会经过一次主线程的渲染流程。
主线程的渲染流程,可以参考浏览器渲染网页的流程:
使用 HTML 创建文档对象模型(DOM)
使用 CSS 创建 CSS 对象模型(CSSOM)
基于 DOM 和 CSSOM 执行脚本(Scripts)
合并 DOM 和 CSSOM 形成渲染树(Render Tree)
使用渲染树布局(Layout)所有元素
渲染(Paint)所有元素
也就是说,主线程每次都需要执行Scripts,Render Tree ,Layout和Paint这四个阶段的计算。
三、以transform为过渡属性时
div {
transform: scale(0.5);
transition: transform 1s linear;
}
div:hover {
transform: scale(1.0);
}
以transform为过渡属性时,主线程和合成线程将按照下面的流程图执行相应的操作。
从图中可以看出,主线程将运行1次,合成线程将运行100次。且合成线程的耗时是比主线程的少的。
看到这里,小伙伴们应该能清楚为什么用height、width、margin、padding为过渡属性时,动画有时会卡顿了吧(在性能越差的设备,卡顿越明显)。根据专业人士测量,transform比margin性能好50%~70%
都看到这里了,就请小伙伴们留下你的点赞吧,谢谢给位啦。
四、结论
在使用css3的transition做动画过渡时,优先使用transform,尽量不要使用height,width,margin和padding。