今天在百度寻找一个合适的webview优化方案过程中,看到了这篇文章,分享给大家看看,希望对开发设计有一个好的影响。

原文地址:点击打开链接


TB19LgLKXXXXXaPXpXXXXXXXXXX-684-536.png

去年(2015)四月份,在 QCon 北京大会上分享了阿里旅行 Hybrid 实战经验,作为航旅在 Hybrid 方向探索的一个收尾。当下集团内的重量级 App(手淘、钱包等)在 H5 容器建设上成长迅速,形成了宏大的技术体系,到去年双十一,H5 容器所承载的流量已经远远超过了有限的 Native Page。就航旅来说,H5 承载的流量是 App 的至少四倍。无疑,处在应用层的 Web 技术栈,以其独有的运行时环境(WebKit)、普适的技术标准(W3C & ES 5、6)以及极具优势的研发灵活性,成为面向 UI 和交互无线研发的不二解决方案。而 H5 离线技术体系的逐渐成熟,让 H5 和 Native 的融合达到前所未有的深度。

资源离线的思路简单、场景复杂,最复杂的就是 H5 活动页面的离线化。今天跟大家分享的就是航旅去年在 H5 活动页推包体系建设的一些实践。

就加载性能来说,资源离线和发版频度是一对矛盾。活动页结构简单,不具备复杂的业务逻辑,但变更极其频繁,对时效性要求很高,这种更新频繁程度在双十一期间表现最甚。我们在去年 4 月份立项的独角兽项目,集中精力建设活动页推包体系,试图克服这一对矛盾。

资源离线是加载性能优化的“二向箔”

Mobile Web 在弱网提速的唯一的办法就是坚决杜绝不必要的(运行时)网络请求,即除了 Json 格式的动态数据和其携带的商品配图之外,不应再有其他网络请求(埋点请求除外)。所以,HTML 和业务数据之间必须解耦。在此基础上,航旅的信鸽平台力争完成这四项任务:

  1. 定时程序:紧随页面结构(HTML)变更进行推包
  2. 增量包:增量包(保性能)和全量包(保安全)必须同时提供
  3. 服务器推:基于长连接的消息推送 & 客户端静默更新
  4. 自动化:推包过程必须自动化,解放人工,搭好页面点击“发布”即完成推包

航旅的页面也会通过 Zcache 在手淘中做离线,但由于缺少对线上页面变更的监控,所以双十一会场页面仍然无法在 Zcache 中缓存 HTML,只能缓存 JS、CSS 和 Img。我们知道,HTML 是否缓存对弱网加载速度影响很大,下图是航旅双十一主会场页面在两个端里 2G 网络下的加载瀑布:

TB159kuKXXXXXXPXFXXXXXXXXXX-1148-714.png

可以看到,手淘 App 里的渲染时机被 HTML 网络请求推后了,而且有一个更新后的 CSS 文件请求,不适时宜的阻塞了渲染。

定时程序动态推包

所以,针对去啊 H5 容器,我们写了两个程序来弥补 Zcache 在缓存动态页面方面的不足,

  1. o2o 在线资源抓取程序:基于 phantomjs 解析资源
  2. grunt-inc-offline 增量包计算器:基于 git-diff 的增量包运算

当然离线包生成器也是必不可少的,我们用信鸽平台将它们这样整合起来:

TB1NMIoKXXXXXXBXVXXXXXXXXXX-1450-1240.pn

  1. o2o 定时程序监听线上页面变更,将其所携带的资源(HTML、CSS、JS 和部分图片)抓取下来
  2. 增量包计算器会计算好与之前若干版本之间的增量文件,配合包生成器将增量包逐一构建打包,同时生成好每个增量包的 Diff Json
  3. 调用 Clam 命令通过 Gitlab 将资源包部署至 CDN,以备手机端更新。
  4. Gitlab 仓库 的更新会触发一个 Hook 脚本,调用 tSync 服务器的接口,来通知资源变更
  5. tSync 服务器沙箱完成消息封装,包括了第二步生成了的 Diff Json 文本
  6. tSync 长连接将消息指令下发给手机终端
  7. 手机终端拼好资源文件链接,从 CDN 将增量包更新下来,随后执行 Diff Json中的指令,完成包的更新。

