WKWebview的内存问题
场景复现
app 中需要加载后台的 HTML 字符串进行展示,解决方案有两个:
- 首先考虑到使用 WKWebview 进行展示;
- 其次考虑到可以使用 libxml2 来解析 HTML之后,将标签处理成富文本,然后在 Label 或者 TextView 上进行展示;
问题:
使用 WKWebView 进行展示固然简单,但是 WKWebView 早就被传言存在内存过大的问题,而且业务中需要展示 5 个 HTML 页面,也就是需要 5 个 WKWebView。
排除掉 HTML 解析的业务复杂性带来的影响,单纯比较富文本展示和 WKWebview 展示的性能,来决定最终方案的取舍,应该怎样进行量化?
阶段一:
实现两种方案之后对比,使用 instrument 观察发现 5个 WKWebView 的 CPU 和内存的使用情况居然只在 2-5M 左右,最多也就 10M,然后使用富文本展示时,基本稳定在 10M 左右,而且会随着 HTML 中图片和 HTML 文本的增多而逐步增多。
疑问:
WKWebView 的性能这么优秀?让安卓端的开发进行测试对比之后发现 WebView 的内存占比达到几百兆,这显然不科学;
解释:
具体链接:https://developer.apple.com/forums/thread/21956
验证:
在模拟器上跑 Demo,然后使用活动监视器查看进程,果然得到验证:
通过上图可以看到,WKWebview 确实开辟了独立的进程来处理任务,具体而言是一个渲染进程和一个网络处理进程,5个 WKWebview 也就创建了 10 个独立的进程;
总结:
- WKWebview 会开辟进程(不是线程)来处理任务;
- 开辟的进程包括一个 content 的渲染进程和一个 networking 的网络处理进程;
- WKWebview 开辟的进程如果在内存超过预算之后,使用 WKWebview 的当前 app 并不会被杀掉,最多就是 WKWebview 展示的页面变成空白页;
备注:
WKWebview 开启进程所占用的内存虽然不会影响当前 app,但是毕竟 iOS 中使用的是共享虚拟内存,当占用内存过大时,必定会影响到 app 的执行效率。如果 WKWebview 没有及时销毁,甚至会发生 CPU 抢占的现象,加剧原 APP 的效率问题;
最终解决方案:
使用 HTML 解析的方式来展示 HTML,毕竟 WKWebview 开辟的内存达到了将近 400M,而解析之后使用富文本展示时,基本在 10M 左右,相差了 40 倍,如果图片较少,图片的解码和 bitmap 加载所占据的内存会更小,总体内存应该还能够更低。