阿里鬼道Weex在双11会场的大规模应用:业务支撑稳定性保障和秒开实战

Posted 中生代技术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了阿里鬼道Weex在双11会场的大规模应用:业务支撑稳定性保障和秒开实战相关的知识,希望对你有一定的参考价值。


鬼道(徐凯),就职于手机淘宝基础架构团队,曾为天猫Pad客户端TL并负责天猫Web前端架构。就职百度移动推广团队期间,负责开发android/ios推广SDK、统计SDK,及对应的Web管理站点。

前言

Native   开发的诸多亮点中,流畅体验和系统调用是最多被提及的。流畅体验体现在页面滚动/动画的流畅性,背后是更好的内存管理和更接近原生的性能;同时又是   Web   的痛点:资源首次下载、长页面内存溢出和滚动性能、动画性能、传统   web   性能(如JS执行效率)。Native   有丰富的系统调用能力,而   Web   痛点在于:W3C   标准太慢,有限的设备访问能力,API   兼容性问题较严重,如   Geolocation     Android   Webview   中可用性很差。

Web   开发同样有诸多亮点,其中最耀眼的当属发布能力和规模协作。Native   App   商店审核周期长(尤指   iOS);应用更新周期长,iOS   稍快大概能达到一周更新率   60%-80%,Android   同样的更新率要2周甚至更长。而   Web   在合适的缓存机制下一分钟可达到   99%+。浏览器内核   webkit   提供了相对一致的底层运行环境,html/js/css   控制页面的结构/行为/样式,uri   连接不同的页面,有了这些基础设施,大规模的业务复用和人与人的分工协作变得相对轻松。 同时今天阿里诸多客户端已经面临包大小接近临界值,大促活动页面(H5)体验较差等一系列问题。结合   Native     Web   技术亮点,同时又能解决阿里遇到的业务问题,这就是   Weex   诞生的客观环境。 2016.11.11,在   1754   张双11会场页面中(统计了天猫和淘宝),Weex   页面数为   1747   占比   99.6%。手淘   iOS/Android   分别有   83.5%/78.3%   版本(UV)启用了   Weex   会场,手猫   iOS/Android   分别为   91.7%/87.9%   版本(UV)。Weex   覆盖了包括主会场、分会场、分分会场、人群会场   等在内几乎所有的双11会场业务。 在这样的应用规模下,工作和目标是: 1.   业务支撑,支撑住双11需求,这是最基本的要求,详见下文“业务支撑”一节 2.   稳定性保障,Weex   引发的问题第一时间响应并处理,不留到双11当天,详见下文“稳定性数据”一节 3.   秒开实战,稳定当先力争高性能,双11正式主会场秒开率冲到   97%,所有会场秒开率冲到   93%,详见下文“秒开数据” 2016   双11会场的感受可查看原始录屏文件:   |     |     |     |     。录屏时主会场已经是预加载版本,其中   WIFI     4G   效果接近,2G   效果取决于数据的网络请求速度(录屏时数据请求约3.9s),无网络情况下打底数据来自前一次成功请求。流畅性可查看 ,左起为   H5、iOS   Weex、Android   Weex。

1 目标

展开   Weex   双11细分目标:

【阿里鬼道】Weex在双11会场的大规模应用:业务支撑、稳定性保障和秒开实战

  -   Weex   双11细分目标 2 业务支撑

支撑住双11的业务需求,是   Weex   必须要迈过的坎。 双11的会场结构大致为:会场框架(框架   +   主会场、全部会场、必抢、清单、我的双11)、分会场、其他会场(分分会场、人群会场等)。

3 会场框架

Weex   支撑双11业务首要解决的是会场框架及其交互形式:

1.   交互主流程: 1.     push   方式(框架Tab   切换):主会场   -   全部会场   -   必抢   -   清单   -   我的双11 2.   push   方式:主会场   -   分会场   -   主会场 2.   iOS   考虑到内存开销,需严控打开的主分会场weex页面,定为   n   级可配,默认为   5;同时   iOS   会场框架为单实例,也是出于内存的考虑;Android   连续打开   30   级以上   Weex   页面,未见内存异常增长,无需特殊方案

