WKWebView 白屏问题

摘要:
在UIWebView上,当内存消耗过大时,AppProcess将崩溃;在WKWebView上,当总体内存消耗较大时,WebContentProcess将崩溃,导致白屏。在WKWebView中加载以下测试链接可以稳定地再现白屏现象:http://people.mozilla.org/~Rnewman/fenec/mem.html此时,WKWebView.URL将更改为nil。简单的重新加载刷新操作已过期,这对一些驻留时间较长的H5页面有很大影响。当WKWebView为白色时,另一个现象是webView.title将为空,因此您可以检查webView.ttitle是否为空,以便在viewWillAppear时重新加载页面。

1、WKWebView 自诩拥有更快的加载速度,更低的内存占用,但实际上 WKWebView 是一个多进程组件,Network Loading 以及 UI Rendering 在其它进程中执行。初次适配 WKWebView 的时候,我们也惊讶于打开 WKWebView 后,App 进程内存消耗反而大幅下降,但是仔细观察会发现,Other Process 的内存占用会增加。在一些用 webGL 渲染的复杂页面,使用 WKWebView 总体的内存占用(App Process Memory + Other Process Memory)不见得比 UIWebView 少很多。

在 UIWebView 上当内存占用太大的时候,App Process 会 crash;而在 WKWebView 上当总体的内存占用比较大的时候,WebContent Process 会 crash,从而出现白屏现象。在 WKWebView 中加载下面的测试链接可以稳定重现白屏现象:

http://people.mozilla.org/~rnewman/fennec/mem.html

这个时候 WKWebView.URL 会变为 nil, 简单的 reload 刷新操作已经失效,对于一些长驻的H5页面影响比较大。

我们最后的解决方案是:

A、借助 WKNavigtionDelegate

iOS 9以后 WKNavigtionDelegate 新增了一个回调函数:

- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView API_AVAILABLE(macosx(10.11), ios(9.0));

当 WKWebView 总体内存占用过大,页面即将白屏的时候,系统会调用上面的回调函数,我们在该函数里执行[webView reload](这个时候 webView.URL 取值尚不为 nil)解决白屏问题。在一些高内存消耗的页面可能会频繁刷新当前页面,H5侧也要做相应的适配操作。

B、检测 webView.title 是否为空 并不是所有H5页面白屏的时候都会调用上面的回调函数,比如,最近遇到在一个高内存消耗的H5页面上 present 系统相机,拍照完毕后返回原来页面的时候出现白屏现象(拍照过程消耗了大量内存,导致内存紧张,WebContent Process 被系统挂起),但上面的回调函数并没有被调用。在WKWebView白屏的时候,另一种现象是 webView.titile 会被置空, 因此,可以在 viewWillAppear 的时候检测 webView.title 是否为空来 reload 页面。

综合以上两种方法可以解决绝大多数的白屏问题。

免责声明:文章转载自《WKWebView 白屏问题》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Oracle-批量修改语句及相关知识点Hive扩展功能(六)--HPL/SQL(可使用存储过程)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

关于Promise,你必须知道的几点。

1.如何改变promise的状态 1). resolve(value) 如果当前的状态是pedding 就会改为 resolved 2). reject(reason) 如果当前状态是pedding 就会改为 rejected 2.一个promise指定多个成功 / 失败的回调,都会调用吗? 当promise状态改变时,对应的回调函数都会调用 const...

iOS-WKWebView的使用

参考文章:http://www.cocoachina.com/ios/20180831/24753.html WK时苹果在iOS8.0之后推出的控件,相比于UIWebView: 内存消耗少; 解决了网页加载时的内存泄漏问题; 与HTML页面的交互更方便; 总之,其性能比UIWebView好很多。 使用时,首先要添加头文件: #import <We...

Android WebView 支持H5的定位Js

1 //启用数据库 2 webSettings.setDatabaseEnabled(true); 3 String dir = this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath(); 5 //启用地理定位 6 webSe...

Highcharts使用=====通过指定日期显示曲线

1、说明:     利用HighStock显示曲线,在右上角的日期间隔选择好日期后,重新请求后台数据,重新加载曲线。 2、实现方法:     在HighStock的rangeSelector中有一个属性inputDateParser,在这里面可以定义一个回调函数,当输入完日期后,会调用这个函数。 3、日期的取得:     右键查看元素可知,开始日期的inp...

CVE20187600 Drupal核心远程代码执行漏洞分析

0x01 漏洞介绍 Drupal是一个开源内容管理系统(CMS),全球超过100万个网站(包括政府,电子零售,企业组织,金融机构等)使用。两周前,Drupal安全团队披露了一个非常关键的漏洞,编号CVE-2018-7600 Drupal对表单请求内容未做严格过滤,因此,这使得攻击者可能将恶意注入表单内容,此漏洞允许未经身份验证的攻击者在默认或常见的Drup...

websql的添加和查询

openDatabase 我们可以使用这样简单的一条语句,创建或打开一个本地的数据库对象 vardb =openDatabase('testDB','1.0','Test DB',2*1024*1024); 复制 openDatabase接收五个参数: 数据库名字 数据库版本号 显示名字 数据库保存数据的大小(以字节为单位 ) 回调函数(非必须)...