原文作者:BBTime
原文链接:https://juejin.im/post/6885298718174609415
前言
自ios8推出wkwebview以来,极大改善了网页加载速度及内存泄漏问题,逐渐全面取代笨重的UIWebview。尽管高性能、高刷新的WKWebview在混合开发中大放异彩表现优异,但加载网页过程中出现异常白屏的现象却仍然屡见不鲜,且现有的api协议处理捕捉不到这种异常case,造成用户无用等待体验很差。
针对业务场景需求,实现加载白屏检测。考虑采用字节跳动团队提出的webview优化技术方案。在合适的加载时机对当前webview可视区域截图,并对此快照进行像素点遍历,如果非白屏颜色的像素点超过一定的阈值,认定其为非白屏,反之重新加载请求。
获取快照
ios官方提供了简易的获取webview快照接口,通过异步回调拿到当前可视区域的屏幕截图。
- (void)takeSnapshotWithConfiguration:(nullable WKSnapshotConfiguration *)snapshotConfiguration completionHandler:(void (^)(UIImage * _Nullable snapshotImage, NSError * _Nullable error))completionHandler API_AVAILABLE(ios(11.0));
其中snapshotConfiguration 参数可用于配置快照大小范围,默认截取当前客户端整个屏幕区域。由于可能出现导航栏成功加载而内容页却空白的特殊情况,导致非白屏像素点数增加对最终判定结果造成影响,考虑将其剔除。
- (void)judgeLoadingStatus:(WKWebView *)webview {
if (@available(iOS 11.0, *)) {
if (webView && [webView isKindOfClass:[WKWebView class]]) {
CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height; //状态栏高度
CGFloat navigationHeight = webView.viewController.navigationController.navigationBar.frame.size.height; //导航栏高度
WKSnapshotConfiguration *shotConfiguration = [[WKSnapshotConfiguration alloc] init];
shotConfiguration.rect = CGRectMake(0, statusBarHeight + navigationHeight, _webView.bounds.size.width, (_webView.bounds.size.height - navigationHeight - statusBarHeight)); //仅截图检测导航栏以下部分内容
[_webView takeSnapshotWithConfiguration:shotConfiguration completionHandler:^(UIImage * _Nullable snapshotImage, NSError * _Nullable error) {
//todo
}];
}
}
}
缩放快照
为了提升检测性能