【阿里鬼道】Weex在双11会场的大规模应用:业务支撑、稳定性保障和秒开实战

  -   会场框架交互 Weex   会场框架很好支撑住了双11的复杂交互需求并提供了更好的内存管理。除了会场框架,更多的   Component     Module   支撑住了各色各样的双11需求,这里仅列出几个代表: 1.     组件是几乎所有会场页面的标配,流畅的滚动帧率、高性能的内存复用机制和渲染机制是页面流畅体验的重要基础 2.     尽管是实验版需求,却支撑住了会场的垂直弹幕、坑位显隐等动画效果,动画效果细腻 3.   Weex   点播/直播组件     全景图组件支撑住了更为垂直个性化的业务需求

4 组织结构

上节内容也可以看出,参与   Weex   双11会场涉及多个团队和平台系统:

【阿里鬼道】Weex在双11会场的大规模应用:业务支撑、稳定性保障和秒开实战

  -   Weex   双11中组织结构 1.   天猫业务:通过斑马(活动页面搭建和发布平台)发布会场页面 2.   淘宝业务:通过斑马和   AWP   (产品页面发布平台)发布会场页面,上层   DSL   使用   Rx(即将开源) 3.   预加载:提前将会场   js-bundle   下载到客户端,客户端访问   Weex   会场时网络   IO   被拦截到本地文件     IO,从而极大加快了网络加载速度,预加载是这次秒开实战的抓手(注:最核心的工作) 4.   手淘、手猫客户端,Weex   是客户端的一部分,客户端中其实是   Weex、Native、H5   并存的 5.   Weex   SDK、业务模块:Weex   容器和基础的   Components、Modules,业务模块包括直播/点播组件、全景图组件 以上也仅涉及到客户端和发布端,背后还有无数的业务后台系统,就不一一列出了。   Weex   架构自上而下地展开: 1.   Business,Weex   业务层,Weex   双11主战场是手淘和手猫,此外还有大量客户端已经启用或接入了   Weex 2.   Middleware,Weex   中间件层,包括为   Weex   页面提供发布(斑马、AWP)、预加载(AWP)、客户端接入支持(AliWeex)、组件库(SUI)、游戏引擎、图表库等模块;其中斑马、AWP、预加载都直接参与了双11 3.   Tool,工具层 1.   DevTools,界面和交互复用了   Webkit   Devtools,支持   elements、network、断点、console   2.   ,方便开发者调试   Weex   页面,同时也是   Weex   example   的聚集地 3.   ,Weex   命令行工具集 4.   目前仍在建设更多的工具,如     支持一键打包成   App 4.   DSL 1.   JS   Framework,Weex   最初的   DSL   是基于   Vuejs   1.0   语法子集;目前在社区中在推进基于   Vuejs   2.0   的版本 2.   Rx,基于   reactjs   语法的   Weex   DSL(将于12   月正式开源) 5.   Engine,渲染引擎,从架构设计上,Android/iOS/H5   RenderEngine   是相互独立和平等地位的渲染端,这是保持三端一致的基础,当然在协议实现层面需要更多的设计、质量保证

【阿里鬼道】Weex在双11会场的大规模应用:业务支撑、稳定性保障和秒开实战

  -   Weex   架构

以上就是   Weex   在双11中的架构和业务支撑的范围了。 5 稳定性保障

Weex   的首要挑战就是稳定性,或者说保障   Weex   会场最大限度不降级。 6   iOS   JSCore   内存治理

8月初(同期双11启动)奥运大促时,手淘   iPhone   中反复进出会场20+(手猫15+),会出现   crash。奥运大促当天,手淘   iOS   1.59%   crash   次数来自该问题(top   6),手猫1.94%(top   8)。发现问题的当天成立了攻坚小组,从   JS业务代码、JSFM(框架)、iOS   渲染、iOS   JSCore   几个方向同时排查,一周内各方向排查到逐步收敛到:根本原因是   Weex   页面实例被全局持有(weex   runtime   只有一份),进而导致页面退出时内存不被释放,反复进出直至内存爆掉。因而任何可能导致页面实例被全局持有的因素都会触发这个问题: 1.   业务代码中的问题,意外导致的,给出   Lint   工具扫描业务代码,引入了“全局污染治理”(见下一节) 2.   JSFM   框架中的问题,如在   destroyInstance   时清理   commonModules   和所有   dependency   target;iOS7下的   Set   Polyfill   内存飙升问题 3.   iOS   中的问题,通过下发配置控制   VC   Push层级控制;内存警告时的非当前实例销毁策略,加入开关控制;iOS   9.x   JSCore   原生   Promise     Polyfill   并存时的内存问题

