大麦 Android 选座场景性能优化全解析

作者:于世雷(蓝彻)

通常情况下移动端APP由于受到设备性能所限一般较少有场景会处理超量数据,更多的是将复杂数据处理交付给服务端。本质上降低终端强数据处理是很有必要的,降低CPU使用率、减少内存抖动可以大幅提升APP使用体验。但是有时移动端也不得不处理超量数据,大麦选座就是这样一个强数据处理场景。

大麦 Android 选座场景性能优化全解析_第1张图片

那么选座场景具体面对的是怎样的超量数据呢? 上图是测试过程中使用的“奥运体育场”在大麦APP选座场景下绘制的UI,这个体育场包含了140+个看台,6万+个可售座位。我们需要建立数据模型来描述一个座位,它的基本要素会包含座位id、价格id、坐标、座位角度、座位位置、座位状态 等等。结合业务场景,在购票流程中的变与不变,我们可以将座位拆分成2套数据:

  1. 座位静态数据,它包含座位相对不变的部分,比如:座位id、价格id、坐标、座位角度、座位位置。
  2. 座位动态数据,即座位状态。它是变化最为频繁的,比如:用户下单时座位从可售状态变更为已售状态,用户取消时座位会从已售状态回归到可售状态。

假设我们使用XML来描述座位静态数据,使用JSON来描述座位动态数据,那么上述体育场6万+个座位对应的座位静态数据的文件大小为9.6M,座位动态数据的文件大小为1.8M。

想象一个场景:拥有6万+座位的超大体育场、偶像级歌手、售前几十万人关注、实时在线选座分钟级别售罄,静态数据的下载、动态数据的刷新、数据的解析与合成,不管对于服务端还是客户端都会是一场考验。当然选座场景自然是不会直接传输这样未经过压缩的数据,但这也从侧面说明了选座场景的数据量级,也就是说选座移动端必须要有能力快速、高效处理数以万计座位的解析、合成、渲染,以保障超级场馆实时在线抢票。

下面我总结了一些核心的提升选座场景用户体验和支撑超大场馆实时在线选座的方案和策略。

接口预加载策略

选座场景相对于其他大麦业务使用到了更多的网络接口及CDN下载,从SKU页进入一个选座页最少要使用5次网络请求才能最终合并成选座UI。

  • 渲染时:
    • Areainfo 网络接口 ,选座引导接口主要描述静态看台信息、静态文件cdn信息、开关信息等;
    • StaticSeat CDN下载,静态座位文件网络下载;
    • StaticSvg CDN下载,静态SVG文件网络下载;
    • DynamicInfo 网络接口,场次信息、票档实时信息;
    • Seatstatus 网络接口,座位实时状态信息。
  • 刷新时:
    • DynamicInfo 网络接口,场次信息、票档实时信息;
    • Seatstatus 网络接口,座位实时状态信息。
  • 选座中:
    • Precheck 网络接口,预锁座功能;
    • CalcPrice 网络接口,实时算价功能。

已知渲染需要至少使用到”渲染时“标出的5个请求,正如木桶效应一样,选座场景的页面加载时长取决于最后一个接口的返回,而通常接口RT取决于网络繁忙程度、网络状况、服务端处理能力等,客户端要做的是尽可能将这些网络请求分类、前置化处理,降低网络请求并发对CPU瞬时负载。

静态数据预加载

这里的静态主要主要是指"Areainfo"引导数据、”静态座位文件“、”静态SVG文件“的预加载策略,特点:他们通常在一个项目上线后很少发生变化,存储于CDN服务器中。静态数据预加载策略 就是在进入选座场景之前的链路如SKU(场次与票档选择页)进行闲时下载。这样可以前置 ”Areainfo“、”StaticSeat“、”StaticSvg“ 请求。

网络接口预加载

一般在Android App开发过程中我们会在Activity.onCreate()方法中触发网络请求,完成页面渲染。在测试的过程中我们发现像选座Activity这样的页面,从startActivity()方法调用到目标activity.onCreate()之间存在50-60ms的调度、创建时间。所以我们将”DynamicInfo“、”Seatstatus“前置到startActivity(),即启动选座场景时立即发出以上2个请求。

这样就可以将需要并发的请求打散、按其特点进行分类、分阶段执行。即可利用静态数据不易变更的特性进行前置下载,也兼顾到动态数据的实时性获取。

静态数据缓存

正如上述提及的

你可能感兴趣的:(android,性能优化)