淘宝页面首帧优化的经验和心得

简介: 淘宝页面首帧优化的经验和心得

最近做了一些移动端页面的首帧优化的工作,有很多心得和感受,其中有很多共性的东西,总结成一篇文章希望可以帮助到更多业务,也希望引起读者一起讨论。



为何要做首帧优化

作为程序匠人,一直在努力追求做一款好的产品,打磨各个细节,做好用户体验,而首帧是用户接触到产品的第一个页面,是体验的重中之重。也正因是产品的第一个页面,转化率接近100%,从ROI的角度来说,做好首帧优化也是一个很划算的deal。


做好首帧优化,至少可以带来以下好处:

  1. 建立用户好感度:良好的第一印象,提升品牌形象
  2. 提升业务转化率:提升业务曝光率、点击率、带来更好的业务结果
  3. 更小的资源消耗、减少成本:更长的首帧启动时间意味着更多的资源消耗,更多的成本投入。优化首帧可以减少一些不必要的资源开销和损耗,节省技术成本。


首帧口径和衡量标准


 口径


做优化前我们需要先想想,用户对首帧体验预期是怎样的?首帧定义是什么,起始范围是什么。不同的口径会影响我们的指标,设计方案,工作量。定义了口径之后,我们可以确定优化事项范围以及边界。


Loading图:

即开始出现loading、展现灰底图或是页面框架图,如果这页面展示也比较久的话,则说明用户交互出现卡顿、假死,迟迟没收到反馈,用户交互被阻塞,属于严重影响用户体验的行为。所以建议在展示骨架图之前,除了framework以外,不要有io、网络等耗时的前置依赖,也不需要有中转页的行为逻辑。

image.png

内容主体呈现:

即页面大部分的内容已经渲染出来,用户可以得到足够的信息,这是一个比较符合用户体感的口径,大多数业务选取的就是这个口径。不过不同业务对于“大部分”,“主体”的定义有所不同,业务可以结合自身需求进行合理选择:

  • 对于“主体”定义:如头图、标题、相机取景器、
  • 对于“大部分”定义:如按照展示“面积”计算的,完整度80%、90%、100%(有一些分页加载策略的业务场景)

image.png


页面可交互:

这个阶段表示页面已经完全渲染完成,并且用户可以进一步交互,如点赞、分享、收藏、加购等行为。


 衡量标准


绝对耗时:

指定口径下的绝对耗时时长,单位一般是ms,多是用于单机线下的验证和比较,不同机型之间、不同场景下的差异较大,如高端机与低端机之间的差别可以相差好几倍,如要反应样本的整体性,多用分位值或者秒开率来衡量。


分位值/秒开率:

  • 多用于线上观测,反应样本的整体性和趋势,长尾数据、极端case不容易被忽略
  • 应该让P90P95分位值,接近于中位数,让整体样本的差异性小一些


取值标准:

  • 按照经验值
  • 绝对耗时<500ms,一般情况下页面切换动画300ms,所以页面首帧500ms以内渲染完成,能够有一个较好的体验,google官方也建议页面尽可能在500ms以内完成冷启动。
  • 秒开率>95%+,即95分位<=1000ms

  • 参考头部竞品
  • 能窥探出同等业务复杂度下,普遍用户能接受的一个范围
  • 通过屏幕录制方式可获取

  • 标准也并不是一成不变的,随着硬件性能不断提升、framework不断优化、亦或是业务形态的变化,而不断调整。


如何分析排查性能问题(以Android为例)


 了解现状


首先要掌握自身产品以及行业竞品的首帧数据,了解在行业中的一个排名情况,再决策是否要进一步做优化,做到什么样的程度。为了保证自身和竞品采用的同一种口径获取首帧耗时,我们这边采用了录屏的方式。


录屏分析方案:在同一台手机上使用特定帧率录屏(如30fps,即1帧33ms),再通过数帧数的方式来计算出首帧耗时的时间,录屏的越高越精确。

