关于javascript:从浏览器渲染层面解析css3动效优化原理

36次阅读

共计 2917 个字符,预计需要花费 8 分钟才能阅读完成。

引言

在 h5 开发中,咱们常常会须要实现一些动效来让页面视觉效果更好,谈及动效便不可避免地会想到动效性能优化这个话题:

  • 缩小页面 DOM 操作,能够应用 CSS 实现的动效不多出一行 js 代码
  • 应用相对定位脱离让 DOM 脱离文档流,缩小页面的重排(relayout)
  • 应用 CSS3 3D 属性开启硬件加速

那么,CSS3 与动效优化有什么关系呢,本文将从浏览器渲染层面讲述 CSS3 的动效优化原理

浏览器页面展现过程

首页,咱们须要理解一下浏览器的页面展现过程:

  • Javascript:次要负责业务交互逻辑。
  • Style: 依据 CSS 选择器,对每个 DOM 元素匹配对应的 CSS 款式。
  • Layout: 具体计算 DOM 元素显示在屏幕上的大小及地位。
  • Paint: 实现一个 DOM 元素的可视成果(色彩、边框、暗影等),一般来说由多个渲染层实现。
  • Composite: 当每个层绘制实现后,浏览器会将所有层依照正当程序合并为一个图层,显示到屏幕。
    本文咱们将重点关注 Composite 过程。

浏览器渲染原理

在探讨 Composite 之前,咱们还须要理解一下浏览器渲染原理

从该图中,咱们能够发现:

  • DOM 元素 Layout Object 存在一一对应的关系
  • 一般来说,领有雷同坐标空间的 Layout Object 属于同一个 Paint Layer (渲染层),通过 position、opacity、filter等 CSS 属性能够创立新的 Paint Layer
  • 某些非凡的 Paint Layer 会被认为是 Composite Layer (合成层 / 复合层),Composite Layer 领有独自的 Graphics Layer (图形层),而那些非 Composite Layer 的 Paint Layer,会与领有 Graphics Layer 的父层共用一个

Graphics Layer

咱们日常生活中所看到屏幕可视成果能够了解为:由多个位图通过 GPU 合成渲染到屏幕上,而位图的最小单位是像素。如下图:

那么位图是怎么取得的呢,Graphics Layer 便起到了关键作用, 每个 Graphics Layer 都有一个 Graphics Context, 位图是存储在共享内存中,Graphics Context 会负责将位图作为 纹理 上传到 GPU 中,再由 GPU 进行合成渲染。如下图:

CSS 在浏览器渲染层面承当了怎么的角色

大多数人对于 CSS3 的第一印象,就是能够通过 3D(如 transform)属性来开启硬件加速,许多同学在重构某一个我的项目时,思考到动画性能问题,都会偏向:

  1. 将 2Dtransform 改为 3Dtransform
    2. 将 left (top、bottom、right)的挪动改为 3Dtransform
    但开启硬件加速的 底层原理 其实就在于 将 Paint Layer 晋升到了 Composite Layer

    以下的几种形式都用雷同的作用:
  2. 3D 属性开启硬件加速(3d-transform)
  3. will-change: (opacity、transform、top、left、bottom、right)
  4. 应用 fixed 或 sticky 定位
  5. 对 opacity、transform、filter 利用了 animation(actived) or transition(actived),留神这里的 animation 及 transition 须要是处于 激活状态 才行

咱们来写两段 demo 代码,带大家具体分析一下理论状况

demo1. 3D 属性开启硬件加速(3d-transform)

.composited{
  width: 200px;
  height: 200px;
  background: red;
  transform: translateZ(0)
}
</style>

<div class="composited">
  composited - 3dtransform
</div>


能够看到是因为应用的 CSS 3D transform,创立了一个复合层

demo2. 对 opacity、transform、filter 利用 animation(actived) or transition(actived)

<style>
@keyframes move{
  0%{top: 0;}
  50%{top: 600px;}
  100%{top: 0;}
}
@keyframes opacity{
  0%{opacity: 0;}
  50%{opacity: 1;}
  100%{opacity: 0;}
}

#composited{
  width: 200px;
  height: 200px;
  background: red;
  position: absolute;
  left: 0;
  top: 0;
  
}
.both{animation: move 2s infinite, opacity 2s infinite;}
.move{animation: move 2s infinite;}
</style>

<div  id="composited" class="both">
  composited - animation
</div>
<script>
setTimeout(function(){const dom = document.getElementById('composited')
  dom.className = 'move'
},5000)
</script>

这里咱们定义了两个keyframes(move、opacity),还有两个class(both、move),起初 #compositedclassName = 'both',5 秒延时器后,className = 'move',咱们来看看浏览器的理论变动。

起初:#composited 创立了一个复合层,并且静止时 fps 没有稳定,性能很稳固

5 秒后:复合层隐没,静止时 fps 会产生抖动,性能开始变得不再稳固

如何查看复合层及 fps

在浏览器的 Dev Tools 中抉择 More tools,并勾选 Rendering 中的 FPS meter

动画性能最优化

之前,咱们提到了页面出现进去所经验的渲染流水线,其实从性能方面思考,最现实的渲染流水线是没有布局和绘制环节的 ,为了实现上述成果,就须要只应用那些仅触发 Composite 的属性。

目前,只有两个属性是满足这个条件的:transformsopacity(仅局部浏览器反对)。
相干信息可查看:css Triggers

总结

晋升为合成层简略说来有以下几点益处:

  • 合成层的位图,会交由 GPU 合成,比 CPU 解决要快
  • 当须要 repaint 时,只须要 repaint 自身,不会影响到其余的层
  • 对于 transform 和 opacity 成果,局部浏览器不会触发 Layout 和 Paint,相干信息可查看:css Triggers

毛病:

  • 创立一个新的合成层并不是收费的,它得耗费额定的内存和治理资源。
  • 纹理上传后会交由 GPU 解决,因而咱们还须要思考 CPU 和 GPU 之间的带宽问题、以及有多大内存供 GPU 解决这些纹理的问题

大多数人都很喜爱应用 3D 属性 translateZ(0) 来进行所谓的硬件加速,以晋升性能。但咱们还须要切实的去剖析页面的理论性能体现,一直的改良测试,这样才是正确的性能优化路径。

参考资料

无线性能优化:Composite – 淘系前端团队


欢送关注凹凸实验室博客:aotu.io

或者关注凹凸实验室公众号(AOTULabs),不定时推送文章。

正文完
 0