作者:哦是你的嘛_416 | 来源:互联网 | 2023-05-18 13:18
预加载说小了就是个提前load,说大了,就是HybridApp的最基础功能。Html5官方有个prefetch的attribute,用来做页面间的prefetch。其实在native
预加载说小了就是个提前load,说大了,就是HybridApp的最基础功能。
Html5官方有个prefetch的attribute,用来做页面间的prefetch。其实在native跳h5容器的过程中更需要这种流程,否则很容易导致体验劣化。
其实方案蛮多的:
直接下载url + WebView#loadDataWithBaseURL
优点是简单,缺点就是只能预加载下个页面的html内容,这样一来,实际效果很差,常常只能预加载1%不到的数据量
用隐藏的WebViewFragment加载,需要时做动画显示
优点也是速度最快,坑就非常多了:
- html加载过程完整,控制行为需要在WebChromeClient/WebViewClient做非常多的分支判断
- 需要兼容动画效果
- 需要控制back
- 最重要的,会导致js中的window#onload之类的函数不合理的触发,引发逻辑问题
用WebView提前load,靠WebView的cache
仍然不复杂,因为在预加载时可以禁掉js,真正加载的时候允许js,上一个方案的控制部分就解决了。问题在于,WebView的Cache是一体的,一清全清,一旦需要清理缓存那就会出现各种各样的全局问题了。
用WebView提前load,手写缓存
最复杂的方案,但是目前看没什么坑。
具体来说:
- prefetch阶段,重写WebViewClient#onLoadResource,将所有资源都下载到本地
- 本地缓存的文件结构:用baseUrl#hashCode生成一个文件夹,每一个资源都缓存到baseUrl#hashCode/resourceUrl#hashCode的文件中
- 缓存过程中,要标记一下,保证未完成的资源不被读取
- mime和charset通过HttpURLConnection的content-type来解析
- 复用阶段,重写WebViewClient#shouldInterceptRequest,重定向所有资源请求到本地stream
- 清理阶段,交给外部,外部通过baseUrl,或者根目录来清理对应的缓存