h5渲染性能一瞥


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

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

获取嘉宾演讲视频及PPT:http://suo.im/4SkvOx

摘要

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

H5 VS Native

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

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

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

渲染

一般一次渲染都会经过JavaScript > style > layout > paint > compoasite这样的过程。在做动画的时候可以进行优化,将layout和paint省略掉,这其实是将做动画的元素提升为一个单独的层。

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

  • 优化JS执行(JS)

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

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

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

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

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

层的优化

上面加粗的两个优化手段可以总结为层的优化,也就是开启GPU加速。这里我们先假设一个场景,在一个页面中存在两个水平排列的元素1、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中。

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

减少绘制区域

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Egret H5 是一种基于HTML5的游戏开发引擎,其渲染流程可以简单描述为以下几个步骤: 1. 准备阶段:在渲染之前,需要完成游戏资源的加载和初始化工作。这包括图片、声音、动画和其他资源的加载,以及游戏场景和界面的初始化设置。 2. 创建场景:Egret H5通过场景与层的概念来管理游戏的元素。在创建场景时,会设置游戏画布的大小和位置,同时创建不同的层,用于容纳游戏中的不同元素。 3. 加载场景元素:在此阶段,需要加载游戏的场景元素,如角色、背景、道具等。这些元素可以是静态的图片,也可以是可交互的动画。加载完成后,这些元素将被添加到对应的场景层中。 4. 渲染循环:Egret H5通过渲染循环不断更新画面,实现动态效果。渲染循环是一个不断循环的过程,每一帧都会执行各种更新和渲染操作。 5. 更新元素状态:在每个渲染循环中,需要更新游戏中各个元素的状态,包括位置、旋转、缩放等。这些更新会基于各种因素,如用户输入、游戏逻辑等。 6. 碰撞检测:在游戏中,需要检测元素之间的碰撞,以便触发相应的事件。Egret H5通过检测元素的位置和形状来实现碰撞检测,一旦发生碰撞,会触发相应的逻辑处理。 7. 渲染画面:在每一帧更新之后,需要将更新后的画面渲染到屏幕上。Egret H5通过调用浏览器的Canvas或WebGL API来实现画面的渲染工作。 总的来说,Egret H5的渲染流程包括准备阶段、场景创建、元素加载、渲染循环、更新状态、碰撞检测和画面渲染。通过这些流程,Egret H5能够实现丰富多样的交互效果,让开发者能够灵活地创建优秀的HTML5游戏。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值