除了建立攻坚团队推进解决该问题,也在造势期前就展开双11会场压测,反复验证该问题,自双11造势期会场开测之后,该问题未再出现。 7 全局污染治理 在治理   JSCore   内存的过程中,逐步意识到对全局变量管控的必要性。Weex   中多个页面共用   1     runtime,单个页面如果写法不规范不仅可能导致内存泄露,更有可能污染全局环境,进而导致所有   Weex   页面无法正常工作。全局污染治理的核心抓手:

1.   严格模式,即   `use   strict`,使用严格模式可以将较多常见的   JS   陷阱转化为错误,如:无法再意外创建全局变量、将拼写错转成异常、限制了   eval   的能力  

2.   冰冻对象,利用   ES5     `Object.freeze()`,将   Weex   核心对象和   JS   原生对象“冰冻”住。尝试修改被“冰冻”的对象会抛出错误,一旦“冰冻”无法“解冻”。 8 跨端依赖梳理 Weex   通过   Adapter   来适配不同客户端的具体实现,诸多通用库,如:网络库、图片库、API   库、   H5容器(Web   组件)、埋点库、配置库   等在不同客户端上版本不一致,因此导致的线上问题将会成为双11会场的隐患。为此展开的依赖梳理和同步机制是双11稳定性的保障之一。这件事情可能将会长期出现在   Weex   问题清单之中,如何做到上层   Weex   SDK? 9 会场压测

*   压测场景 1.   5     200   坑位的普通会场页面,1   全景图会场页面,1   UT   Expose   压测页面,1   直播会场页面 2.   页面中提供链接,能够按顺序进行   push   跳转 *   压测方案 1.   主链路(首页->店铺->详情->购物车)做一遍操作,让内存缓存占满,记下内存值   M0 2.   进入   Weex   页面,滑动到底部,滑动到顶部,记下   M1;点击跳转按钮,跳转到下一个页面 3.   重复步骤   2,让所有的页面进行压栈;全景图->p1p2p3p4->直播->p1p2p3p4->UT *   压测结果:iOS   通过,Android   通过 1.   测试过程手淘手猫均未出现因为压栈导致的   Crash,稳定性可以保证; 2.   Android低端机压栈过多会导致体验较差,之后也会引入类似   iOS   VC   层级控制;

压测在造势期会场测试阶段展开,在超出真实会场压力的情况下(真实会场150坑位上限),尽可能提前嗅探出潜在的   iOS   JSCore   内存问题、iOS/Android   异常闪退等细节问题。 10 稳定性数据 2016.11.11,Weex   在手淘中的   Crash   占比情况:

*   iOS   1.46%(TOP7) *   Android   Java   Crash   0.85%(TOP13)、Native   Crash   1.72%(TOP8)

考虑到会场的业务量级,Weex   的稳定性仍然是不错的。注:单独计算的   Weex   Crash   率太小,参考价值不大。 11 秒开实战 Weex   秒开率   =   (加载时间   +   首屏渲染时间)<   1s   的比率

其中:加载时间指   Weex   js-bundle   的加载时间(从网络下载或本地加载);首屏渲染时间指   Weex   页面开始渲染到第   1   个元素   bottom   超出首屏范围的时间。下文提到的“首屏网络时间”为加载时间与首屏渲染时间的和。

从双11结果看预加载大幅度提升加载时间,对秒开率的贡献尤其突出;但性能优化是个长期迭代的过程,回头来看优化的抓手是:预加载和首屏渲染优化。 12 预加载

预加载解决了   1   个问题: 用户访问页面(H5/Weex)之前,将页面静态资源(HTML/JS/CSS/IMG...)打包提前下载到客户端;用户访问页面时,将网络   IO   拦截并替换为本地文件   IO;从而实现加载性能的大幅度提升。

