
本文对比的是 UIWebView、WKWebView、flutter_webview_plugin(在iOS中使用的是WKWebView)的加载速度,内存使用情况。
测试网页打开的速度,只需要获取 WebView 在开始加载网页和网页加载完成时的时间戳,时间戳的差即为打开网页的时间
为了使差异更明显,我们选择较为复杂的 新浪首页 进行加载的对比,为了减小网络对加载速度的影响,我们让手机连接同一个网络,分别进行 10 次测试然后取平均值,另外,我们需要关闭 WebView 的缓存,防止缓存对加载速度产生影响
下面使笔者进行 10 次测试所得到的数据
结果让我有点惊讶,一直以为 WKWebView 会是个王者。结果看,速度上 WKWebView 略慢一点,不过总体差异不大(该结果仅仅是测试新浪的结果,仅供参考啦)
在这里,笔者又加了一个测试,尝试记录从 viewController 的 viewDidLoad 到 webview 的 didFinish 时间,测试了新浪的数据,如下:
UIWebViewA : 4970、3808、3815、4250、3556 avg(40798) (加载完所有页面)
UIWebViewB : 4103、3124、3070、3256、2835 avg(32776)(加载sina完毕)
WKWebView : 3672、3032、2892、2912、2739 avg(30494)
flutter_webView : 4532、3901、4310、3496、3378 avg(39234)
其中可以看到,webView 有两行,UIWebViewB 的数据就是加载 sina 主站的时间;UIWebViewA 的数据是因为在加载完 sina 主站之后,新浪又加载了一个 >
随着苹果爸爸强制推动WKWebView替代UIWebView,各旧项目的替换工作随之而来,据说在2020年12月31日前未将UIWebView替换成WKWebView的项目将会被下架,而新项目在初次上线审核就会被卡。
那么WKWebView究竟好在哪里呢?
步骤:
解决方式
方式一
方式二
参考文章: >
1HTML5 , Manifest最开始我的想法是使用HTML5中的离线存储功能,也就是分析Manifest文件来存储和更新部分资源文件。但是经过实践发现,UIWebView根本不支持HTML5,他只实现了Webkit中页面渲染的那一部分。所以要实现缓存必须要另辟蹊径。2NSURLCache 尽管在官方的说明文档里面说到NSURLCache和NSCachedURLResponse可以用于缓存,但经我测试好像仅仅只能用于加载本地某些资源文件(这里有一篇博客,原文是英文的,这是翻译过来的),而且还有大小的限制(好像根据iphone的版本不同而不同,最小是25KB吧),比如和JS代码, 而对于整体的页面无法进行加载。而且经过测试也没有感觉加载速度有明显的提高,我用的缓存策略是NSURLRequestReturnCacheDataElseLoad(可能是没有读取本地的缓存文件?),离线模式下也无法加载(可能是baseURL的关系?)。这找到一篇博客,一种新的解决思路,经过我测试,可以很好的实现缓存。另外做一点引申,对于动态获取数据的页面,我们不需要缓存的那些请求,只要过滤掉就可以了。先新建一个文件,把所有不需要缓存的请求的URL写在一个文件里,就象HTML5的 Cache Manifest那样。然后需要使用缓存的时候读取这个文件,并在重写的- (NSCachedURLResponse )cachedResponseForRequest:(NSURLRequest )request 这个方法内对请求进行判断,如果是属于这个文件内的,比如web service的请求就直接返回,其他的就继续处理。
WKWebView是苹果在iOS 8之后推出的框架,关于它比webview的优势这里就不讲了。主要说一下与JS交互的问题,其实WKWebView已经内置了JS与OC的互调、传值等方法,使用起来也非常方便,下面就来细细的探讨一下以及自己遇到过的坑
首先来看下WKWebView的初始化相关设置:
一、导入相关头文件、设置相关代理和属性
二、WKWebView初始化
注意:
楼主遇到的第一个坑:如果JS给OC传值为空,必须写成: postMessage(null),如果什么都不写,方法是调不通的。
1、在viewWillAppear中配置, addScriptMessageHandler name: "这里就是JS的方法,方法名必须统一"
楼主遇到的第二个坑:配置完后必须在 viewWillDisappear 中 remove,否则会造成循环引用,导致crash
2、实现 WKScriptMessageHandler 协议
以上就是JS调OC,JS向OC传值
楼主这里举三个例子:
1: webview加载完成前,将用户信息传给js
2: webview加载完成,将相关信息传给js
3: 调用相册或相机时,将选择的请求后台接口,后台返回地址,将该地址回传给H5,H5将显示到页面上
第一个例子: webView加载完成前传值
因为 evaluateJavaScript 方法默认是在加载完成后调用,所以直接在页面开始加载中调用是传不过去的,这个时候怎么办呢? 我们可以让js端写两个方法, 第一个方法是js端开始向oc端发起信息需求的方法名,当oc端收到该方法名的时候,就去调用js端第二个获取传值的方法,把信息传递过去。
先让JS端写个方法调OC,OC实现方法后在这个方法内部给JS传值
在WKScriptMessageHandler协议中,实现该方法,然后在方法内部给JS传值
注意: 以上就是在Webview加载完成前传值,如果打印没报错,证明传参成功,如果web端没收到,让他把获取到值的方法写到页面中即可。
第二个例子: webView加载完成,传值给js
第三个例子: 传地址给js,js拿到后显示
1:拍照事件
11:将拍的照片请求上传接口,成功返回地址,并传值给H5
2: 从相册中选取照片
22:将相册中选取的照片请求上传接口,成功返回地址,并传值给H5
注意: getPhotoCallback 即为调用的方法名,后面传值格式必须为: ('') , 这里遇到了第三个坑, 如果方法名写为: 名称名称 (例如:hello getPhotoCallback),这种是调不通的,可以写成hello_getPhotoCallback的形式,一般的话最好还是定义一个完整的名称。 刚开始这个问题卡了比较久,一直调不通,在此记录一下
在 viewDidLoad 中注册进度条监听
开始加载网页
加载完成
加载失败
页面跳转失败
progressView懒加载
添加监听观察者
最后别忘记 removeObserver
Demo地址: >
用第三方合作平台,将html5和页面素材先上传到第三方服务端,也可以在微信平台通过文字或链接跳转的形式,实现html5页面的转换。
自从微信升级 X5 Blink内核之后,兼容性大大好转。IOS虽说没有升级统一为同一版本的内核,但IOS版本的微信一直是WKWebView内核,WKWebView的版本依赖于IOS的版本。
IOS 80以上的系统,对Html5和css3的支持率也很高,基本的H5,CSS3的特性均得到支持,测试中有详细数据。
万维网的核心语言、标准通用标记语言下的一个应用超文本标记语言(HTML)的第五次重大修改(这是一项推荐标准、外语原文:W3C Recommendation、见本处参考资料原文内容:)。
2014年10月29日,万维网联盟宣布,经过接近8年的艰苦努力,该标准规范终于制定完成。
以上就是关于Flutter 与 iOS 原生 webView 对比全部的内容,包括:Flutter 与 iOS 原生 webView 对比、iOS 正确的修改User-Agent、WKWebView加载本地Web项目文件(WKWebView离线加载)及带参数请求等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)