其中,获取增量包时,手机会将本地离线仓库版本带上,和远端 tSync 消息中的更新包版本一起拼成资源包的 URL(一个真实的增量包 URL),格式形如:

http://g.alicdn.com/trip/h5-op2op/{$线上最新版本}/{$本地包版本}.zip

另外,Diff Json也很干净,包含了“新增”、“删除”、“更改”,这样可以让客户端来删除旧文件,减少新包覆盖后的冗余。平台的易用性上,信鸽平台的操作界面里很贴心的加上了“快速下线”功能,即一旦发现离线包更新到达率不够,可以立即做离线包下线,端的虚拟域会自动切换到线上页面。

TB1QIQFKXXXXXb0XVXXXXXXXXXX-1842-1064.pn

可以看到,整个系统关键在两个平台的衔接,即信鸽平台和 tSync Server。两者的分工很明确:

  1. 信鸽平台面向在线的 URL 完成资源抓取、构建和部署。
  2. tSync Server 完成消息推送和动态更新。

只要思路捋顺,整个推包的逻辑设计并不难,难的是这些模块的实现是否可靠健壮,其中较为核心的模块就是 o2o 定时抓取程序,o2o 定时程序是@弘树 开发的独立的命令行脚本,将资源离线的过程中,需要根据文件内容来决定文件路径的哈希值,即只要文件内容不变,离线后的引用路径就不变,这样就比较容易由 git-diff 程序来计算增量文件,毕竟文件是否属于“新增”应当看内容是否有变化,而不应该根据文件名(或者版本号)的不同来判断。

由于 o2o 是基于 phantomjs 来抓资源,所以,以 o2o 为原型我们衍生出了 o2o-capture 项目,将线上页面完全静态化到本地,用来做 TMS 系统挂掉的容灾备份方案,也是棒棒的。

有了完整的外围设施,手机端就可以聚焦在文件 IO 的性能优化上了,之前也介绍过,航旅 H5 容器用多层保障来加速 Local File 的文件读写,一方面避免不必要的 IO、另一方面将资源池管理和运行时的缓存管理隔离开,确保各自程序任务聚焦、高效,下图是手机端的两个重要进程:

  1. 资源预加载进程:在实际访问页面之前,将资源预加载到缓存池并更新 Cache Map
  2. 创建 WebView 进程:只聚焦本地资源读写,别的什么也不干

所以手机端 touch 到网络的环节收敛到了两处,第一,Package Update Controller,第二,WebView 本身必要的网络请求:

TB18CPfKpXXXXaMXpXXXXXXXXXX-2853-3043.pn

最终,在定时程序的帮助下,我们可以放心的将 HTML 也离线到端,而不必担心更新不及时的问题,配合高性能的 H5 容器,做到秒出就是自然而然的事情了。我们来看 2G 下去啊 App 和 手淘加载航旅会场页的速度对比,显然,去啊 App 的离线更干净彻底,不管首次加载还是二次加载,速度都是很可观的:

qua_vs_taobao_2g.gif

从全网的性能数据看亦是如此,下图是航旅双十一预售阶段的数据,10月28日主会场页在去啊、钱包、手淘里各种网络情况下的 DomReady 时间统计。在 2G 网络下,支付宝和手淘基本都卡在 HTML 请求阻塞上。

三端在三个网络下的 DomReady 时间对比(单位秒),结果是显而易见的:

TB1GmC1KpXXXXXGXFXXXXXXXXXX-1452-1186.pn

应当说明的是,这是在手淘和钱包没有条件缓存活动页 HTML 资源的情况下拉的数据,依照上面的思路,我们也写了一个外围工具 zcache pusher,来半自动化推送动态更新的页面,理论上手淘也是可以做到 2G 离线加速的

此外,Zcache 较早前就有计划和新版 TMS 尝试打通,让离线操作自动化起来,期待能尽快看到进展,和我们一样,Zcache 也会面临这个问题:“发版频度和离线包更新到达率”的问题。那么,影响包的到达率的因素都是什么呢?

发版频度 vs 离线包更新到达率

信鸽的整个体系对性能的考验不是来自架构设计,而来自硬件瓶颈,尤其是当定时程序检测到线上页面频繁部署(比如双十一期间,航旅会场页面每天更新频率峰值多达四十多次每天),频繁推包会带来两个问题:

  1. 手机终端是否能及时更新到最新版的离线包
  2. 如果要保证更新足够及时,频繁静默更新又会大量占用手机的流量

