我们来看看chrome控制台动画的性能

问题1:我们使用left/top来看看动画的性能

body {
  padding: 30px;
  text-align: center;
}

.container {
  position: relative;
  min-height: 400px;
  -webkit-tap-highlight-color: rgba(0,0,0,0);
}
.ball {
  position: absolute;
  top: 0;
  left: 0;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.75);
}
.ball:nth-last-child(1) {
  background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/splogo.png');
  background-position: center center;
  background-repeat: no-repeat;
}
.ball-running {
  -webkit-animation: run-around 4s infinite;
  animation: run-around 4s infinite;
}
@keyframes run-around {
  0%: {
    top: 0;
    left: 0;
  }
  25% {
    top: 0;
    left: 200px;
  }
  
  50% {
    top: 200px;
    left: 200px;
  }
  
  75% {
    top: 200px;
    left: 0;
  }
}
我们的页面结构如下:

 <div class="container">
    <div class="ball" id="ball"></div>
</div>
然后我们看看JS代码:

var balls = document.getElementById('ball');
balls.classList.add("ball");
balls.classList.add('ball-running');
我们从控制台来看看动画的执行性能:

首先我们看到动画运行的时候一直有一个绿色框,这表示重绘的区域,而且是一直重绘的:


第二步:我们看看这个动画的时间分布


我们可以看到页面重绘的时间是107.3ms,二页面回流的时间是186.8ms

第三步:我们看看具体的事件步骤


我们可以看到每次都会重新计算样式,位置大小等,然后更新每一层的元素的相关信息,然后合成每一层的内容显示。这将导致很严重的重绘和回流,对于性能的消耗要大得多。注意:这里只有一个图层,就像PS图层一样,我们只是会重新绘制图层中的元素,而不是整个图层本身,因此图层本身并没有变成绿色。

问题2:我们看看使用transform实现的动画性能

修改CSS样式如下:

              body {
		  padding: 30px;
		  text-align: center;
		}
		.container {
		  position: relative;
		  min-height: 400px;
		  -webkit-tap-highlight-color: rgba(0,0,0,0);
		}
		.ball {
		  position: absolute;
		  top: 0;
		  left: 0;
		  width: 100px;
		  height: 100px;
		  border-radius: 50%;
		  box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.75);
		}
		.ball:nth-last-child(1) {
		  background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/splogo.png');
		  background-position: center center;
		  background-repeat: no-repeat;
		}
		.ball-running {
		  animation: run-around 4s infinite;
		}
		@keyframes run-around {
		  0% {
		    transform: translate(0, 0);
		  }
		  25% {
		    transform: translate(200px, 0);
		  }  
		  50% {
		    transform: translate(200px, 200px);
		  }
		  75% {
		    transform: translate(0, 200px);
		  }
		}
第一步:我们看到浏览器为该元素产生了一个独立的层

第二步:我们看看总时间分布



可以看到重绘的时间明显减少

第三步:看看事件的顺序


我们看到这里主要牵涉到样式计算,然后更新特定层的元素,最后再合成就可以了,明显没有了前面的重绘和回流操作。注意:因为这里是transform属性的改变,如果是改变left/top值,那个这个图层还是会发生回流和重绘操作的。

浏览器接收到页面文档后,会将文档中的标记语言解析为DOM树。DOM树和CSS结合后形成浏览器构建页面的渲染树。渲染树中包含了大量的渲染元素,每一个渲染元素会被分到一个图层中,每个图层又会被加载到GPU形成渲染纹理,而图层在GPU中 transform 是不会触发 repaint 的(只是重新计算元素的样式,然后根据计算的样式更新特定层的元素,然后把更新后的层和其他层合成起来,这个过程中是没有repaint的),这一点非常类似3D绘图功能,最终这些使用 transform 的图层都会由独立的合成器进程进行处理。

注意:因为上面我们使用的是2D变化,而不是3D变换。3D 和 2D transform 的区别就在于,浏览器在页面渲染前为3D动画创建独立的复合图层,而在运行期间为2D动画创建。动画开始时,生成新的复合图层并加载为GPU的纹理用于初始化 repaint。然后由GPU的复合器操纵整个动画的执行。最后当动画结束时,再次执行 repaint 操作删除复合图层。所以,上面的例子在开始和结束的时候会有两次repaint操作。

问题2:不要弄混淆,即使单独创建了一个图层,如果变动了重绘和重排的指标,也是会回流和重排的

例子的代码如下:

     .box{
       	  width:100px;
       	  height:100px;
       	  background-color: #ccc;
       	  position:absolute;
       	  top:0;
       	  left:0;
       	  transition:left 5s linear;
       	  transform: translateZ(0);
       	  /*这时候虽然给我们的box元素放在一个独立的层当中,但是我们依然修改了他的left属性,所以他肯定会重绘回流,除非我们修改为transform属性和opacity*/
       }
       .hv{
       	 left:400px;
       }
JS代码如下:

    window.οnlοad=function(){
       	 	var box=document.querySelector('.box');
       	 	box.classList.add('hv');
       	 }
DOM结构如下:

 <div class="box"></div>
这时候我们通过了transform:translateZ为这个元素创建了一个独立的图层,但是我们的transition依然是通过left来完成的, 这时候也是会发生回流,重绘,合成操作的。但是这时候的回流,重绘,合成操作都是在该图层中进行的,而不会影响其他的图层。



我们把上面的动画使用transform来完成

 .box1{
       	  width:100px;
       	  height:100px;
       	  background-color: #ccc;
       	  position:absolute;
       	  top:0;
       	  left:0;
          transition:transform 5s;
          -webkit-transition: -webkit-transform 2s;
          -webkit-backface-visibility:hidden;
       	  transform: translate3d(0,0,0);
       	  -webkit-perspective:1000;  
       }
       .hv1{
       	  transform: translate3d(200px,0,0);
       }
修改CSS属性如上,我们看看结果如何


这时候我们看到已经没有前面说的重绘和回流了,这就是transform动画的优秀之处。使用tranforms来实现移动效果的元素将会被正常绘制,同时不会触发对其他元素的绘制。这种处理方式和思想跟图像处理软件(比如Sketch/GIMP/Photoshop)是一致的,它们都是可以在图像中的某个单个图层上做操作,最后合并所有图层得到最终的图像。摘抄自简化绘制的复杂度、减小绘制区域

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值