image.png


自动化脚本方案:

通过自动化录屏脚本工具、使用模拟点击 + OCR文字识别/图像识别的方案,识别首/尾帧、进而自动化生成耗时的中位数、平均值。

image.png


 了解原理


在分析问题之前,我们要搞清楚系统是如何将首帧绘制在屏幕上的,了解了这些我们才能针对性的分析问题。



 使用性能分析工具


  1. 官方工具:

从代码、资源等细粒度的维度(如方法级别、事件级别),来定量分析程序对CPU、内存、网络IO等核心计算资源的消耗情况,可以比较完整、全面的分析启动过程,但这种方式得到的数据比较细碎、散点,需要经过一定的归纳、合并才能得到一个具体可实施的方案。

  • TraceView:Instrumentation 模式下采用 AddListener 的方式注册 MethodError、MethodExited、MethodUnwind 的回调来采集方法起止时间;Sampling 模式下使用一个 SamplingThread 定时主权线程堆栈,通过对此的堆栈对比近似确定函数的进入和退出时间;虽然是官方提供的工具,但两种模式本身都存在比较大的性能损耗,可能带偏优化方向。
  • CPU Profiler:整体通过 JVM Agent 实现,具有完成方法调用栈输出,且支持 Java、C/C++方法的耗时检测,上手比较简单,但其同样存在性能损耗较大的问题,且一般仅用于 debug 包,release 包需要额外添加 debuggable 的配置。
  • Systrace:基于 Android 系统层的 Atrace 实现,Atrace 又基于 Linux kernal 层的 ftrace 实现,ftrace 在内核中通过函数插桩获取耗时;其自身性能损耗比较低、数据源丰富且具有较好的可视化页面,但其默认监控点较少,在 APP 自有代码中的监控点需要手动加入,比较麻烦。


  1. 二方/三方工具:

如果我们的页面是通过第二/三方的页面框架所构建,如weex/rn/flutter等框架。我们可以通过第二方框架提供的性能分析工具、插件去分析和归因。

  1. 业务自定义工具:

有时为了弥补官方工具火焰图太细碎、难以聚类、需要花费更多时间去分析和追踪,我们可以根据业务视角、使用自定义的业务阶段/流程,去粗粒度的去分析各个阶段的耗时。

  • 埋点/日志工具:核心链路节点performance日志,如:页面视图创建、网络耗时、数据处理、渲染
  • 切面/插装代码工具:面向常用对象/事务/流程,对业务无侵入式的观测和统计


常见的优化方案和策略


分析完原因后,我们需要对不同原因给出优化方案,首帧优化的核心思想用一句话总结是:在尽可能在短的时间里准备好首帧渲染所需要最小的资源模型。围绕“最短时间”和“最小的模型”两个中心思想下,总结了一些常见的优化策略:


 预加载/缓存策略


在前置页面的合理时机(一般是闲时)提前获取数据、下载资源,并解析,然后缓存到内存或者磁盘里,以便后置页面快速读取数据和资源。


这个策略可能带来以下副作用:

  • 提前获取的数据可能会引发服务端qps暴增,带来额外资源开销,和影响稳定性。
  • 如果页面点击率不高的话,缓存命中率会比较低,造成资源浪费的问题。
  • 可能会造成前置页面的性能受损。
  • 这个策略结合特定人群一起使用会更好一些。


 延迟初始化(懒加载)


与首帧无关的代码逻辑、资源可以在首帧渲染后进行初始化,具体的初始化时机可以在使用时再初始化,如某些二级页面的创建、多余tab的创建等。


 并行处理&异步化


并行处理:充分利用多核CPU,通过多线程并行处理耗时的任务,提升CPU的负荷。如容器初始化和数据请求解析可以同时进行。


异步化:一些比较耗时、IO任务,不要占用宝贵的主线程资源。


 View渲染优化


