上一篇 《转转离线包设计实践》 提到了转转 h5 离线包,早在三年前转转已经有了 h5 离线包服务的工程化能力,并且服务于集团内部若干个线上项目,同时带来的收益也是显著的。
什么是离线包
离线包是将包括 HTML、JavaScript、CSS 等页面内静态资源打包到一个压缩包内。预先下载该离线包到本地,然后通过客户端打开,直接从本地加载离线资源,从而最大程度地摆脱网络环境对 H5 页面的影响。
离线包技术不仅提升用户体验,也可以实现动态更新,节约用户流量(一次下载多次使用)。
传统的 H5 技术容易受到网络环境影响,因而降低 H5 页面的性能。通过使用离线包技术,可以有效的解决该问题,同时保留 H5 的优点。
转转离线包实现原理
由于 IOS 与 安卓客户端系统能力差异性,并且 IOS 请求拦截时系统本身的一些策略导致,因此转转针对不同端采用了不同端实现技术方案。
安卓侧:安卓侧实现相对简单一些,主要利用
shouldInterceptRequest
api 能力进行请求拦截,对于静态资源,先匹配服务端拦截路径前缀如果与本地离线资源匹配则走本地离线没有则走线上 CDN,对于 ajax 请求直接走线上。该方案实现相对简单。IOS 侧:由于 IOS 客户端能力限制,当请求拦截时,http(s) 的 post 请求则丢失 header、 body,因此在方案的实现上比安卓复杂。
转转内部探索了自己的实现方案,具体原理就是,通过 NSURLProtocol,注册 webview 并设置拦截 Scheme 为 "http"。在 canInitWithRequest 方法拦截所有 scheme 为 "http" 的 url,通过特定规则映射本地路径,如果找到本地资源,则加载本地资源,否则还原 scheme 为"https" 并请求远端数据。
需要制定一套特定的匹配规则方案进行实现,如图所示。
离线包的更新策略
如何做到及时的更新是一个必须要面临的难题。转转的方案是客户端主动拉取服务离线包版本 + 差分包策略,及时对用户侧的离线包进行更新。
主动拉取策略是 1. 用户打开 app 2. 用户打开 webview。这两种时机触发拉取离线包服务端版本进行与本地版本 diff 来实现及时的更新。
面临的新问题
但是,随着时间的推移,业务项目不断地扩张,工程化体系的演进愈来愈错综复杂,各种因素造成离线包整体服务本身也积攒了较多问题没有较及时的彻底的解决。因此决定对离线包服务现有的问题进行一次相对较彻底的治理与升级。
经过对现有离线包服务、项目情况以及整体使用流程进行了调查,发现了以下几个主要问题。
现有离线包平台使用成本较高,离线包管理与项目管理处于并行管理状态;项目离线包的开启与否取决多个人工操作步骤;且没有下载优先级概念。
现有离线包平台对离线包的开启率、端内页面整体命中率暂未统计,无法进行整体数据查看与分析
现有离线包项目开启率很低,经过统计大概只有 15% 的业务项目接入并开启了离线包功能(开启不代表端会下载)
某些没有 pv 的旧项目开启了离线包,并且造成了客户端进行无效的下载,浪费了流量和空间;
集团内的魔方(转转内部的活动页搭建平台)项目未接入离线包,某些业务会直接采用的魔方页面作为主入口页面。
当然了,以上背景是基于现象初步分析得出来的一些结轮,只了解现象还远远不够,还需