常见的H5白页我们是无法通过WKWebview的代理方法监听到,我们可以先来了解下WKWebview监听方法对应的H5加载状态
WKWebview提供了以下几种代理方法监听整个h5页面加载的生命周期:
// 开始加载
- (void)webView:(WKWebView *)webViewdidStartProvisionalNavigation:(WKNavigation *)navigation{
NSLog(@"[开始加载] 请求已发送,等待响应...");
}
// 服务器已返回内容
- (void)webView:(WKWebView *)webViewdidCommitNavigation:(WKNavigation *)navigation{
NSLog(@"[已接收响应] 开始渲染页面...");
}
// 加载成功
- (void)webView:(WKWebView *)webViewdidFinishNavigation:(WKNavigation *)navigation{
NSLog(@"[加载成功] 页面及所有资源加载完成");
}
// 加载失败
- (void)webView:(WKWebView *)webViewdidFailProvisionalNavigation:(WKNavigation *)navigationwithError:(NSError *)error{
NSLog(@"[加载失败] 错误原因: %@", error.localizedDescription);
}
// 重定向
- (void)webView:(WKWebView *)webViewdidReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
NSLog(@"[发生重定向] 目标 URL: %@", webView.URL.absoluteString);
}
H5 页面状态与 WKWebView 事件的对应关系

JS/CSS/图片加载失败监听问题
WKWebView 不会 直接通知外部这些资源的加载失败。如果需要监控,需通过注入 JS 代码监听 H5 页面的 window.onerror 事件:
let js = """
window.onerror = function(message, source, lineno, colno, error) {
window.webkit.messageHandlers.jsError.postMessage(
{ message: message, source: source }
);
};
"""
webView.configuration1.userContentController.addUserScript(
WKUserScript(source: js, injectionTime: .atDocumentStart, forMainFrameOnly: false)
)
// 注册 JS 消息处理器
webView.configuration1.userContentController.add(self, name: "jsError")
我们了解下H5的加载流程
初始化 webview -> 请求页面 -> 下载数据 -> 解析HTML ->同步js-> DOMContentLoaded -> 请求 js/css 资源 -> dom 渲染 -> 解析 JS 执行 -> JS 请求数据 -> 解析渲染 -> 下载渲染图片
H5页面一般只有在DOM渲染后才会显示页面,所以在这之前出现问题就有可能导致白页的出现。从H5的加载流程出发我们猜测可能出现白屏的因素有js/css等资源下载失败、DNS解析失败、CDN缓存异常、运营商服务波动,当然如果H5流程不规范写成等待业务接口请求完成后再渲染页面、同步js/css阻筛,wkwebvew内存溢出(如大图表、无限滚动)也会造成白页。
1、wkwebvew内存溢出
需要H5检查业务优化长列表渲染(虚拟滚动)、及时销毁无用的事件监听和定时器;同时在wkwebvew内存即将溢出时会回调webViewWebContentProcessDidTerminate方法,客户单重新reload页面也能避免白页的出现;
还有一种情况内存溢出不会触发webViewWebContentProcessDidTerminate方法,比如h5调起手机相机拍照、拍照消耗系统资源比较大,此时系统会挂起和回收其他的任务,这时候wkwebvew内存被侵占并不会出发webViewWebContentProcessDidTerminate,遇到这种情况我么可以去监听页面title是否置空。
2、资源下载失败
可以按上述的js 注入监听,这个问题可能由于网络原因、或者资源过大、或者设置超时时间过短,可以针对性去排查和解决,同时也可以使用离线资源的形式去去提升加载速度,可以参考《优化APP中H5页面加载速度》
3、DNS解析失败
4、CDN缓存异常