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.跨域问题

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AI阅读 16,357评论 3 119
  • 从废墟上穿越 千年烽烟 我迫不及待地呼吸 干净的空气 干净的文化 干净的人文 神秘的你 不晓得从什么时候开始 让戈...
    博吉琪琪格阅读 229评论 0 1
  • 弯叶泪汪汪,平鼻脸四方。 招风相对望,两鬓染风霜。
    良柳如烟阅读 183评论 7 6
  • 别的城市不知道,但深圳的莲花山公园确实有这样的“相亲角”。 在很多相信感情的人们的眼中,这样的“相亲角”,通常会被...
    流言非愚阅读 1,033评论 0 1
  • 正月时节,原本应该是喜气洋洋,欢天喜地的,可是近几年来,我却不太能感觉到这种气氛了,小时候,会期待新衣服,期待好吃...
    花想容玉行阅读 802评论 4 6

友情链接更多精彩内容