显然,这两点是相互矛盾的。我们既希望用户尽可能及时的更新到最新版的离线包,又不希望这种频繁推送过多占用手机流量。这种情况下,增量包只能确保用户及时更新的情况下,尽可能少的占用流量,而无法完全杜绝。也就是说,不管是手淘、钱包还是航旅 App,目前离线包的推送策略仍然过于“全量”,稍显粗暴,用户“无条件”接受所有更新。即目前所有端都做不到对用户行为的精准判断,做不到用户需要(订阅)A,我就给他推包 A。所以,信鸽平台和 tSync Server 都存在很大升级空间。

So,在这次双十一执行过程中,在航旅 App 里,这一对矛盾究竟如何表现?下图是10月28日会场页面最新一次推包后的客户端更新比例,左图是推包 1 小时后,右图是推包 2 小时后。

TB1LtssKXXXXXXmXVXXXXXXXXXX-1398-576.png

天哪,看看今天执行了多少次推包!

可以看到,相比于过去传统的线上页面部署,离线包的部署时效性显然慢一些,不够 100% 所见即所得。这也是为了换取加载速度不得不做的牺牲。但基本上每次推包 3 个小时候可以完成 90% 以上的更新。受用户所在网络和打开时机等因素影响,散落在手机端里的离线包旧版本的碎片化依然非常严重。不管用了多少优化手段,频繁修改页面、频繁推包都会对页面体验带来负面影响。

所以,对于时效性很强的页面,比如凌晨零点的发布需要切会场的场景,需要页面即时部署即时生效。若要走离线有两个方案可以选择:

  1. 提前(至少四个小时)推离线包,需要在页面中写好定时切换的逻辑
  2. 提前推消息指令,先将离线页面从端删除,在切换时同时执行线上部署和离线推包,去啊客户端支持虚拟域, 在线离线页面 URL 在容器中保持一致,在保证线上页面可用的情况下,逐步扩大离线包在端的覆盖率。

但不论哪个方案,我们都不可能像过那样部署线上资源那样轻松了。如果需要更高的时效性 + 更快的加载速度,则必须适度减少琐碎需求变更,降低推包次数。从这个角度看,决定性能的因素这里已经主要不在技术上、而在工程上了。

今年手淘(天猫)双十一主会场页面也遇到同样的状况,本来 Weapp 可以非常优雅的将 H5 Page 转义成 Native Page,理论上是可大大提速的,但还是为了满足页面动态性更新和个性化配置,不得不引入一些额外的网络开销,这些网络开销不合时宜的阻塞了布局的渲染,在弱网里的影响更大。我们来看去啊 App 里首次进航旅主会场(H5)和手淘中首次进天猫主会场在移动 3G 下的加载速度:

weapp_vs_hybrid_at_3G.gif

可以看到,H5 页面是逐级加载的,Native Page 是等待请求完成后瞬时渲染的。所以,不管是 H5 还是 Native,只要是应对这种频繁修改部署变更的活动页面,都会遇到加载上的瓶颈。信鸽平台是解决这对矛盾的一个缓冲,但根本上还是要从控制页面灵活性角度来求解。

但是,这种离散性未必都是坏事,它能适度缓解安装包体积膨胀的压力。

安装包体积极限

大家相信吗,手淘和猫客的安装包都过百兆了。这已经到了一款电商 App 包体积的极限。在上一篇文章中也提到,目前客户端技术架构在面对新功能的井喷时显得力不从心。H5 是一个方案,将资源和内容置于远端,但又会极大稀释客户端的体验。离线包技术就很合事宜的弥合这对矛盾。

但这显然不够,和钱包 App 的早期一样,航旅 App 在构建安装包时就会“预装”一部分重要 H5 资源,但面临高速迭代的产品需求,这个缓冲区是远远不够用的。目前,钱包和手淘显然已经将这个缓冲挤占完全挤占:

TB1yFPFKpXXXXcZXXXXXXXXXXXX-1740-578.png

