客户端相关
WebView
WebView 是一种嵌入到客户端的浏览器控件,可以加载网页,展示 HTML 内容。
Android
- 基于 WebKit 的 WebView:在 Android 4.4 之前,Android 使用的是基于 WebKit 的 WebView。
- 基于 Cromiun 的 WebView:从 Android 4.4 开始,为开发者提供了基于 Cromiun 的 WebView,性能、安全、功能更好,支持 HTML5、CSS3 和 JS 新特性。
iOS
- UIWebView:UIWebView 是 iOS 2.0 时期引入的,是一个基于 WebKit 的控件。
- 支持 NSURL。
- WKWebView:iOS 8 起,苹果推出了新的 WKWebView,取代了 UIWebView,在 iOS 13 后宣布不再支持 UIWebView。
- 多进程模型。
- 大幅度降低占用内存,支持 60fps 的刷新率,内置手势测探。
- 支持多进程。
- 支持如 indexedDB 和 WebAssembly 等 HTML 5 新特性。
- 代理方法命名更加清晰,提供更多功能。
JSBridge
简介与对比
JSBridge 是客户端与 H5 交互的桥梁,通过 JSBridge 可以实现客户端与 H5 的双向通信。
H5:
- 版本迭代快,上线灵活
- 兼容跨平台系统,如 PC、Android、iOS
Native:
- 使用原生内核,更加稳定
- 网速影响较小
- 加载速度快,更加流畅
- 原生系统 API 丰富,能实现的功能较多,体验较好
双向通信原理
JS 调用 Native
- 拦截 URL Schema
- 重写 prompt 方法
- 注入 API
拦截 URL Schema
- Android使用 shouldOverrideUrlLoading() 方法拦截 URL。
- iOS 使用 UIWebView 的 delegate 方法拦截 URL。
- 有长度的隐患。
重写 prompt 方法
- 拦截 window.prompt() 方法。
注入 API
- Android 使用 addJavascriptInterface() 方法。
- iOS 的 WKWebView 提供 window.webkit.messageHandles 方法。
- iOS 的 UIWebView 提供 JavaScriptScope 方法。
Native 调用 JS
拼接 JS 代码
- Android 4.4 之后使用 evaluateJavascript() 方法调用 JS 方法。
- Android 4.4 之前使用 loadUrl() 方法调用 JS 方法。
- iOS 的 WKWebView 使用 evaluateJavaScript() 方法调用 JS 方法。
单向调用回调如何处理
类似 JSONP 的思路,在 url 里面拼接 callback 参数。
离线包
离线包是客户端将 web 资源本地缓存,请求 web 页面时拦截 webview 的请求,并优先使用本地缓存的静态资源进行响应,以此来优化页面的加载性能。
实现方案
- 前端
- 前端和客户端约定一套统一的页面 URL 的路由规则发布。
- 在发布的时候配置是否需要离线包和是否差量更新(需要设置 diff 包的最大版本差,比如 10),上传离线包、计算差量包。
- 离线包工程根目录新增
appJson.json
文件,用于存放离线包的信息,包括离线包需要过滤的文件、客户端预加载的接口列表等。 - 一般离线包体积限定为 2mb 以内,图片等静态资源一般使用 CDN 链接。
- 只有常驻 webview 页面,或经常会打开的重要活动页面可以用离线包。否则会让客户端重启时下载负担过重,造成资源浪费和空间占用。
- 客户端
- 客户端需要在首次打开/重启/每间隔一定小时(拉取离线包列表接口),检查离线包的版本号,如果有新版本则预加载离线包,下载时机最好是仅 WIFI。
- 可以判断是否是全量包来差量更新。
- 拦截 webview 的页面请求,优先使用本地缓存的静态资源进行响应。
- 根据接口预加载列表在初始化 webview 的时候,预先获取首屏渲染依赖的接口数据,并存储在内存中,即用即销毁,H5 渲染时用内存中的数据。