摘要: 该文章来自于阿里巴巴技术协会 (ATA) 精选文章 IO 优化 今天 去啊 App 5.1.1 已经发布了, 航旅 Hybrid 混合架构有了更进一步的落地, 这轮优化目标是搞定 H5 真正的无缝秒出 先来看效果, 去啊 App 2G 网络下购买国际机票, 30 秒完成, 除了搜索入口页, 列表往下到付款页的前端都是 H5 Page, 大家感受一下: 目测性能是可观的
该文章来自于阿里巴巴技术协会 (ATA) 精选文章
IO 优化
今天 去啊 App 5.1.1 已经发布了, 航旅 Hybrid 混合架构有了更进一步的落地, 这轮优化目标是搞定 H5 真正的无缝秒出
先来看效果, 去啊 App 2G 网络下购买国际机票, 30 秒完成, 除了搜索入口页, 列表往下到付款页的前端都是 H5 Page, 大家感受一下:
目测性能是可观的尽管 H5 包的离线化隔绝了弱网对秒出的干扰, 设备本地 IO 耗时也是不能忽视的, 算上 zip 的解压缩, 仅在设备本地 IO 完全一个 html(包含其携带的资源文件)也会达到秒级的耗时, 在 iphone5 上也会有 0.5 秒左右的白屏时间
另外, HTML 本身的优化依然无法绕过, webView 里 JS 的运行效率通常是 Mobile Browser 里的四分之一所以 JS 必须尽可能靠后的介入渲染, CSS 必须尽可能靠前的介入渲染而在当下前端开发习惯来看, 页面通常会至少阻塞加载一个种子文件(比如 kissy), 而在 Mobile 设备中, 哪怕是无干扰 Dom 的 JS 阻塞运行都会带来 0.3 秒左右的白屏延时
所以, H5 容器的 IO 优化和 HTML 渲染提前是本期改造的重点, 即:
H5 容器加载资源的 IO 优化: 干掉 zip 包的即时解压, 离线包更新后立即解压散列到 SD 卡, 每次创建 View 时直接从设备读文件, 本地文件管理依然基于标准的 H5 包规范
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 的干扰
几点改造:
AngularJS 种子文件异步载入
非数据关联的 HTML 一律预装在页面
首次加载干掉任何影响页面抖动的 HashChange
基础数据的离线化(比如城市列表)
这几点无非是让首次渲染能尽快的展现, 接下来 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://abc.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 的速度:
整整一倍的提速, 太让人垂涎期待了
Whats 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 才会迎来真正的非标商品的个性化多元化时代这时我们的技术体系将着重解决这几类问题:
千人千面, 重点解决面向不同人群做手机里的定制化功能的问题
无线大数据, 重点解决打破 App 间的信息孤岛, 让跨端的数据化运营更加高效可靠
无线开源, 让 B 商家参与进来, 像手淘一个 (Native) 商品详情页通吃所有商品的时代很快就会被更个性多彩的非标商品打破, 这时, 大量垂直领域的产品模式设计更多要靠商家参与, 而不是我们自己那几个产品经理, 所以, 更开源更自由的手机店铺, 闭环服务才是王道
说到闭环, 去啊的机票购买流程, 是无线端闭环的经典案例:
这个例子是从钱包的入口开始购机票流程, 通过短信 Push 下载唤起等操作, 将用户捣腾到去啊 App 里(整个过程体验流畅, 估计你也很难分清楚哪些 Page 是 H5 的哪些是 Native 的吧)
So, 开源 + 闭环, 是我理想中的无线 Hybrid 技术的终极状态, 去啊 Hybrid 技术积累也才刚刚开始
来源: http://www.tuicool.com/articles/EBR7na3