以去啊 App v6.0 为例7 M 的 H5 离线包承载了将近 40% 的功能性页面 和 100% 的活动页面。所以只要你的 H5 页面质量够高,H5 离线包的体积消耗是非常划算的。这也是在航旅 BU 正在发生的事情,即便是在交互极其华丽的“去啊 App 6.0 行程”项目中,PM 还是不断从前端团队抽调同学参与一些关键页面的研发,一方面大家已经不担心 H5 体验的瓶颈,另一方面,“前端同学搭界面真是快!!!”

所以,高性能 H5 容器配合高效的离线包推送体系,再加上高质量的 H5 代码(通过 Clam 工具来保证),做出全网络“无缝秒出”的体验是完全没有问题的(体验视频):

h5_vs_native_v2.gif

大家还可以感受下航旅这次双十一的无线狂欢城和跑步游戏在3G网络中的表现

经过上面这些折腾,最终就达成了我们希望的结果:

  1. 快速的页面研发
  2. 灵活的部署、持续交付
  3. 无缝秒出
  4. 划算的功能体积比
  5. 时效性强的活动页也能做到高效离线化!

这就是航旅无线技术团队正在做的事情。好像很爽的样子,下面我们来说但是吧。

另一种混合

由于 WebView 对 App 进程来说是一个沙盒,所以 H5 页面的内存分配和 CPU 分片都是 WebView 独立完成,前端代码因为普遍缺少细致的内存管理,所以内存泄露时有发生,以至于H5 容器一定程度会影响 Crash 率。比如手淘 Android 就会限制打开的 WebView 堆栈的个数来减少内存压力。

ReactNative 是一个解法,就像我跟@小马 开玩笑时讲的,“前端同学用 React 搭了一个 App,就好像 Java 开发同学用 Bootstrap 搭了一个后台界面一样兴奋”。和 Bootstrap 一样,ReactNative 是业余 Native 开发同学的脚手架,是无法做出面向 C 端的产品的,只能做一做“阿里内外”这种量级的应用。

还有一个方向就是重新设计动态的 Native 页面布局,集团内代表性的就是鸟巢、 Dynative和今年双十一手淘在尝试的基于 Web Component 在三个端同构渲染的 Weapp,尽管对于复杂列表还是偶有性能问题,但至少整个 UI 的渲染已经脱离了 WebView,内存更加可控。我们也必须承认,在运行时性能上,不管是 H5 翻译 Native 还是原生 Native,都要强过 H5 容器的,尤其是在超长复杂列表的渲染上。相对于鸟巢和 Dynative 的全 UI 渲染,航旅也在规划 H5 和 Native 的交叉渲染技术的尝试,总体思想是借助 JSCore 和一个删减版的 Webkit 内核来渲染翻译好的 HTML 片段,页面交由 Native 来拼装:

TB1u4IFKXXXXXbaXFXXXXXXXXXX-1306-900.png

这个方向我们也是刚刚起步,希望能和兄弟 BU 们一同共建。

小结

航旅在 Hybrid 方向上做的事情,并非要证明航旅 H5 比其他端快,毕竟应用场景不同(比如手淘就有选择的忽略 3G 和 2G 网络)。但从航旅和集团各 BU 的混合开发实践来看,其实大家都在朝着一个方向努力,Native 期望获得 H5 快速开发和部署能力、H5 期望获得更快的速度和更高的硬件调用权限,两个思路:

  1. H5 容器技术(得益于 Clam 工具的保障,手淘、钱包、去啊 各自的容器,已经做到90%相互兼容):
    1. 优势:独立的 WebView,对前端开发友好,天然获得多端兼容的特性
    2. 劣势:外围体系化建设难度大
    3. 需要克服:一,硬件调用能力,通过桥协议解决;二,秒出保证,通过“离线包体系” + “精心编程的 H5 页面”解决
  2. H5 代码 Native 化(鸟巢Dynative、ReactNative、Weapp,互不兼容):
    1. 优势:H5 代码编译成二进制代码直接运行,天然的秒出体验
    2. 劣势:对前端开发极其不友好
    3. 需要克服:一,阉割版的布局能力,通过增加对 CSS3 标签的支持来解决;二,无法做到多端兼容,通过限制 H5 语法来解决

可见,两个思路都各有取舍、各有克服,都很难完美,从实践效果来看,H5 容器更加适合哪些对多端部署有要求的 BU,航旅就是一个典型。而 H5 的 Native 化方案更加适合独立客户端的一些私有场景,比如支付宝和天猫。所以要根据自身需求来选择技术路线。

