The principle and practice of Lala Android H5 offline package

  1. background

In actual business, there are more and more scenarios in which H5 pages are used in the app. There are also a large number of H5 pages in the Huo Lala app, such as the Jinqiu Lahuo Festival, the balance, the model introduction page, etc. The loading speed has become a problem for users. a pain point. For this reason, we decided to introduce an offline package solution. In addition, we also need to solve the problems that the traditional offline package solution is inflexible, bulky, difficult to manage, and difficult to downgrade. We designed and developed a set of H5 offline package system. After several iterations of sdk versions, At present, the Huolala H5 offline package sdk has been implemented in many businesses and has been tested by a large number of users. The effect of opening the model introduction page before and after using the offline package:

  1. Industry Solutions

At present, the H5 offline package solution is usually to put the offline package into the assets directory, package it inside the apk, and then load it on demand during the user's use. So in most cases there may be the following problems:

  1. The update is not timely due to the fixed content of the offline package
  2. When the content of offline packages is large or the number of offline packages is large, the volume of the App package will be seriously affected
  3. Can't downgrade when something goes wrong, can't be disabled due to fixed logic inside the offline package
  4. There is no data comparison to know the online effect

In response to the above pain points, our team designed and optimized the offline package and applied it to multiple applications and multiple business scenarios within the team.

  1. Technical realization

The basic principle of H5 offline package is to package static resources such as html, js, css, and pictures into compressed files, and then download them to the client. When H5 loads, static resources directly fetch files from the local area, reducing network requests and improving speed. Problems and solutions for loading local file paths:

There is a problem Solution
cgi request cross domain Added null support for cross-domain request headers
cookie cross domain problem At present, there is no cookie operation in static js, and there is no cookie cross-domain problem
localstorage cross domain issue The problem of domain name isolation is not involved for the time being. If necessary, it will be solved by calling the native method.
The problem of using absolute paths in the front end relative path

4.1 Overall structure

H5 release basic process

image.png

App-side flowchart

image.png

The front-end packaging platform supports publishing as online pages and offline packages. In the offline package mode, the client will first check whether there is an offline package that needs to be updated, and if there is an offline package, it will be updated.

The H5 offline package can also be updated and upgraded like the online H5. There are three update timings:

1)WebView容器打开时更新。在需要开启离线包功能的H5页面打开时,会去后端检查对应的离线包页面是否有更新。如果有更新,则下载离线包到本地,绝大部分场景是下次打开时生效。

2)启动查询离线包更新。对于实时性要求比较高的页面,可配置在启动时检查更新。

3)通过长连接推送的方式通知客户端下载最新的离线包。(需要接入方自己实现长链接,调用SDK更新方法)

4.2 性能优化

1)多业务并行化,单业务串行

离线包检查更新时,存在同时查询多个业务的离线包是否有更新的情况,为了提高查询效率,多个业务离线包检查的请求采取并行请求的方式。考虑到后端改造成本问题,目前还不支持聚合查询,计划在后续版本中完善。另外,考虑业务流程的更新流程取消可能导致不稳定,单业务只做串行,避免过程中文件损坏,下载不全,线程并发的问题。

image.png

2)启动预下载

大部分离线包查询和下载的时机为打开H5页面时,由于离线包查询、下载、解压总体耗时较长,导致首次打开无法命中离线包。所以货拉拉离线包支持配置部分离线包在启动时检查和下载离线包。配置为:

OfflineConfig offlineConfig = new OfflineConfig.Builder(true)

        .addPreDownload("offline-pkg-name")//预加载业务名称

        .build();,
复制代码

4.3 可靠性设计

1)解压操作可靠性设计

文件解压耗时较长(大约30ms),如果中间程序退出可能会导致只解压了其中一半文件,影响后续离线包逻辑。所以解压到文件夹操作采取先解压,然后重命名,保证最后的文件夹的里的文件是完整的。同时当离线包正在使用时,一般情况下采取先解压,下次生效的策略,极端情况下可以立刻生效,但会导致页面强刷,影响用户体验。操作过程采取了temp、new、cur三个文件夹,解压细节如下

image.png

2)三重降级策略

a.客户端自动降级。

本地没有离线包时,客户端会自动将启用了离线包的H5页面降级为线上H5页面。

b.客户端远程配置降级。

可以设置局部降级,即临时将某个使用离线包的H5页面降级为线上,也可设置全局降级,关闭所有页面的离线包功能。接入方可以自行根据自己服务端下发参数进行配置:

OfflineConfig offlineConfig = new OfflineConfig.Builder(true)//总开关

        .addDisable("disable-offline-pkg-name")//禁用业务名称

        .addPreDownload("offline-pkg-name")//预加载业务名称

        .build();
复制代码

c.服务端接口降级。

服务端提供的离线包查询接口也可以设置将某个页面降级为线上H5,也可以支持让客户端更新离线包后强制刷新。目前,强制刷新为空实现,需要接入方自己实现,例如重启当前页面,关闭当前页面等。

降级策略流程图如下:

image.png

3)性能监控

货拉拉对webview的加载成功率,错误码、耗时进行了统计上报,通过监控面板查看。

此外离线包sdk还有离线包下载,请求,解压的耗时、结果数据上报。监控和上报采取的接口扩展方式,接入方根据业务特点选用具体的数据上报sdk。

4.4 效能优化

离线包和URL映射配置化

image.png

配置格式如下:主要通过url中的host、path、Fragment配置命中规则。根据接入方是否需要传入,不需要可以不传递。

//匹配规则相关 可选

ArrayList<String> host = new ArrayList<>();

ArrayList<String> path = new ArrayList<>();

ArrayList<String> fragment = new ArrayList<>();

host.add("www.xxxx.cn");

path.add("/aaa");

fragment.add("/ccc=ddd");



OfflineRuleConfig offlineRuleConfig = new OfflineRuleConfig();

offlineRuleConfig.addRule(new OfflineRuleConfig.RulesInfo("offline-pkg-name",host,path,fragment));


new OfflineParams()

        .addRule("offline-pkg-name",host,path,fragment)//自定义配置的形式

        .setRule(Constants.RULE_CONFIG)//json形式的规则

        .setRule(offlineRuleConfig)//实体类形式
复制代码
{
    "rules": [{
            "host": ["test1.xxx.cn", "test2.xxx.cn"],
            "path": ["/pathA"],
            "offweb": "offline-pkg-name-a"
        },
        {
            "host": ["www.aaa.cn", "aaa.xxxx.cn"],
            "path": ["aaa/path", "bbb/path"],
            "offweb": "offline-pkg-name-b"
        }
    ]
}
复制代码
  1. 总结

离线包上线后,收益明显,平均加载速度从2秒提升到1秒,同时H5页面加载成功率也有提升。页面主框架(不考虑动态数据)加载成功率从96%提升到100%。

  1. 后期工作与展望

扩大开源范围。比如支持断点续传的下载SDK,后续会考虑开源。离线包依赖的后端服务暂时未开源,目前采取是通过HttpServer搭建一个简单的本地Web Server,可保证离线包示例在本地正常运行。

具体使用方法参考开源代码中介绍(github.com/HuolalaTech…

  1. 参考资料

zhuanlan.zhihu.com/p/34125968

juejin.cn/post/684490…

  1. 作者介绍

货拉拉移动端技术团队

Guess you like

Origin juejin.im/post/7119662876578545678