🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# animation与transform #### 区别对比 transition 关注的是 CSS 属性值的变化,属性值和时间的关系是一个三次贝塞尔曲线。 * transition的优点在于简单易用,它的主要局限为: * transition是一次性的,不能重复发生,除非一再触发。 * transition只能定义开始状态和结束状态,不能定义中间状态,也就是说只有两个状态。 * animation 作用于元素本身而不是样式属性,可以使用关键帧的概念,说可以实现更自由的动画效果。 #### 性能优化 正常情况下,在transition / animation动画的每一帧中,浏览器都要relayout和repaint,然后将位图发送给GPU。加载位图到GPU内存中是很慢的。 > 浏览器之所以这么拼命的工作是因为元素在不停的变化。而且修改元素的高度可能会导致子元素的大小也会变化,所以浏览器不得不进行relayout。在relayout之后主线程还需要重新生成元素的位图。 > **如果想进行优化,我们可以利用硬件加速:** 我们可以将页面绘制的过程分为三个部分:Layout、Paint和合成。Layout负责计算DOM元素的布局关系,Paint负责将DOM元素绘制成位图,合成则负责将位图发送给GPU绘制到屏幕上(如果有transform、opacity等属性则通知GPU做处理)。 GPU加速其实是一直存在的,而如同 translate3D 这种hack只是为了让这个元素生成独立的 GraphicsLayer , 占用一部分内存,但同时也会在动画或者Repaint的时候不会影响到其他任何元素,不会触发主线程的 layout 和repaint ,对高刷新频率的东西,应该分离出单独的一个 GraphicsLayer。 GPU对于动画图形的渲染处理比CPU要快。 一般是在以下几种情况下,浏览器会创建一个独立图层: 对 opacity 和 transform 应用了CSS动画的层 使用了加速CSS滤镜(filters)的层 3D或者加速2D环境下的canvas元素的层 同合成层重叠,且在该合成层上面(z-index)渲染的层 3D 和 2D transform 的区别就在于,浏览器在页面渲染前为3D动画创建独立的复合图层,而在运行期间为2D动画创建。动画开始时,生成新的复合图层并加载为GPU的纹理用于初始化 repaint。然后由GPU的复合器操纵整个动画的执行。最后当动画结束时,再次执行 repaint 操作删除复合图层。 硬件加速的注意点: 如果GPU加载了大量的纹理,很容易就会发生内存问题,这一点在移动端浏览器上尤为明显,所以,不要让页面的每个元素都使用硬件加速。防止出现层爆炸,可以通过将该层提高(设置相对定位并提高z-index)。 #### will-change 优化 在CSS中提供了一个新的CSS特性: will-change。其主要作用就是提前告诉浏览器我这里将会进行一些变动,请分配资源(告诉浏览器要分配资源给我)。 在使用will-change时应该注意: * 不要将 will-change 应用到太多元素上:浏览器已经尽力尝试去优化一切可以优化的东西了。有一些更强力的优化,如果与 will-change 结合在一起的话,有可能会消耗很多机器资源,如果过度使用的话,可能导致页面响应缓慢或者消耗非常多的资源。 * 不要过早应用 will-change 优化:如果你的页面在性能方面没什么问题,则不要添加 will-change 属性来榨取一丁点的速度。 will-change 的设计初衷是作为最后的优化手段,用来尝试解决现有的性能问题。它不应该被用来预防性能问题。 * 有节制地使用:通常,当元素恢复到初始状态时,浏览器会丢弃掉之前做的优化工作。但是如果直接在样式表中显式声明了 will-change 属性,则表示目标元素可能会经常变化,浏览器会将优化工作保存得比之前更久。所以最佳实践是当元素变化之前和之后通过脚本来切换 will-change 的值。 在使用will-change一定要注意方式方法,比如常见的错误方法是直接在:hover是使用,并没有告诉浏览器分配资源。其正确使用的方法是,在进入父元素的时候就告诉浏览器,你该分配一定的资源