WKwebview 白屏问题——(WebApp/HybirdApp)

我们app从ReactNative转H5app,在开发过程中发现一个顽固性问题。点击H5的tabbar或者页面之间点击跳转会偶现白屏问题。或者app退到后台一段时间唤醒app会出现白屏。

白屏原因:

WKWebView是一个多进程组件,Network Loading以及UI Rendering在其它进程中执行。所以UIWebView上当内存占用太大的时候,App Process会crash;而在WKWebView上当总体的内存占用比较大的时候,WebContent Process会crash,从而出现白屏现象。这种一般是操作中交互点击内存过大可能会突然白屏,然后这种你查看图层还会看到界面UI,但是页面就是白屏。后台放置一段时间唤醒会白屏,这种感觉也是程序在内存中被销毁,打开白屏。查看图层会发现白屏的WebView的中缺少一个WKCompositingView视图(WKWebView的渲染单元,属于渲染进程)。目前白屏现象发现有这两种表象。

我们处理白屏方案:

方案一:后台放置一段时间唤醒会白屏

解决方式:退到后台再唤醒,我们native 超过10分钟会刷新,一是页面数据定时更新需要刷新,二是防止内存杀死白屏。但是仍然存在偶现白屏。

方案二:判断webView.titile

在白屏的时候,有些时候页面 webView.titile 会被置空,所有会在viewWillAppear判断标题为空的重新reload页面。

- (void)viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];

    self.navigationController.navigationBar.hidden = true;

    if (!self.isFirstLoad && StrIsEmpty(self.wkWebView.title)) {

        [self.wkWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:Active_Path]]];

    }

方案三:内层过大会执行webViewWebContentProcessDidTerminate进程终止方法

有些情况当日在web一直操作时会突然白屏,有的时候是因为内容过大导致程序终止。所以采用如下方法处理

    // 此方法适用iOS9.0以上     iOS8用监听另行处理

- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView NS_AVAILABLE(10_11, 9_0){

    NSLog(@"进程被终止");

    [self loadActiveRequestWithUrl:Active_Path];

    

}

    // 防止白屏,单web应用,后面路由切换不会加载

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    if (object == self.wkWebView && [keyPath isEqualToString:@"URL"])

    {

        NSURL *newUrl = [change objectForKey:NSKeyValueChangeNewKey];

        NSURL *oldUrl = [change objectForKey:NSKeyValueChangeOldKey];

        

        if (ObjIsNilOrNull(newUrl) && !ObjIsNilOrNull(oldUrl)) {

            [self loadActiveRequestWithUrl:Active_Path];

        }

    }

}

这三种方案基本解决了我项目里99%的白屏,复现几率很少。但是最近还遇到过2回白屏。最近逛简书发现还有一种方案。

补充方案:待验证

可以遍历WKWebView的subviews,通过是否包含WKCompositingView来判断是否白屏。按照网络方案,清缓存、reload和setNeedsLayout都不能解决白屏,所以只能回收旧webview(webview = nil 后记得清除代理,移除监听,要不然会crash)创建新的 webview, 然后重新request。

// 判断是否白屏

- (BOOL)isBlankView:(UIView*)view { // YES:blank

    ClasswkCompositingView =NSClassFromString(@"WKCompositingView");

    if ([viewisKindOfClass:[wkCompositingView class]]) {

        returnNO;

    }

    for(UIView*subViewinview.subviews) {

        if (![selfisBlankView:subView]) {

            returnNO;

        }

    }

returnYES;

}

补充方案来源简书作者如下:
作者:zhoutq
链接:https://www.jianshu.com/p/de67f5a752b6
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Asia_ZhangQQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值