Android里面ViewTree构建和渲染是比较耗时过程的,如下:

  • 将 xml 文件解析到内存中 XmlResourceParser 的 IO 过程;
  • 根据 XmlResourceParser 的 Tag name 获取 Class 的 Java 反射过程;
  • 创建 View 实例,最终生成 View 树;
  • View渲染:layout、measure、draw

优化方案:

  • 层级优化/布局优化 (merge嵌套),减少布局层级,减少递归深度
  • 使用ViewStub,延迟按需inflate,降低inflate耗时
  • x2c:xml转code构建
  • 异步inflate,异步ui构建


image.png

 数据借用


为了加快数据获取,我们可以从前一个页面借用一部分数据过来将主体内容做填充,随后再用真实数据刷新。这个方案多适用于列表进入详情的场景。


这里的数据不仅包含文字和图片,也可以延伸到媒体播放器、camera取景器等其他一些文件流、数据流,甚至可以是widget组件(共享元素动画)。

image.png

 分块渲染


如果页面元素比较多,数据量比较大,一次性请求加载的时间比较长,这个时候我们可以通过分块的方式,将大页面拆成若干个小页面模块、将服务端接口拆成若干个小接口,各个页面模块独立渲染。可以有效降低服务端RT耗时,以及页面渲染耗时。

image.png


 骨架图优化


使用骨架图作为打底图和纯白底图相比,有了布局样式等信息,更加接近于首帧的效果,正式数据刷新时,页面也不会出现明显刷新,体验比较好。

image.png

线上验收


线下的优化,并不意味着线上真实用户也能同步看到优化的结果,因为业务路径的差异、机型的差异,你线下的优化可能不具备普遍性,所以需要线上真实结果的反馈。


  1. 较全面信息的数据大盘建立:

包含:版本、设备分、业务场景、机型、时间等尽可能多的数据维度的数据大盘,可以尽量还原优化or劣化的信息全貌,提供更多的归因信息。


  1. 分位值(数据聚合类别):

长尾数据、小众case往往容易被整体数据给覆盖,不足以引起重视,为了我们应该分别分析中位数、分位数。


  1. AB实验:

这样做不仅能控制变量确保优化项的严格有效,还能借此来观察性能优化所带来的业务指标收益,这些都可以作为规划后续启动优化方向的参考指导。



防劣化


人无完人,人都会失误犯错,绝对不能把系统性能交给某一个人身上,一个人犯错概率高,一群人都犯错的概率低,应该交给一群人共同协作的机制和流程。


防劣化相比于优化是更能持久有益的,所以更应该在较早期建立起防劣化机制:

  • 准入机制:
  • 禁止在启动核心阶段添加代码,一切代码添加需要走审查流程,启动阶段包含:
    Windvane.execute,
    Activity.onCreate,
    Fragment.onCreate/onCreateView
  • 审查机制:提审/测试/核准/灰度/上线

  • 遵循严格规范
  • 代码约束
  • 框架约束
  • 检查工具
  • CR规范

  • 线上监控
  • 大盘监控:趋势分析
  • 分阶段监控:归因分析
  • 监控告警:及时止损


结语


 持续迭代


首帧优化并非一蹴而就,而是一个需要持续迭代与打磨的过程,在初期阶段优化空间相对较大,只需要投入一些不多的资源,即可看到较大的收益,但随着优化不断深入,到了中期阶段,就需要有相当程度的投入,去攻坚各个难点,聚少成多,才能看到收益。后期随着业务越来越复杂,分支越来越多,要做防劣化工作,同时也要和业务一起做好精细化管理,将有限的资源,分配给最优先级的业务,要做好ab实验管控、优先级管理、及时下线等。

 做好复杂度管理