我作为一名传统的前端工程师,从 PC 时代转战到无线,从去年航旅开始无线研发模式的探索以来,我也很幸运的尝鲜各种 Native 技术,从开始的好奇,到现在一大堆体系和工具的落地,一系列探索让我自己脑洞大开,也打破了之前固有的编程理念,这两年前端技术被颠覆的如此剧烈,让人有点不敢相信自己的眼睛。我想一方面,PC Web 开发的迅速衰落为无线前端技术快速崛起带来契机,另一方面,无线技术快速崛起,带来的不仅仅是技术体系的混合(H5 和 Native),更多的呼唤人的混合。我们很欣慰的看到一大堆前端同学在研究 ReactNative,另外一大堆 Native 同学在研究 W3C 和 HTML5。打破技术边界、拥抱无线技术的 All In,充满好奇,用怀疑一切的眼睛去看待自己固有的技术理念,投身并享受新一轮的无线技术变革,我想,或许正是因为此,使得阿里无线端技术体系伴随业务的增长,不断走向百花齐放、走向多元的吧。

IO 优化

今天 去啊 App 5.1.1 已经发布了,航旅 Hybrid 混合架构有了更进一步的落地,这轮优化目标是搞定H5真正的“无缝秒出”。

先来看效果,去啊App 2G 网络下购买国际机票,30秒完成,除了搜索入口页,列表往下到付款页的前端都是H5 Page,大家感受一下:

be4c2c9b4fa8d3e0d2e7ec92df37403a.gif

目测性能是可观的。尽管H5包的离线化隔绝了弱网对秒出的干扰,设备本地 IO 耗时也是不能忽视的,算上zip的解压缩,仅在设备本地 IO 完全一个 HTML(包含其携带的资源文件)也会达到秒级的耗时,在iphone5上也会有0.5秒左右的白屏时间。

另外,HTML 本身的优化依然无法绕过,WebView 里 JS 的运行效率通常是 Mobile Browser 里的四分之一。所以 JS 必须尽可能靠后的介入渲染,CSS 必须尽可能靠前的介入渲染。而在当下前端开发习惯来看,页面通常会至少阻塞加载一个种子文件(比如kissy),而在Mobile设备中,哪怕是无干扰Dom的JS阻塞运行都会带来0.3秒左右的白屏延时。

所以,H5容器的IO优化和HTML渲染提前是本期改造的重点,即:

  1. H5 容器加载资源的 IO 优化:干掉zip包的即时解压,离线包更新后立即解压散列到SD卡,每次创建 View 时直接从设备读文件,本地文件管理依然基于标准的H5包规范。
  2. HTML 本身的页面优化,CSS 提前,JS 置后。

“CSS 提前和JS置后”的动作是由工具来完成。即只要构建工具统一,开发者不需要关心如何摆放脚本最优,只需关注实现业务逻辑即可,举个例子,JS 置后的做法是这样:

其实无非是将同步的脚本改成异步。先保证带样式的页面框架秒出来,然后去执行 JS。从性能数据上甚至看不出差别,但从感官上的提升非常明显,我宁愿让你先看到界面,而不是白屏。

IO 优化(续)

从策略上,做到这两点足够应付大多数场景,能保证页面任何时候能秒出来。但在我们整个 Hybrid 架构中,我们设计了比较灵活的 H5 离线化,即用虚拟域来确保在线离线的一致,比如酒店团购H5页面,浏览器扫码打开是一个在线页面,用去啊App扫码进来就是一个离线页面,同一份代码,一个走网络加载,一个走本地加载:

这样设计主要是为了做线上线下的开关切换,紧急问题可随时配置到线上页面,线上页面是可以随时部署的,离线页面则涉及到推包。为了做这层开关,就会带来判断文件是线上还是离线的问题。

因为H5容器虚拟域的代理层会引导 WebView 去本地而不是网络读文件。如果读不到本地文件,再创建一个HTTP请求去对应的线上请求文件。如果通过 IO 一次再判断本地是否存在文件,显然实际的 IO 次数依然降不下来(所有的资源文件请求都必须要 IO 一次手机硬盘),为了降低实际 IO 次数,我们针对每个 H5 离线包生成一个本地资源文件列表(cache_info.json),并同时将域名路径和文件路径做成了映射 Map,这个映射表读入内存后备用,涉及到H5的访问,用这个 Map 过滤下就能直接找到要读的文件位置,Map 匹配不上就直接创建HTTP从网上取文件了,这样可以避免无必要的 IO。

