作者:余浩斐(浩斐)
拥有 6.8 亿人口的东南亚市场正在经历爆发式增长,作为东南亚领先的电商平台和阿里巴巴全球化战略的重要增长引擎,Lazada 已成长为当地领先和增长快速的旗舰电子商务平台,推动了东南亚数字经济基础设施的进步,目前Lazada业务在东南亚印尼、菲律宾、泰国、马来西亚、新加坡和越南等六国运营,员工来自全世界50个不同的国家和地区,实现了各国业务的同步推进,在买家和商家数量上继续保持了强劲的持续增长态势。
数据显示 D11 当天有超过800,000品牌和商家参与,Lazada越南首小时同比去年销售额翻番,Lazada新加坡首小时销售额较平日增长10倍!这些增量数字的背后,离不开Lazada各个团队、商家、品牌和用户的共同努力,其中无线技术团队坚持数据驱动、技术赋能,高效稳定的支撑D11期间的多方购物场景,同时在启动耗时、会场渲染、包体积和主链路体验方面都有显著的进步。
去年我们已经进行了大量布局优化等基本技术策略,在2021年我们将优化场景在一步下沉到更加细化的领域,结合“页面合并和任务重编”对应用启动进行了大幅优化,开展了针对低端机所进行的“全链路路由动态预请求”,为了进一步增强数据复用性也开展了“购物车增量更新”和“下单页首屏预判”......链接针对Lazada 启动、首页、PDP、Cart、Checkout等基础链路核心场景所进行的多方面体验优化,形成了链路级别的用户体验再升级,量变的过程也势必将引发质变的结果,最终提升整体的业务转化效率.
启动任务编排&懒加载
应用启动作为用户进入首页的第一必经环节,启动性能带给用户的体感很大程度决定了用户接下来是否选择继续留存,因此对App的启动优化我们一直是持续精进,同时随着业务的不断复杂以及可优化空间的逐渐压缩,优化遇到的挑战也是非常大,也经历了不断的探索。
应用启动阶段大大小小有几十个任务,这些任务需要主线程进行调度并行,同时主线程自身也需要执行一些必须执行的任务,任务之间还有逻辑上的依赖和锁依赖,因此我们将任务分成若干个组,组内并行可以达到最大并发效果,组间串行解决依赖问题,组和组之间由主线程进行同步调度,在任务并发和依赖之间达到平衡的调度框架。
启动任务优化的宗旨就是要让组内任务并行更快,减少主线程的占用,让主线程能够更快地调度下一组, 因此每一组的启动时长由组内的最长耗时任务决定,通过对任务进行编排,让有逻辑依赖和锁依赖的任务尽量不分在相同的组,基于这个原则我们通过systrace等工具对短板任务和锁进行了进一步的梳理并进行了针对性优化:
- 对耗时过长任务进一步进行拆分,缩短任务在单组中的耗时;
- 尽量在保持依赖关系的前提下对下列使用loadLibrary锁的任务进行分散编排,最大程度减少锁竞争;
- 对耗时任务进行优化,对不必要在系统启动阶段使用的任务在可交互后初始化。
通过以上的优化策略,本期优化启动时间相对去年双11有较大幅度的改善,随着优化的进一步进展,后续的启动优化,需要有更多的积少成多的决心和耐心,不断地引入新的工具、新的思想,结合线上数据的完善更加精确地进行治理和优化。
启动页合并
在启动任务编排的基础上,我们在启动过程中可以观察到,一次完整的启动过程,APP会经历Application的创建,闪屏页Activity的创建,最后才是用户真正看到的首页Activity,即LazadaApplication.onCreate() -> EnterActivity.onCreate() -> MainTabActivity.onCreate()
如果将这两个页面合并为一个Activity,用户启动即首页。在Activity内部通过View的转换完成上述闪屏页到首页Activity的切换,那么用户就会减少一次Activity的创建及这个过程中相应的Binder调用,从而更快的展现首页内容
最后,新的启动流程就由原来的三步演变为LazadaApplication.onCreate() -> EnterActivity.onCreate() 两步,在EnterActivity内部,当启动任务初始化完成时,通过contentView的转换将闪屏页替换为首页内容,从而提升启动速度,借助实验采样节约了250ms左右的启动时间。
全链路路由动态预请求
如何针对低端机弱网络进行定向性分析,并形成链路式而非单点式的优化策略是我们2021年新的发力点,全链路预加载项目是在全局资源智能调度上的一个尝试,通过定制更加灵活的调度策略来实现最大程度的利用系统空闲资源,我们启动该项目的核心目标也是:通过灵活的前置任务调度,实现全链路的秒开体验。
- 导航预加载 利用导航过程中的时间gap,提前加载下个页面的资源。这部分节省的时间 不仅包含页面切换耗时100ms-200ms,可能也包含页面初始化的时间100ms-200ms(个别页面已经实现了“初始化和网络加载同步化”)。
- 闲时预加载 智能调度:基于用户行为预测,利用当前页面空闲时间,提前加载下个预测页面的资源;强制调度:无行为分析,利用当前页面空闲时间,提前加载下个配置页面的资源。
通过定义一套标准化解析调度框架不仅支持远程配置的解析映射同时也支持本地任务的远程调度,最终在业务无侵入的特性下实现全链路的路由请求。
通过前置请求加速网络请求过程 PDP场景优化110ms, Cart(from PDP)场景优化230ms, 下单页优化110ms,用户核心购物链路预计节省450ms。
购物车异步刷新增量更新
不同于页面打开场景:在二刷场景中端侧的视图构建和渲染基本不会有时间消耗,Android和IOS都是有成熟的View复用机制,目前桎梏二刷用户体验的核心问题在于网络耗时过程,从监控数据也能看出接口的Api-totalTime耗时平均就需要1200ms左右。引发二刷网络耗时的原因有两个:
- 全量更新导致服务端必须在update中进行全页面元素的重新计算(Trade基于集团奥创中间件协议);
- 全量数据返回引发数据的传输和解析过程都会更加耗时。
因此初步的解决方式是:针对二刷场景服务端仅返回需要增量更新的数据元素,客户端借助上次数据进行本地增量合并更新,这样子即降低了服务端的请求耗时,同时也能降低数据量大小从而减少传输和解析耗时(当然多了一次对比过程耗时,基本可以忽律不计)
整体的方案概述为:借助客户端对上次页面数据的复用能力,通过针对购物车异步操作进行增量更新,降低服务端请求的计算范围和数据包体积,并最终达到降低网络耗时的目的。第一期我们主要针对"商品店铺的选择反选、商品数量的增减"操作进行定向优化,将计算范围缩小到"已选中商品的店铺元素、操作的商品店铺元素、特殊固定元素"
效果对比视频,请查看:Lazada D11 体验升级技术实践
数据取自中国深圳, 线上环境
- 借助AB实验对比:ServerRt优化57.52%,SKU查询量优化80.69,QPM优化217.75%
- 客户端大盘数据TotalTime从1100ms->750ms提升31.82%,通过细分维度可以观察到Item引发的刷新动作有明显降低其他的基本稳定,符合预期;
购物车弱化刷新频次
Android购物车目前每次重新进入都会引发刷新操作,结合购物车线上性能数据:用户每次进入基本要等待1.029.81ms,64.5%的用户可以在1s内完成加载,这就导致一个问题“部分加购的用户可能重回购物车时也会引发刷新”,譬如这个用户故事:用户在Cart Just For You模块看到了一个感兴趣的商品并点击进入PDP, 在PDP浏览后(无任何加购操作)返回Cart,Cart重刷会导致之前正在浏览的数据被重新覆盖。因此我们启动了该项目主要目的是:在兼顾购物车正常刷新的前提下,降低购物车的刷新频次。
Android侧仅开放“重回购物车时刷新”,这是考虑到“大促场景下Android用户群体庞大,加购动作如果直接绑定Cart刷新行为可能引发流量压力”;同时,Android侧提供了“即时刷新购物车”的能力以便于特殊场景下的使用。
效果对比视频,请查看:Lazada D11 体验升级技术实践
数据取自中国深圳, 线上环境
- 重回场景下降低了55.45%的刷新请求,整体降低了35.28%的刷新请求, 推全后单日预计减少千万级冗余请求
下单页首屏预判
通过对年度同期数据的对比,我们发现相对于202004 Checkout Render接口耗时在860ms上下浮动,2021同期时间段已经上涨为1160ms上下增幅35%,鉴于Checkout日益增长的网络耗时,客户端推动了Checkout首屏渲染缓存项目,主要目的在于通过复用上级页面数据和本地缓存数据快速渲染页面首屏视图,降低用户在空白加载期间的等待焦灼感。
通过对线上数据的分析进入Checkout的路径主要来自PDP.70+%和Cart.20+%,结合这两种不同路径,根据数据的复用方式我们将可复用数据分为2类:
- 上一跳页面数据;譬如Cart选中的商品和店铺、PDP对应的店铺、商品和物流配送信息;
- 固定出现但数据变化的元素;譬如店铺物流配送(new)、包裹总价、支付方式、订单流水、订单总价等;
- 用户不经常变动的历史数据;譬如地址、优惠券输入组件等。
根据数据的存储形式我们可以分为4类:上一跳带入、文件缓存非加密、文件缓存加密(譬如地址信息)、自行构建的元素(店铺物流)。基于这样子推论,我们可以根据可复用数据将页面的大部分区域进行预测式的提前展示,并在网络数据回调后及时更新页面视图。
效果对比视频,请查看:Lazada D11 体验升级技术实践
- 通过进行AB实验验证后,只打开购物车到下单页的优化路径,优化了大约125ms左右;只打开PDP到下单页单的优化路径,优化了大约390ms左右;全开桶提升528ms。
下单页合并请求
测试团队反馈通过不同路径进入Checkout的场景中(同样是单商品场景),用户体感耗时会有一定的差别,经过详细比对相差将近400ms,因此将此问题反馈给端侧团队进行排查。从端侧梳理的结果来看,目前两种路径的主要区别在于Cart_Submit请求的时间,Cart的跳转是在收到服务端接口回调后才触发的. 对比mtop.lazada.carts.ultron.submit的totalTime时长400ms,正好是两种路径时长的差值。
通过进一步分析,Cart-->Checkout路径中,客户端只是将服务端返回的buyParams参数透传给给了mtop.lazada.buy.renderorder接口,没有做任何加工处理。但是由于端侧两次请求的同步性,就导致了用户体验上的差异。东南亚的网络特性,我们从上图中也就看到mtop.lazada.carts.ultron.submit的ServerRT只需要不到100ms,但是来回传输耗时缺需要200-300ms,如果只看serverrt可能觉得两个同步请求差不了太多,但是考虑到网络传输耗时那么对用户体感的差异就会很大。
基于后置合并,我们协同服务端提供一个基于 mtop.lazada.carts.ultron.submit 和 mtop.lazada.buy.renderorder 的合并请求接口,在不修改原接口内部逻辑的基础上,服务端封装一个上层接口开放给端侧使用。请求的发起节点调整到进入下单页面,也就是点击下单按钮后直接进入下单页面&将Cart选中数据透传过去,并在下单页面进行请求;调整后,Cart.Submit承载的失败场景将直接挂在Checkout页面。
- 借助AB实验分析经过优化后,路由响应耗时(从用户点击开始计时到下单页发起页面请求)434.48ms->64.33ms提升85.19%,网络总耗时(从用户点击开始计时到下单页收到请求返回数据)1308.66ms->965ms提升26.26%;
收银台前置请求&提前渲染
二次收银台native之后,虽然在性能上相对weex有比较大的提升但还稍逊于竞品,通过对现有加载流程分析后,我们发现当前上游进入收银台的流程属于串行,分段耗时如下:
优化的核心思想:后事前移,串行改并行。mtop本身不依赖Activity,可以直接放到路由层去开始请求,同时我们渲染的流程实际上是包含了加载布局的时间(inflate)加绘制流程时间(即measure+layout+draw),通过本地自测可以看到收银台支付列表的一个布局,inflate一般会耗时20ms左右而一般需要5个这样的布局才能基本覆盖80%的页面大概耗时100ms(低端机可能会更多),那么这个渲染流程实际上也是可以提前加载的。
- 借助AB实验分析,优化带来了100ms的性能提升(701.62ms->604.74ms)提高14.29%
总结和展望
- 借助AB实验平台评估, 推全后全开优化组相对原始组PR预计带来71,203DAB, 7051DNB;
- 对于应用启动耗时:同比去年D11 Android启动整体耗时提升23%,iOS启动整体耗时提升20%;
- 对于页面渲染耗时指标:同比去年D11Android全链路耗时提升37%,iOS全链路耗时提升优化34%;
- 对于页面二刷场景耗时指标:购物车数据TotalTime提升31.82%,全量后ServerRt预计优化57.52%;
- 对于降低冗余请求指标:购物车重回场景下降低了55.45%的刷新请求,整体降低了35.28%的刷新请求, 推全后单日预计减少千万级冗余请求。
体验优化项目将会是伴随着业务成长的一项持续动作,Lazada也将持续关注细节场景,不断的发现问题、定位问题、解决问题并总结经验。明天,我们将会继续分享深度解析文章《Lazada 容器深度优化之旅》,敬请期待。
最后感谢参与项目一起奋斗的所有小伙伴~
我们招聘啦!
简历投至方式:haofei.yu@lazada.com
Lazada创立于2012年,在东南亚印度尼西亚、马来西亚、菲律宾、新加坡、泰国和越南六国拥有超过8000万活跃消费者,且拥有该地区竞争力优势明显的物流和支付网络。 作为阿里巴巴东南亚旗舰电商平台,在利用阿里巴巴先进成熟的产品技术快速提升海外本地电商能力并帮助阿里生态迅速发展海外业务的同时,我们基于阿里已有平台抽取出一套国际化的全链路系统,从无线手机端到交易链路,从商家业务到大数据和推荐,打造全新的端到端国际电商操作系统。
在这里你不仅有机会了解商品、交易、会员、营销等核心平台,而且有机会接受极具前瞻性的海外电商业务的挑战,并且需要针对多国场景进行业务抽象和平台剥离,任务的新颖性和挑战性都是前所未有的。我们在招的岗位包含产品、架构师、开发、测试、前端等多种机会,业务涉及电商端到端的所有环节,只要你自信,有能力、有激情,一定可以找到吸引自己的新挑战。加入Lazada,和我们一起激荡东南亚市场,共创国际化电商!
关注【阿里巴巴移动技术】微信公众号,每周 3 篇移动技术实践&干货给你思考!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。