为了将达到最优的启动速度,我们运用了各式各样的策略,将时间和空间塞得满满的,但是这改变了原来的常规流程,带来了额外代码复杂度提升,比如预加载策略,后面维护同学需要考虑,预加载失败以及成功两种情况,又或者是缓存策略,后面维护的同学需要考虑缓存命中、不命中的情况,如果不断使用if堆积代码,那代码最终将无法维护。所以我们需要通过框架来管理复杂度,尽量让业务层无感知。比如数据中间层,业务无需关心数据是否来自缓存还是实时请求,拿来使用即可。


 全局意识


通常我们以启动速度来衡量启动性能。为了提升启动速度,我们可能会把一些原本在启动阶段执行的任务进行延后或者按需,这种方式能够有效优化启动速度,但同时也可能损害后续的使用体验。比如,如果将某个启动阶段的后台任务延后到后续使用时,如果首次使用是在主线程,则可能会造成使用卡顿。因此,我们在关注启动性能的同时,也需要关注其他可能影响的指标。性能上我们需要有一个能体现全局性能的宏观指标,以防止局部最优效应。


参考资料



团队介绍


我们是淘天集团-内容技术团队,专注于推动淘宝内容生态和电商体验的深度融合。我们致力于为全球用户提供丰富、多样性、高品质的购物内容体验,旨在通过技术创新,更好地连接用户和商品,以提升用户的购物满意度和平台的商业价值。通过尖端技术提升内容创作、分发与消费的效率,赋能内容创作者、商家与消费者,构建一个繁荣、健康、可持续发展的内容生态圈。


相关文章
|
7月前
|
测试技术 开发工具 UED
什么是农场游戏系统开发规则玩法/详细需求/案例详情/源码项目
明确定义游戏概念和目标**: - 确定农场游戏系统的主题和核心玩法,明确目标用户群体,并设定明确的游戏目标和规则。
|
7月前
|
安全 区块链
区块链农场游戏系统开发运营版/玩法详情/规则方案/案例设计/项目源码
Developing a blockchain farm game system is an interesting and challenging task. Here is a design solution that can help you get started developing such a system
|
5月前
|
人工智能 运维
学习若依的好地方,若依社区,好的运维,社区,也可以运营自己的社区,可以用于投放软件产品和海报展示,有空可以研究怎样运行社区,好的标题设计
学习若依的好地方,若依社区,好的运维,社区,也可以运营自己的社区,可以用于投放软件产品和海报展示,有空可以研究怎样运行社区,好的标题设计
|
JavaScript 数据安全/隐私保护
某招聘站新版zptoken玩法分析第三弹
某招聘站新版zptoken玩法分析第三弹
289 1
|
存储 人工智能 算法
AI提效:基于手淘首页截图进行请求定位能力实现
AI提效:基于手淘首页截图进行请求定位能力实现
|
搜索推荐 定位技术 UED
淘宝用户体验分析方法论(上)
淘宝用户体验分析方法论(上)
1535 0
|
自然语言处理 数据挖掘 数据建模
淘宝用户体验分析方法论(下)
淘宝用户体验分析方法论(下)
717 0
|
安全 Python
盲盒商城系统模型开发技术方案源代码详情
blind_boxes = get_blind_boxes() return render_template(&#39;index.html&#39;, blind_boxes=blind_boxes) else: return redirect(url_for(&#39;login&#39;))
|
运维 监控 小程序
淘宝小游戏背后的质量保障方案
2022年4月,淘宝开启了小程序游戏项目,旨在从互动公域和店铺私域引入了大量的三方游戏服务商入淘 ,初步构建淘宝游戏的三方生态。对于开放质量团队来说,“游戏生态管控 & 游戏容器测试”是一个新的命题。
961 1
淘宝小游戏背后的质量保障方案
|
安全 区块链
DAPP游戏拆分互助系统开发玩法规则/案例分析/项目方案/源码说明
每一个区块中储存有一定的数据或信息,它们根据各自诞生的时间先后顺序连接成链条。所形成的这个链条是可以被保存在所有的服务器中。也就是说,只要整个体系中有任意一台服务器可以正常运作,整条区块链就是安全的。
下一篇
DataWorks