AngularJS 在移动端的加速

去啊 Hybrid 中存在大量的列表页,比如上面的团购和视频中国际机票的例子,AngularJS 是最适用于这种场景。但 AngularJS 目前没有专门针对 Mobile 做优化,而在 Mobile 设备里,hashchange带动数据模型data-model的变更,进而通过View来渲染。首次渲染稍慢,因为要等Model准备好才出视图,无论如何界面也秒不出来(从hashchange到出界面至少0.8 秒)数据结构在稍微复杂点,立即破1秒,当然这个时间是伴随着首次加载构建DOM的干扰。

几点改造:

  1. AngularJS 种子文件异步载入
  2. 非数据关联的HTML一律预装在页面
  3. 首次加载干掉任何影响页面抖动的 HashChange
  4. 基础数据的离线化(比如城市列表)

这几点无非是让首次渲染能尽快的展现,接下来 OPOA 中的编程就是 AngularJS 所擅长的了。

离线包里的 TMS 如何载入

我们知道 AWP 只支持静态 HTML 的发布,这没什么好解释的,毕竟,高性能要求更简单粗暴且有效的缓存,全静态就可以全缓存,尤其是在移动终端的破网里面,缓存尤其重要,但 TMS 动态内容如何生成?我们都知道 AWP 平台提供了一个<!--HTTP:url-->的标签(使用说明),TMS 变更后就重新生成一份HTML 推送到CDN上。

那么问题来了,离线包里怎么做?

我们团队的同学写了offline-tms-parser模块,clam会将<!--HTTP:url-->标签构建:

<!--HTTP:http://abc.php,gbk:HTTP-->

构建为:

<script 
    src="http://trip.taobao.com/market/trip/h5_offline_service.php?
    callback=handle_tms_fragment&src=http%3A%2F%2Fabc.php" 
    charset="gbk"></script>

这样,在离线包里的 TMS 内容就和 H5 页面完全分开了,毕竟 TMS 由于变更频繁,是没办法直接做离线化的。但上面这段脚本显然会阻塞页面渲染,所以offline-tms-parser提供了异步的版本,即将:

<!--HTTP:http://abc.php?async,gbk:HTTP-->

构建为:

<script id="tms_fragment_1">
get_tms_fragment("http://abc.php", "gbk", "tms_fragment_1");
</script>

然后在 H5 页面顶部塞一个get_tms_fragment的实现即可。

如此,基于 AWP 平台开发业务将不受任何影响,工具帮我们处理好 TMS 和 H5 页面的百分百解耦,离线包里也可以大量使用 TMS 了。

尽管如此,也必须不能滥用 TMS,代码逻辑层面的 View 和 Data 的解耦仍然是必须要做的。

让人期待的 grunt-kmb

本期优化面向 H5 离线容器的代码改造的重点是上面这几项,但还有一项激动人心的变化: grunt-kmb,没错,构建流程也需要瘦身和简化了。

grunt-kmb是团队另一位同学正在开发的 grunt-kmc 的替代方案。相比于 grunt-kmc 基于正则匹配的模块解析,grunt-kmc 完全基于 uglify-js 提供的 JavaScript 语法解析树(AST),先看对比:

grunt-kmc 的速度:

grunt-kmb 的速度:

整整一倍的提速,太让人垂涎期待了。

What's Next

本期的优化没有多少高科技的东西,大都是体力活,将技术做透。好的体验真的是靠点滴的积累,需要花时间去磨。

其实从去啊App Hybrid 刚开始设计并做第一版优化到现在已经有半年多时间,这期间离不开客户端同学的全心投入,因为 H5 的优化必须借助高性能的 WebView 容器,但靠 H5 或者 Web 技术本身无论如何是无法做到秒出的。再配上《高性能网站建设指南》里零碎的优化技巧,H5 在 Hybrid 中完全可以做到秒出,再配备离线包动态推送和埋点采集等基础设施,Web 技术的瓶颈在 Mobile 中就能获得一定的突破。

我在这次集团前端技术峰会上的汇报里,提到过我们面临的挑战:

去啊 App 是介于工具化的钱包App和运营化的手淘App之间,既有营销活动,也有工具化、流程化的 PageFlow。将标准化的 PageFlow 的性能做到极致,接下来的挑战就是如何将运营活动也做到智能的推送,完成这类页面的离线部署。

当然,活动页面的离线化部署目前来看不是我们面临最急迫的难题,最棘手的是数据打通的问题:

看这个场景,在钱包App做了一个引流的入口,唤起了去啊App,并定位到机票搜索结果页:

目前我们很难跟踪唤起的效果,手机里的App是信息孤岛,很难通过简单的传参来把跨 App 的 PageFlow 串联起来。即使参数能带过来,但身份信息、登陆状态和账号关联能否也能带过来呢,每一项都是很有挑战。

我在前两天给航旅的新人培训上,分享了我理解的《Mobile First》,这段话是值得分享给大家一起共勉的:

内聚的 App 和散列的 Web 似乎是一个不可调和的矛盾。企业倾向于认为只有提供越来越多地功能,才能满足用户不断膨胀的需求,但又会打破原有应用的简便易用。当两者无法调和,信息膨胀到必须散列到不同的端时,通过 Web 技术将这些信息孤岛关联起来就显得至关重要。

所以,我们之前所做的所有技术的优化,都是在为构建无线“前端/终端”技术体系夯实根基,所以这一轮无线All In 从某种意义上看是一种原始积累,第二轮无线All In才会迎来真正的非标商品的个性化、多元化时代。这时我们的技术体系将着重解决这几类问题:

  1. 千人千面,重点解决面向不同人群做手机里的定制化功能的问题
  2. 无线大数据,重点解决打破App间的信息孤岛,让跨端的数据化运营更加高效、可靠
  3. 无线开源,让 B 商家参与进来,像手淘一个(Native)商品详情页通吃所有商品的时代很快就会被更个性、多彩的非标商品打破,这时,大量垂直领域的产品模式设计更多要靠商家参与,而不是我们自己那几个产品经理,所以,更开源、更自由的手机店铺,闭环服务才是王道。

说到闭环,去啊的机票购买流程,是无线端闭环的经典案例:

这个例子是从钱包的入口开始购机票流程,通过短信、Push、下载、唤起等操作,将用户捣腾到去啊App里(整个过程体验流畅,估计你也很难分清楚哪些Page是H5的、哪些是Native的吧)。

So,开源 + 闭环,是我理想中的无线 Hybrid 技术的终极状态,去啊 Hybrid 技术积累也才刚刚开始。



To Be Continue...



一些 Q & A:

Q:现在 Wifi 是最多的用户网络,为什么要纠结于弱网用户?

A:首先,我们希望在最严苛的环境中考练技术,再者,广大(地级)市、县乡这些 Wifi 覆盖率低的地区,我们都亲身体验过那里 4G 和 3G 是什么网速。

Q:这种强混合的研发模式,对前端技术框架有什么影响?

A:影响是颠覆式的。前端的模块化编程过于依赖 Loader 和上层的模块规范,而 Mobile Web 里是不是还强依赖 Loader 要打一个问号,一方面,Loader 本身太重,另一方面,Loader 是在运行时去组织资源依赖加载,显然会抢占宝贵的运行时资源,资源的组织和加载应当下沉交给更底层的 H5 容器或者工具去解决。

Q:H5 容器即是浏览器,怎么去平衡 Web 的加载性能和运行时性能?

A:这篇文章主要说的就是加载性能的解决方案。运行时性能我们也有一揽子的最佳实践,另开一篇介绍。

Q:基于 H5 容器毕竟不像浏览器,怎么快速打离线包调试?

A:这方面手淘、钱包 都有最佳实践。航旅通过工具可以实时构建 zip 离线包,直接拷贝到手机即可。目前是最土,也是最有效的办法。

Q:航旅怎么做到 7 M 的离线包完成 App 里40%的功能页面?

A:我们化了一整年来做体积瘦身的优化,另开篇介绍吧。

Q:上面提到的离线数据从哪里来的?

A:航旅自己提供了一个非常全面的打点方案 tracker,目前部署上抽离的还不是很够,但基本上我们想要的关键数据可以比较精确的取到了。大部分数据可以通过鱼眼来查看。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