h5渲染性能一瞥


内容来源:2018 年 6 月 30 日,饿了么前端主管向勇在“饿了么技术沙龙・第27弹 【前端专场】”进行《h5渲染性能一瞥》演讲分享。IT 大咖说(微信id:itdakashuo)做为独家视频合做方,经主办方和讲者审阅受权发布。前端

阅读字数:2488 | 7分钟阅读面试

获取嘉宾演讲视频及PPT:suo.im/4SkvOx
性能优化

摘要

前端性能按照类型来分主要分为加载性能和渲染性能。加载性能对于首屏的展现及其重要,而渲染性能对于页面加载完成后的交互体验极其重要。但目前绝大部分同窗在提到前端性能的优化时都会默认等同于对加载性能的优化,而忽略了渲染性能。本次议题就从几个比较常见的角度聊聊开发中会无心识碰到的渲染性能问题。微信

H5 VS Native

在将H5和native进行对比的时候,咱们一般能想到的一点就是“快”,H5相对于native开发和上线都会快一些,通常的活动页面和非关键页面更多的倾向于H5来开发。前端性能

固然H5也有相应的缺点,它的加载和操做会慢一些,抽象来看就是性能问题。加载慢对应的是加载性能,操做慢对应的是渲染性能。加载性能可被定义为页面首次加载时候的性能,这方面的优化方案主要有静态资源压缩、懒加载、雪碧图、CDN、server push等。布局

渲染性能可被定义为页面进行操做/交互时候的性能,对于这方面的优化可能并不太容易想到。我在面试的时候也常常会问面试者关于性能优化的问题,不过大部分提到的优化方案都是关于加载性能,少部分会提到GPU加速,相对来讲这部分同窗的CSS技能会高一些。性能

渲染

通常一次渲染都会通过JavaScript > style > layout > paint > compoasite这样的过程。在作动画的时候能够进行优化,将layout和paint省略掉,这实际上是将作动画的元素提高为一个单独的层。flex

渲染性能的优化能够针对渲染过程当中的每一步来作,下面列出了google开发者论坛中提到的具体优化措施优化

  • 优化JS执行(JS)动画

  • 缩小样式计算的范围并下降其复杂性(style)

  • 避免大型、复杂的布局和布局抖动(layout、paint)

  • 使用输入处理程序去除抖动(layout、paint)

  • 坚持仅合成器的属性和管理层技术(composite)

  • 简化绘制的复制度、减少绘制区域(paint、composite)

层的优化

上面加粗的两个优化手段能够总结为层的优化,也就是开启GPU加速。这里咱们先假设一个场景,在一个页面中存在两个水平排列的元素一、2,他们分别位于左右两端,咱们要作的是将1移动到2的位置。对此最简单的方案是设置position并改变right或left的值。第二种方式是使用transform:translateX,并加上 will-change: transform/transform: translate(0)将它提高为单独的层,这种方案的好处在于启用了GPU加速。

这样看来只要应用GPU加速就能很好的解决动画优化问题,可是实际应用中的页面每每要比上面所描述的场景复杂的多。就拿饿了么的H5页面来讲,它除了有轮播外还涉及到页面滚动、点击展开,返回顶部等。当开启layer borders查看时会发现滑动的过程当中若是轮播图正在播放整个页面就会建立不少没必要要的层。另外开启Paint flashing查看重绘状况时也会发现每次轮播图播放都会致使整个页面重绘。这种问题在低端手机上可能会形成闪屏,须要额外注意。解决方案其实前面也提到过就是要将作动画的元素提高为一个单独的层(合成层)

以前说过动画的问题有两种解决方案,若是这两个方案结合在一块儿又会怎么样呢,也就是将position和will-change写在同一个元素上,这在实际写代码的过程当中是很容易碰到的。由此引出了新的问题,浮动元素(渲染层)和合成层的关系。对此我我的作了下总结:若合成层的z-index值小于下方兄弟元素,且他们有重叠,则下方兄弟元素也会被提高为合成层。

上图是饿了么页面的简化场景,区域1是可滑动动画区,使用flex布局实现,区域2是店铺列表,区域3是店铺信息,这两个区域都添加了position:relative。

这种实现方式没有指定浮动层的z-index值,所以在区域1进行滑动的时候,下方的每一个店铺列表都会被提高为单独的层。在为区域1设置position:relative和z-index:1(高于下层)以后下方的层就不会再被提高了(此时下层z-index未设置)。

层爆炸

注意图中标记区域,当点击展开/收起活动的小三角的时候会有一个旋转180度的交互效果,相信你们对此都很熟悉。这种效果实现起来也很简单,设置transition过渡属性就能完成。

在实际操做的时候查看层级会发现,每一个商店列表都被提高成单独的层且有不少嵌套。形成此问题的缘由和前面的案例相似,主要仍是没有给拥有过渡动画效果的小三角元素添加z-index值,解决方案一样是为动画元素设置z-inde。

这一系列的问题涉及到一个概念:层压缩,即若是多个渲染层同一个合成层重叠时候,这些渲染层会被压缩到一个GraphicsLayer中。

另外若是元素有动画/过渡效果,可未指定层级顺序高于下方浮动层,此时会假定下方的浮动层在动画期间会受影响,从而没法被压缩。

减小绘制区域

通常咱们编写页面的时候都会为头部和底部设置固定浮动,这涉及到减小绘制区域的优化策略。在没有设置浮动的状况下,每次页面滚动头部和底部就会被从新渲染,解决方案是设置浮动后将这些浮动的头部和底部提高为单独的层。

相关文章
相关标签/搜索