点击上方蓝字关注我,知识会给你力量

背景

在实际业务中,app中的H5页面使用的场景越来越多,在货拉拉app中也存在大量的H5页面,比如金秋拉货节、余额、车型介绍页等,加载速度成为了困扰用户的一个痛点。为此我们决定引入离线包方案,另外还需要解决传统离线包方案不灵活,体积大,不易管理,不易降级等问题,我们设计和开发一套H5离线包系统,经过几个sdk版本的迭代,目前货拉拉H5离线包sdk,已在多个业务中落地,接受了大量用户检验。车型介绍页面使用离线包前后打开效果:

行业方案

目前H5离线包方案,通常是将离线包置入assets目录中,打包在apk内部,用户使用过程中再按需加载。所以大部分情况下可能存在以下问题:

  1. 由于离线包内容固定导致更新不及时

  2. 当离线包内容较多或者离线包个数较多时,会严重影响App包体积

  3. 由于离线包内部的逻辑固定,当出现问题时无法降级,无法禁用

  4. 上线没有数据对比无法知道上线效果

针对以上痛点,我们团队对离线包进行设计优化,应用于团队内的多个应用,多个业务场景中。

技术实现

H5离线包的基本原理是将html、js、css、图片等静态资源打包到成压缩文件,然后下载到客户端,H5加载时静态资源直接从本地取文件,减少网络请求,提高速度。加载本地文件路径存在的问题和解决:

存在问题 解决方法
cgi请求跨域 跨域请求头增加null支持
cookie跨域问题 目前静态js中无cookie操作,没有cookie跨域问题
localstorage跨域问题 暂时不涉及域名隔离问题,如果有需要,采取调用原生的方式解决
前端使用绝对路径问题 相对路径

4.1 总体结构

H5发布基本流程

image.png

App端流程图

image.png

前端的打包平台,支持发布为线上页面,也支持发布为离线包。离线包模式时,客户端会先查询是否有离线包需要更新,有则更新,同时支持离线包降级为线上网页。

H5离线包和线上H5一样也能进行更新和升级,有三个更新时机:

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"}]
}

总结

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

后期工作与展望

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

