写点什么

Lazada D11 体验升级技术实践

  • 2022 年 2 月 08 日
  • 本文字数:5395 字

    阅读完需:约 18 分钟

Lazada D11 体验升级技术实践


作者:余浩斐(浩斐)


拥有 6.8 亿人口的东南亚市场正在经历爆发式增长,作为东南亚领先的电商平台和阿里巴巴全球化战略的重要增长引擎,Lazada 已成长为当地领先和增长快速的旗舰电子商务平台,推动了东南亚数字经济基础设施的进步,目前 Lazada 业务在东南亚印尼、菲律宾、泰国、马来西亚、新加坡和越南等六国运营,员工来自全世界 50 个不同的国家和地区,实现了各国业务的同步推进,在买家和商家数量上继续保持了强劲的持续增长态势。


数据显示 D11 当天有超过 800,000 品牌和商家参与,Lazada 越南首小时同比去年销售额翻番,Lazada 新加坡首小时销售额较平日增长 10 倍!这些增量数字的背后,离不开 Lazada 各个团队、商家、品牌和用户的共同努力,其中无线技术团队坚持数据驱动、技术赋能,高效稳定的支撑 D11 期间的多方购物场景,同时在启动耗时、会场渲染、包体积和主链路体验方面都有显著的进步


去年我们已经进行了大量布局优化等基本技术策略,在 2021 年我们将优化场景在一步下沉到更加细化的领域,结合“页面合并和任务重编”对应用启动进行了大幅优化,开展了针对低端机所进行的“全链路路由动态预请求”,为了进一步增强数据复用性也开展了“购物车增量更新”和“下单页首屏预判”......链接针对 Lazada 启动、首页、PDP、Cart、Checkout 等基础链路核心场景所进行的多方面体验优化,形成了链路级别的用户体验再升级,量变的过程也势必将引发质变的结果,最终提升整体的业务转化效率.

启动任务编排 &懒加载

应用启动作为用户进入首页的第一必经环节,启动性能带给用户的体感很大程度决定了用户接下来是否选择继续留存,因此对 App 的启动优化我们一直是持续精进,同时随着业务的不断复杂以及可优化空间的逐渐压缩,优化遇到的挑战也是非常大,也经历了不断的探索。


应用启动阶段大大小小有几十个任务,这些任务需要主线程进行调度并行,同时主线程自身也需要执行一些必须执行的任务,任务之间还有逻辑上的依赖和锁依赖,因此我们将任务分成若干个组,组内并行可以达到最大并发效果,组间串行解决依赖问题,组和组之间由主线程进行同步调度,在任务并发和依赖之间达到平衡的调度框架。


启动任务优化的宗旨就是要让组内任务并行更快,减少主线程的占用,让主线程能够更快地调度下一组, 因此每一组的启动时长由组内的最长耗时任务决定,通过对任务进行编排,让有逻辑依赖和锁依赖的任务尽量不分在相同的组,基于这个原则我们通过 systrace 等工具对短板任务和锁进行了进一步的梳理并进行了针对性优化:


  1. 对耗时过长任务进一步进行拆分,缩短任务在单组中的耗时;

  2. 尽量在保持依赖关系的前提下对下列使用 loadLibrary 锁的任务进行分散编排,最大程度减少锁竞争;

  3. 对耗时任务进行优化,对不必要在系统启动阶段使用的任务在可交互后初始化。



通过以上的优化策略,本期优化启动时间相对去年双 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 左右。引发二刷网络耗时的原因有两个:


  1. 全量更新导致服务端必须在 update 中进行全页面元素的重新计算(Trade 基于集团奥创中间件协议);

  2. 全量数据返回引发数据的传输和解析过程都会更加耗时。


因此初步的解决方式是:针对二刷场景服务端仅返回需要增量更新的数据元素,客户端借助上次数据进行本地增量合并更新,这样子即降低了服务端的请求耗时,同时也能降低数据量大小从而减少传输和解析耗时(当然多了一次对比过程耗时,基本可以忽律不计)



整体的方案概述为:借助客户端对上次页面数据的复用能力,通过针对购物车异步操作进行增量更新,降低服务端请求的计算范围和数据包体积,并最终达到降低网络耗时的目的。第一期我们主要针对"商品店铺的选择反选、商品数量的增减"操作进行定向优化,将计算范围缩小到"已选中商品的店铺元素、操作的商品店铺元素、特殊固定元素"


效果对比视频,请查看: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 类:


  1. 上一跳页面数据;譬如 Cart 选中的商品和店铺、PDP 对应的店铺、商品和物流配送信息;

  2. 固定出现但数据变化的元素;譬如店铺物流配送(new)、包裹总价、支付方式、订单流水、订单总价等;

  3. 用户不经常变动的历史数据;譬如地址、优惠券输入组件等。


根据数据的存储形式我们可以分为 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 篇移动技术实践 &干货给你思考!

发布于: 刚刚阅读数: 2
用户头像

还未添加个人签名 2018.07.07 加入

阿里巴巴移动&终端技术官方账号。

评论

发布
暂无评论
Lazada D11 体验升级技术实践