【阿里鬼道】Weex在双11会场的大规模应用:业务支撑、稳定性保障和秒开实战

【阿里鬼道】Weex在双11会场的大规模应用:业务支撑、稳定性保障和秒开实战

启用预加载后加载时间的变化,粗算一下:手淘   iOS,走网络平均   296ms,走预加载   18ms,网络性能提升约   15   倍;手淘   Android,走网络平均是   696ms,走预加载是   54ms,网络性能提升约   12   倍,但绝对值更大,对   Android   会场秒开贡献更为突出。 2015年预加载已经在双11   H5   会场中有较多应用,2016   年预加载升级为一项基础服务,不仅为   WindVane   提供预加载能力,也成为   Weex   秒开的最强外援。 此次双11会场共启用   30   个预加载包,总容量超过   20MB,业务需求相对稳定且流量较大的几个页面(会场框架+主会场   等)是独立的包,保证了对整体秒开的贡献,其他分会场均分在剩余的包中。同时主要采用强制更新的策略,即新的资源包(服务端有新发布)未下载到本地就直接读取线上,可以保证业务的实时性。2016.11.11,双11会场中   Android   走预加载占比为   59.4%,iOS     62.5%,高于平均水平(但还可以更高)。

13 首屏渲染优化

首屏渲染优化的目标就是尽力缩短首屏的渲染时间,为此在一系列的优化过程中,可以粗分为:DOM   解析优化、UI   渲染优化、分段懒加载。 13.1   DOM   解析优化 *   Component   append   属性定义了   `node`     `tree`   2   种渲染模式,`node`   就是逐个节点渲染,   `tree`   就是整棵树一起渲染。直观的对比:   |   *   `node`   模式,节点逐个从   js   提交到   native   的,   native   侧有个   16ms   间隔的   layout   保证渲染的正确性,这是更接近于   WebKit   的一种解析渲染模式。优势是每一个被解析完的节点都可以立刻显示,同时保证不会长时间阻塞主线程,劣势是可能会造成多次冗余   layout,拉低流畅性。 *   `tree`   模式,整棵树(以当前节点为   root   的整棵树)从   js   提交到   native。优势是只需布局一次,渲染更高效;劣势是如果   tree   过大,就可能会阻塞主线程甚至阻塞渲染。 *   `node`     `tree`   可以精细化地控制页面展示的逻辑和颗粒度,典型的实践为首屏以内按   tree   解析,首屏以外按   node   解析。 13.2   UI   渲染优化 *   List   组件在   native   分别对应   iOS   UITableView     Android   RecyclerView,这两种   View   构建了   App   的半壁江山,使用它们来封装   list   的好处: *   只会渲染可见区域,减少首屏的渲染消耗 *   内存复用,所有滑动到不可见区域的   cell   都会被系统回收,用于渲染下一个   cell *   cell   之间天然互相隔离,   可以默认以   cell   维度划分并用   tree   的模式解析,提高渲染效率 *   拥有原生的交互体验,在   cell   上点击、左滑、右滑、移动排序等交互方式后续可以更方便地支持 *   想要达到   60FPS   的体验,一次主线程渲染必须少于   16ms。Weex   中一次渲染需要经过   6   个主要步骤(Build   Tree、Compute   Style、CSS   Layout、Create   View、Update   Frame、Set   View   Props),所以必须在   16ms   内完成这   6   个步骤,现实是任何一步在主线程中都可能超过   16ms,这块。 13.3分段懒加载 *   除了底层的优化,业务上也通过分段懒加载进一步降低整体渲染时间,对首屏渲染有间接帮助(减少调度) *   方案为:会场页面使用   List   进行布局,一个   cell   对应一个模块;页面启动默认加载   6   个模块(少数页面因为首屏模块过多因此特殊处理);默认往下滑到底触发   loadmore   后再加载   5   个模块;若加载过程中遇到电梯则电梯以下模块全部加载 除了底层的保障,我们也坚持每天产出“性能优化建议”,推进业务性能优化,接下来会有更加方便的工具提供给业务方直接性能调优;如双11期间   devtool   中增加了层级检测和告警,可以帮助排查深层级导致的   android   低端机   stackoverflow。

