Open youngwind opened 8 years ago
在Hybrid App中,需要频繁访问H5页面。要是每一次的页面请求都通过网络从远端拿的话,不但会消耗很多的用户流量,而且在网络不好(2G、3G)的时候会有巨大的延迟。 如何解决? --> 把H5页面直接放到app包里面,随版本发布,每次请求页面都从本地拿。 是的,早就有人这么做了。天猫、淘宝APP越来越大的安装包体积,原因之一就是放入了越来越多的H5资源。不过这个方法有局限性:第一,安装包体积不能无限增大;第二,APP发版之后web资源需要更新怎么办?所以这个方法只适用于存储一些基本不怎么变的web资源。
假设我有这样的一个APP。从每一个入口点击进去都是一系列不同的H5页面,你可以简单理解成四个不同的主要功能。我们称它们为“组件包”,所以这里就有四个组件包,对应到开发的时候就相当于有四个前端项目。
我们的目标是:当FE对任意一个项目作出修改之后,APP都能够动态更新对应组件包。 下图是对应的实现方案。
方案实现的demo分别是下面三个仓库:
目前实现的方案有一个问题:只有当用户启动APP的时候,才会去检查组件包是否更新,这样会导致更新的不及时。当然,我可以通过增多检测的时间点来缩短这个延时。但是,如果想要实时更新组件包,其实这本质上是“客户端与服务器之间的实时通信”问题。经典的解决方案有比如:短轮训、长轮训、websocket。我一开始在查阅很多这个更新机制相关的资料的时候,频繁出现”HTTP长连接“这个字眼,但是又都语焉不详,没有好好解释。我误以为HTTP协议本身可以实现实时的服务器推送,折腾了数天都没法实现。后来才发现”其实所谓HTTP长连接本质上只是TCP的长连接,通过HTTP header中设置connection:keep-alive来启动,能做到的不过是保持TCP通道,让之后的HTTP请求复用这一个通道,好处是省略了TCP的三次握手而已,是没有办法做到服务器推送的。要想实现服务器推送,还是需要用原始socket或者websocket来做。“实现这个难度比较大,这次就先不做,留待之后再优化。而且不仅组件包的实时更新需要用到socket,安卓APP的消息提醒机制也需要用到socket,所以之后还是得好好研究这个。
做到最后才发现漏了一个功能。。。那就是”组件包解压到本地之后,如果引用的问题。“比如说APP的webview想加载的是:”http://www.example.com/package/index.html“ 如何映射到APP内的对应目录呢?如果APP内没有离线资源,还要让webview加载远端的线上资源等等。
http2 是可以实现服务器推送的
问题
在Hybrid App中,需要频繁访问H5页面。要是每一次的页面请求都通过网络从远端拿的话,不但会消耗很多的用户流量,而且在网络不好(2G、3G)的时候会有巨大的延迟。 如何解决? --> 把H5页面直接放到app包里面,随版本发布,每次请求页面都从本地拿。 是的,早就有人这么做了。天猫、淘宝APP越来越大的安装包体积,原因之一就是放入了越来越多的H5资源。不过这个方法有局限性:第一,安装包体积不能无限增大;第二,APP发版之后web资源需要更新怎么办?所以这个方法只适用于存储一些基本不怎么变的web资源。
分析
假设我有这样的一个APP。从每一个入口点击进去都是一系列不同的H5页面,你可以简单理解成四个不同的主要功能。我们称它们为“组件包”,所以这里就有四个组件包,对应到开发的时候就相当于有四个前端项目。
我们的目标是:当FE对任意一个项目作出修改之后,APP都能够动态更新对应组件包。 下图是对应的实现方案。
实现
方案实现的demo分别是下面三个仓库:
遗留问题
所谓HTTP长连接
目前实现的方案有一个问题:只有当用户启动APP的时候,才会去检查组件包是否更新,这样会导致更新的不及时。当然,我可以通过增多检测的时间点来缩短这个延时。但是,如果想要实时更新组件包,其实这本质上是“客户端与服务器之间的实时通信”问题。经典的解决方案有比如:短轮训、长轮训、websocket。我一开始在查阅很多这个更新机制相关的资料的时候,频繁出现”HTTP长连接“这个字眼,但是又都语焉不详,没有好好解释。我误以为HTTP协议本身可以实现实时的服务器推送,折腾了数天都没法实现。后来才发现”其实所谓HTTP长连接本质上只是TCP的长连接,通过HTTP header中设置connection:keep-alive来启动,能做到的不过是保持TCP通道,让之后的HTTP请求复用这一个通道,好处是省略了TCP的三次握手而已,是没有办法做到服务器推送的。要想实现服务器推送,还是需要用原始socket或者websocket来做。“实现这个难度比较大,这次就先不做,留待之后再优化。而且不仅组件包的实时更新需要用到socket,安卓APP的消息提醒机制也需要用到socket,所以之后还是得好好研究这个。
虚拟路由问题
做到最后才发现漏了一个功能。。。那就是”组件包解压到本地之后,如果引用的问题。“比如说APP的webview想加载的是:”http://www.example.com/package/index.html“ 如何映射到APP内的对应目录呢?如果APP内没有离线资源,还要让webview加载远端的线上资源等等。
参考资料