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系统的内存消耗相比可以说是很低。

二.优化

来源:WebView性能、体验分析与优化 - CSDN博客


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

当使用loadRequest来读取本地的HTML时,WKWebView是无法读取成功的,后台会出现如下的提示:

Could not create a sandbox extension for /

原因是WKWebView是不允许通过loadRequest的方法来加载本地根目录的HTML文件

而在iOS9的SDK中加入了以下方法来加载本地的HTML文件:

[WKWebView loadFileURL:allowingReadAccessToURL:]

但是在iOS9以下的版本是没提供这个便利的方法的。以下为解决方案的思路,就是在iOS9以下版本时,先将本地HTML文件的数据copy到tmp目录中,然后再使用loadRequest来加载。但是如果在HTML中加入了其他资源文件,例如js,css,image等必须一同copy到temp中。这个是最蛋疼的事情了。


链接:https://www.jianshu.com/p/ccb421c85b2e


5、关于 NSURLProtocol 拦截

WKWebView 基于 WebKit 框架,与 UIWebView 机制不同:加载过程中所有的请求都不经过 NSURLProtocol,换句话说就是 WKWebView 无法拦截响应数据 鉴于之前大部分 Hybrid 框架的离线预加载机制都依赖于拦截功能,这意味着废掉很多程序猿们辛辛苦苦设计实现的 Hybrid 框架

6.不支持捏合手势

7.post请求的坑

post请求多个参数 iOS9 失败

使用NSURLSession发送一个请求,然后把请求下来的数据当作本地HTML加载

8.跨域问题

你可能感兴趣的:(wkwebview的坑和优化)