具体使用方法参考开源代码中介绍(https://github.com/HuolalaTech/HLLOfflineWebView-android )

参考资料

https://zhuanlan.zhihu.com/p/34125968

https://juejin.cn/post/6844903934004297736

作者介绍

货拉拉移动端技术团队

向大家推荐下我的网站 https://xuyisheng.top/  点击原文一键直达

专注 Android-Kotlin-Flutter 欢迎大家访问

往期推荐

  • flutter与compose的爱恨情仇

  • 从精准化测试看ASM在Android中的强势插入-读懂diff

  • 闲言碎语——第四期

  • ConstraintLayout2.0一篇写不完之MotionLabel

本文原创公众号:群英传,授权转载请联系微信(Tomcat_xu),授权后,请在原创发表24小时后转载。

< END >

作者:徐宜生

更文不易,点个“三连”支持一下

货拉拉 Android H5离线包原理与实践相关推荐

  1. 货拉拉 Android 动态资源管理系统原理与实践(下)

    点击上方蓝字关注我,知识会给你力量 so资源动态化方案 so资源打包问题 在打包so资源的过程中,我们遇到了如下问题. 如何移除apk中的so文件,并将他们收集起来? 如何将多个so文件压缩打包,并生 ...

  2. 货拉拉 Android 动态资源管理系统原理与实践(上)

    点击上方蓝字关注我,知识会给你力量 ❝ jary,货拉拉高级客户端工程师,目前负责货拉拉App Android端稳定性提升,包体积优化相关工作. ❞ 前言 随着公司业务的扩展,货拉拉用户端apk包的体 ...

  3. 货拉拉Android稳定性治理

    App Crash对于用户来讲是一种最糟糕的体验,它会导致流程中断.app口碑变差.app卸载.用户流失.订单流失等.相关数据显示,当Android App的崩溃率超过0.4%的时候,活跃用户有明显下 ...

  4. 货拉拉移动端网络优化——协议升级篇

    作者:货拉拉技术 链接:https://juejin.cn/post/7194627379656917047 一.背景 网络能力是互联网App的基本能力,一个app只有联网才具有生命力.为了提升货拉拉 ...

  5. 2022新鲜出炉Android面试总结附真题+答案解析(京东、新东方、货拉拉...)

    前言 从我的面试情况来看,不要以为技术面试过了就稳了,hr会卡人(京东),审批会卡人(货拉拉),所以,面试的时候,要多面试几家,不要一棵树吊死. 1.技术面试,通过 9家: 千喜鹤(2面),广州星域( ...

  6. 使用chrome devtools app(离线包)调试Android H5页面

      在调试Android H5页面的时候时候Chrome自带的"Chrome://inspect"工具调试时,国内用户都面临不可用的问题. 不翻墙,实现chrome浏览器调试工具的 ...

  7. Android货拉拉面试题,【货拉拉 产品 offer】货拉拉、Soul、不止少年最全面经!

    这是小喵的第52篇分享 小喵分享 一.offer情况 截止目前 货拉拉 产品 offer 二.个人背景 商科港硕 2段腾讯运营岗实习 三.面试经历 货拉拉 产品 一面 1. 为什么做这个项目? 2. ...

  8. 2021年7月 虾皮、货拉拉、有赞等面经总结

    大家好,我是若川,加我微信 ruochuan12 进源码交流群.今天分享一篇7月份新鲜出炉的面经,文章较长,可以收藏再看.学习源码系列.面试.年度总结.JS基础系列. 本文来自作者@几米阳光 投稿 原 ...

  9. 货拉拉客户端通用日志组件 - Glog

    作者:货拉拉技术  链接:https://juejin.cn/post/7168662263337861133 Glog 是货拉拉移动端监控系统中的日志存储组件,Glog 意即 General log ...

最新文章

  1. python timestamp转string_Python操作钉钉机器人发送各种消息
  2. NTLM在使用代理服务器的情况下,第三次握手可能出错
  3. Apache Sentry 初识
  4. Java Web开发小结
  5. 操作系统基础知识笔记
  6. 深入浅出WPF之Binding的使用(二)
  7. 利用T-SQL处理SQL Server数据库表中的重复行
  8. LADRC的学习——寻找物理模型被控对象(验证调参效果)
  9. Linux 杀死进程方法大全(kill,killall)
  10. 1.看板方法---解决敏捷管理者的困境
  11. 未开启3389实现远程桌面
  12. excel如何比对两列数据是否相同
  13. EDA技术及应用实验2 or2a程序
  14. 软件测试之逻辑思维题
  15. 朱嘉明:区块链将为再全球化提供基础结构和技术性制度(全文)
  16. Tips: Python语言中,《三国演义》人物出场统计
  17. httpwatch9.1 安装包
  18. VMware三种网络模式
  19. tomcat执行shutdown报错Could not contact [localhost:8005] (base port [8005] and offset [0]). Tomcat may n
  20. 计算机可以不需要显卡吗,显卡有什么用 电脑不装显卡影响大吗

热门文章

  1. Vue超好玩的新特性:在CSS中引入JS变量
  2. java 中的位移运算
  3. Persformer
  4. 读词----《苏幕遮》-(怀旧)
  5. Java中的日志分类及应用
  6. 极致CMS个人博客综合型模板
  7. 【我的Android进阶之旅】解决重写onTouch事件提示的警告:onTouch should call View#performClick when a click is detected
  8. 关于永磁同步电机机械特性的疑问?
  9. Android startForeground 却无notification的黑科技原理分析 以及Android7.1的修复
  10. FCN-Fully Convolutional Networks for Semantic Segmentation