如今不少app都是经过webview内嵌H5的页面,这种方式的好处就是无需发版就能更新线上的内容,并且能够作到多平台的统一开发,节约开发成本。可是这种模式也带来了必定的问题,web开发很大程度依赖于网络,而移动端的网络千差万别,H5页面对于网络属于强依赖,由于各类请求都须要走网络,因此在弱网的状况下,资源文件迟迟加载不到,影响整个页面的解析,致使页面白屏。html
对于这个问题,根源在于资源文件对于网络的依赖,为了解决这个问题不少hybrid应用将静态资源文件都打包进了应用里面,对文件的访问直接指定为本地文件,这虽然能够解决弱网状况下白屏问题,可是也致使了其余问题,一个是更新须要跟随app的发版,二是若是页面在web和app平台共用的话,须要打包两个版本,比较麻烦。前端
针对上面问题,资源本地化是必须作的,只有资源文件请求不依赖于网络才是解决问题的根本。同时,咱们须要提供一套在线更新本地资源文件的机制,才能充分利用H5页面可以及时升级更新的灵活性。web
资源本地化跨域
为了让一套 web 页面同时兼容浏览器和 Hybrid 容器等多种环境,咱们但愿不改变前端代码就能够作到“资源请求发到本地”。这里采用的解决方案是监控整个webview容器的网络请求。浏览器
采用配置映射表的形式,映射表指明了网络请求文件对应的本地文件的路径,当webview的网络请求发出的时候,webview的拦截全部的网络请求,检测请求文件资源是否在配置表中,若是有,直接拿本地文件,若是没有直接走网络请求。网络
资源配置表:app
这样作的好处是资源本地化对于整个web容器是一个黑盒子,我按照正常的方式发送和接收请求,只不过是中途的方式变了,无需改变咱们web的任何文件来作兼容。这里只要提供给客户端一份资源映射表便可。而映射表的生成能够直接作在持续集成的流程里,构建工具在 build 时会帮你生成出来。异步
至于客户端的修改,须要对webview的网络访问进行拦截匹配,具体可参考:工具
Android:http://droidyue.com/blog/2014/11/23/block-web-resource-in-webview/index.hml测试
Ios: http://www.zhimengzhe.com/IOSkaifa/257201.html
至此,咱们经过上面的方式能够作到读取本地资源,那接下来须要解决另一个问题,本地资源如何获取和更新。
离线资源获取和更新
对于离线资源的获取和更新,采用比较暴力的手段。将整个离线包zip打包压缩,每次H5应用启动后,会去请求一个配置文件,配置文件包含当前离线资源包的版本号字段,将请求到的版本号跟上次保存(第一次不存在)在本地的版本号比较,若是发生了改变,说明离线资源文件包更新,下载解压而且替换掉旧的离线包。
到这里就完成了静态资源本地化的过程。在弱网或者无网络的状况下咱们的应用也能快速打开页面。在测试的过程当中,又出现了一些问题,因为静态页面能够打开,可是咱们接口获取一些列表数据走的是异步请求的接口,没法离线到本地,致使没有数据的展现。这里咱们须要作一些本地化存储。
本地化存储
对于一些基本的数据展现接口,咱们能够借助HTML5的localstorage,当在有网络请求的状况下,将数据打上时间戳,存储localstorage。数据请求超时的时候,把对应存储在localstorage的数据暂时展现给用户,这样能够解决长时间没有数据的问题。localstorage 的方案要解决跨域访问的问题,而且在每一个子域存储空间上存在上限,是5M,因此对于这个数据的存储要控制好。