WKWebView预初始化
开篇语:
由于业务需求,我们采用了WKWebView和其它view混合布局的展现方案。如果你的WKWebView个数不多,例如同一个页面不超过3个WKWebView,是很难发现这个瓶颈问题。不是内存占用太多,是init确实占用太多主线程时间。如果你尝试异步初始化WKWebView发现是不行的,init必须在主线程中执行。这就导致如果一个页面同时需要多个WKWebView,会产生卡顿问题(当然,新款设备CPU性能强悍,和老设备对比非常明显)。
方案:
船到桥头自然直,车到山前必有路…… 既然躲不过,那就直接面对吧!解决方法就是预初始化N个WKWebView备用,当使用的时候,直接设置HTML。那,预初始化的时候不会卡主线程吗?当然会,不过我们可以将这个过程放到页面加载(网络请求转圈圈)的地方,也就是牺牲用户网速体验,提升页面渲染速度。总体下来,我感觉加载变流畅了呢?,毕竟更多的人已经习惯了网络加载缓慢,反而更关心页面流畅度。况且,根据实际测试,初始化20个WKWebView的时间也就1秒--1.5秒(都是针对老设备而言的),新款设备基本体验不出差别。
说了这么多,无非就是写一个WKWebView池,必要的时间点初始化N个WKWebView,用的时候直接拿即可。如果池中的WKWebView不够用了,那就用一个初始化一个,反正都在主线程,没必要再预初始化更多了。
实现:
简单实现,一个单例管理所有预初始化的WKWebView。
HXWKWebViewPool.h
#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>@interface HXWKWebViewPool : NSObject+ (instancetype)sharedInstance;/**预初始化若干WKWebView@param count 个数*/
- (void)prepareWithCount:(NSUInteger)count;/**从池中获取一个WKWebView@return WKWebView*/
- (WKWebView *)getWKWebViewFromPool;@end
HXWKWebViewPool.m
#import "HXWKWebViewPool.h"@interface HXWKWebViewPool ()@property (nonatomic) NSUInteger initialViewsMaxCount; //最多初始化的个数
@property (nonatomic) NSMutableArray *preloadedViews;@end@implementation HXWKWebViewPool+ (instancetype)sharedInstance {static dispatch_once_t onceToken;static HXWKWebViewPool *instance = nil;dispatch_once(&onceToken,^{instance = [[super allocWithZone:NULL] init];});return instance;
}+ (id)allocWithZone:(struct _NSZone *)zone{return [self sharedInstance];
}- (instancetype)init
{self = [super init];if (self) {self.initialViewsMaxCount = 20;self.preloadedViews = [NSMutableArray arrayWithCapacity:self.initialViewsMaxCount];}return self;
}/**预初始化若干WKWebView@param count 个数*/
- (void)prepareWithCount:(NSUInteger)count {NSTimeInterval start = CACurrentMediaTime();// Actually does nothing, only initialization must be called.while (self.preloadedViews.count < MIN(count,self.initialViewsMaxCount)) {id preloadedView = [self createPreloadedView];if (preloadedView) {[self.preloadedViews addObject:preloadedView];} else {break;}}NSTimeInterval delta = CACurrentMediaTime() - start;NSLog(@"=======初始化耗时:%f", delta);
}/**从池中获取一个WKWebView@return WKWebView*/
- (WKWebView *)getWKWebViewFromPool {if (!self.preloadedViews.count) {NSLog(@"不够啦!");return [self createPreloadedView];} else {id preloadedView = self.preloadedViews.firstObject;[self.preloadedViews removeObject:preloadedView];return preloadedView;}
}/**创建一个WKWebView@return WKWebView*/
- (WKWebView *)createPreloadedView {WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];WKUserContentController *wkUController = [[WKUserContentController alloc] init];wkWebConfig.userContentController = wkUController;WKWebView *wkWebView = [[WKWebView alloc]initWithFrame:CGRectZero configuration:wkWebConfig];//根据自己的业务需求初始化WKWebViewwkWebView.opaque = NO;wkWebView.scrollView.scrollEnabled = NO;wkWebView.scrollView.showsVerticalScrollIndicator = NO;wkWebView.scrollView.scrollsToTop = NO;wkWebView.scrollView.userInteractionEnabled = NO;if (@available(iOS 11.0,*)) {wkWebView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;}wkWebView.scrollView.bounces = NO;wkWebView.backgroundColor = [UIColor clearColor];return wkWebView;
}@end
使用的时候,根据业务需求提前预初始化 prepareWithCount:多个WKWebView。使用是时候直接调用单例的getWKWebViewFromPool 得到一个WKWebView即可。
实际测试中,发现页面渲染实际缩短了一倍,旧款设备提升明显。
相关文章:让你的WKWebView支持自动布局----Auto Layout
WKWebView预初始化相关推荐
- 3,引擎预初始化(2,ue4模块初始化)(8.3大象无形)
现在看看预初始化时,加载了哪些模块. 这些模块分为五部分 一,加载核心模块,即CoreUObject. 二,在初始化引擎之前加载模块FEngineLoop::LoadPreInitModules() ...
- 3,预初始化(一)(大象无形9.2)
正如书中所说,预初始化流程由FEngineLoop::PreInit()所实现 主要处理流程 1,设置路径:当前程序路径,当前工作目录路径,游戏的工程路径 2,设置标准输出:设置GLog系统输出的设备 ...
- 【转】Flex Application 初始化顺序
转自:http://www.jexchen.com 大家都知道,我们在编写Flex应用程序时,通常是以<mx:Application>标签作为开头,实际上,Flex应用程序在启动运行的时候 ...
- WKWebView 的使用简介
1. navigationDelegate [objc] view plaincopy print? - (void)webView:(WKWebView *)webView didStartProv ...
- [Spring 深度解析]第7章 IoC容器的初始化过程
7. IoC容器的初始化过程 简单来说,IoC容器的初始化是由前面介绍的refresh()方法来启动的,这个方法标志着IoC容器的正式启动.具体来说,这个启动包括BeanDefinition的Re ...
- IOS进阶之WKWebView
前言 Xcode8发布以后,编译器开始不支持IOS7,所以很多应用在适配IOS10之后都不在适配IOS7了,其中包括了很多大公司,网易新闻,滴滴出行等.因此,我们公司的应用也打算淘汰IOS7. 支持到 ...
- 5首页加载慢_UIViewController 预加载方案浅谈
作者 | hite,目前在网易严选iOS 组,主要工作内容 webview 相关,业余时间会写一些胡思乱想产品策划稿,各类游戏云玩家. 一. 引子 预加载作为常规性能优化手段,在所有性能敏感的场景都有 ...
- finishBeanFactoryInitialization 处理预实例化Bean
当Bean 定义资源被载入IOC 容器之后, 容器将Bean 定义资源解析为容器内部的数据结构BeanDefinition 注册到容器中,AbstractApplicationContext 类中的f ...
- SQLite和NPoco的数据库初始化器
目录 介绍 IDbInitialiser IDatabaseConfigurator 示例实现 注意事项 下载源代码 - 49.7 KB 介绍 这篇文章是在我创建一个小型博客风格的Web应用程序时出现 ...
最新文章
- Git npm相关命令
- DDoS攻击已成掩盖真实网络攻击的烟雾弹
- [Spring cloud 一步步实现广告系统] 10. 使用Ribbon 实现微服务调用
- poj 3662 Telephone Lines(好题!!!二分搜索+dijkstra)
- html批量翻译 github,英文单词短语批量翻译工具WordListTranslator
- EAI的Spring集成教程
- c语言加密shell脚本,shell脚本加密
- dax powerbi 生成表函数_Power BI应用技巧:如何为DAX建的表添加索引?
- vue快速复制快捷键_vue快捷键.doc
- extern ,extern C 与 __cplusplus
- 学计算机的用hd620,HD620核显相当于什么独立显卡 HD620核心显卡性能评测
- vivox9系统基于Android,vivo X9
- 小学期 BlueSky学长与友人帐
- Traffic Shifting
- 深入理解朴素贝叶斯(Naive Bayes)
- 如何在高德地图windowInfo弹窗中使用VUE组件
- matlab 理想变压器,Simscape Electrical
- 【学习笔记】Splay
- java List 根据某个字段进行升降序排列
- Springboot实战项目---从需求分析到项目部署一站式开发,给简历添加一点色彩