14 秒开数据

由于主会场流量占据了总流量的大部分,对其秒开率单列统计。2016.11.11   数据为:

主会场

  • 秒开率峰值(00:00):整体   96.9%(278.8ms)   ios   99.4%(146.4ms)   Android   93.4%(411.1ms)
  • 秒开率均值:整体   94.4%(367.6ms)   ios   99.0%(177.0ms)   Android   91.8%(473.3ms)
  • 帧率(FPS):红米   Note1s   53、小米5s   58.5;iPhone5c   53.1、iPhone6p   56.9、iPhone7   58,帧率数据来自线下采集,见 (左起为   H5、iOS   Weex、Android   Weex)。
所有会场
  • 秒开率峰值(00:49):整体   92.4%(490.7ms)   iOS   97.4%(291.6ms)   Android   87.5%(689.8ms)
  • 秒开率均值:整体   83.9%(651.9ms)   iOS   94.5%(368.0ms)   Android   78.6%(797.4ms)

15 新的起点

Weex   技术委员会在十月中成立了,核心解决   Weex   开发过程中的标准化和协同问题。并于10.26   进行了第一次会议,审议的   4   个话题(Input   focus/blur、750px实现方案、weex   analyze后续发展、标准化流程草案)经过充分讨论,均获得全员投票通过。 鬼道作为第一任组长,接下来半年带领各方推进   Weex   在集团和社区的深度建设,欢迎大家参与   Weex   的共建之中。对于参与   Weex   的各方而言,最直接的影响就是:需要作为   Weex   官方推荐,向集团或(和)外部社区贡献的   Module、Component、工具、平台   等成果   需要通过   Weex   技术委员会检视标准性。要求在   方案设计出来后实现之前   和(或)   实现出来后     2   个时间点向   Weex   技术委员会汇报标准性相关细节;这个要求是强制的,目的是保持   Weex   社区的标准化推进。如果你只是为局部业务开发定制化的   Weex   扩展,不涉及标准性,并不会被要求到   Weex   技术委员会汇报。 Weex   任重道远: 1.   Weex   不只是   Weex   容器,Weex   业务背后是发布、预加载、AB、线上监控、质量效能度量、数据埋点、业务开发技能转变/升级   等一系列行为的交织,如何减少业务从   H5/Native   转向   Weex   时的“阵痛”,是接下来的攻坚重点 2.   双11中遇到的典型案例或问题,会成为下一阶段的工作重点之一 3.   仍有大量业务需求需要开发,为此我们已经启动了   Weex   BigBang   项目,按照   WindVane     API   的调用频度和业务反馈情况,分批实现   30+   Weex   Module/Component,包括常用的   schema   唤起支持、网络类型判断、geolocation、audio、cookie、大图预览、通讯录   4.   减少新客户端接入   Weex   的成本,目前在尝试的   AliWeex   项目会扩大应用范围并成为客户端接入的标配 5.   跨客户端的底层依赖不同步问题会一直存在下去,需要更好的解法 不一一列举了,之后会有   Weex   Roadmap   的讨论并且会及时公布出来,欢迎关注。 从“ ”开始,先后经历的   Hybrid、React   Native、WVC   再到   Weex,这段经历也算挺戏剧性的;未来会是   Weex   吗?答案并不重要,唯有沉醉其中。


本文节选章节于2016双11电子书

记录阿里巴巴2016双11背后的技术

欢迎扫描识别上图二维码阅读全书



以上是关于阿里鬼道Weex在双11会场的大规模应用:业务支撑稳定性保障和秒开实战的主要内容,如果未能解决你的问题,请参考以下文章

第八章 交互技术,8.4 Weex 双11会场大规模应用的秒开实战和稳定性保障(作者:鬼道)

Weex 在双11会场的大规模应用

阿里移动11.11 | Weex 在双十一会场的大规模应用

Android初识weex与rax

《尽在双11》--阿里巴巴技术演进与超越 读书笔记

WeexConf 2018干货系列|Weex技术演进