wkwebview的坑和优化
一.wkwebview 和UIWebView的区别
WKWebView iOS(8.0) 用以替代 UIKit 中笨重难用、内存泄漏的 UIWebView。WKWebView 拥有60fps滚动刷新率、和 safari 相同的 JavaScript 引擎等优势。
1、在性能、稳定性、功能方面有很大提升(加载速度,内存的提升谁用谁知道)
2、更多的支持 HTML5 的特性
3、官方宣称的高达60fps的滚动刷新率以及内置手势
4、Safari 相同的 JavaScript 引擎
5、将 UIWebViewDelegate 与 UIWebView 拆分成了14类与3个协议,包含该更细节功能的实现。
UIWebView和Android的WebView在首次初始化时都要消耗大量内存,之后每次新建WebView会额外增加一些。
UIWebView的内存占用不会在关闭WebView时主动回收,每次新开WebView都会消耗额外内存。
相比于性能,对于内存的优化可以做的还是比较有限的。
WKWebView的内存占用优势比较大(代价是初始化比较慢)。
页面内代码消耗的内存相比与WebView系统的内存消耗相比可以说是很低。
二.优化
1.启动时间慢
从第一次打开wkwebview 到网络请求时间,和再次打开的时间都比uiwebview长
原因:当App首次打开时,默认是并不初始化浏览器内核的;只有当创建WebView实例的时候,才会创建WebView的基础框架。所以与浏览器不同,App中打开WebView的第一步并不是建立连接,而是启动浏览器内核。
解决方案:
在客户端刚启动时,就初始化一个全局的WebView待用,并隐藏;
当用户访问了WebView时,直接使用这个WebView加载对应网页,并展示。
这种方法可以比较有效的减少WebView在App中的首次打开时间。当用户访问页面时,不需要初始化WebView的时间。
当然这也带来了一些问题,包括:额外的内存消耗。页面间跳转需要清空上一个页面的痕迹,更容易内存泄露。
2.数据请求:
在初始化的同时,通过Native来完成一些网络请求等过程,使得WebView初始化不是完全的阻塞后续过程。
3.分块输出
在HTTP协议中,我们可以在header中设置transfer-encoding:chunked使得页面可以分块输出。如果合理设计页面,让head部分都是确定的静态资源版本相关内容,而body部分是业务数据相关内容,那么我们可以在用户请求的时候,首先将Web API可以确定的部分先输出给浏览器,然后等API完全获取后,再将API数据传输给浏览器。
如果采用普通方式输出页面,则页面会在服务器请求完所有API并处理完成后开始传输。浏览器要在后端所有API都加载完成后才能开始解析。
如果采用chunk-encoding: chunked,并优先将页面的静态部分输出;然后处理API请求,并最终返回页面,可以让后端的API请求和前端的资源加载同时进行。
两者的总共后端时间并没有区别,但是可以提升首字节速度,从而让前端加载资源和后端加载API不互相阻塞。
4.本地缓存问题
iOS 9以后可以使用 WKWebsiteDataStore 来清理缓存。iOS 8可以通过清理 Library 目录下的 Cookies 目录来清除缓存,
使用cookie
在使用 UIWebVIew 的时候我们并不关注 Cookie,因为在调用登录接口的时候无论是AFNetworking,还是其他,登录成功之后都会自动保存在
[NSHTTPCookieStorage sharedHTTPCookieStorage].cookies 中,以后再使用也会自动去获取(这里有个 UIWebView 的坑:访问的链接越多,如不处理Cookie,它会加载越来越多的无效 Cookie 导致内容急剧增大)。但 WKWebView 的存储体系与 UIWebVIew 完全不一样,只能手动给它添加 Cookie
5、关于 NSURLProtocol 拦截
WKWebView 基于 WebKit 框架,与 UIWebView 机制不同:加载过程中所有的请求都不经过 NSURLProtocol,换句话说就是 WKWebView 无法拦截响应数据 鉴于之前大部分 Hybrid 框架的离线预加载机制都依赖于拦截功能,这意味着废掉很多程序猿们辛辛苦苦设计实现的 Hybrid 框架
6.不支持捏合手势