开篇语:

由于业务需求,我们采用了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预初始化相关推荐

  1. 3,引擎预初始化(2,ue4模块初始化)(8.3大象无形)

    现在看看预初始化时,加载了哪些模块. 这些模块分为五部分 一,加载核心模块,即CoreUObject. 二,在初始化引擎之前加载模块FEngineLoop::LoadPreInitModules() ...

  2. 3,预初始化(一)(大象无形9.2)

    正如书中所说,预初始化流程由FEngineLoop::PreInit()所实现 主要处理流程 1,设置路径:当前程序路径,当前工作目录路径,游戏的工程路径 2,设置标准输出:设置GLog系统输出的设备 ...

  3. 【转】Flex Application 初始化顺序

    转自:http://www.jexchen.com 大家都知道,我们在编写Flex应用程序时,通常是以<mx:Application>标签作为开头,实际上,Flex应用程序在启动运行的时候 ...

  4. WKWebView 的使用简介

    1. navigationDelegate [objc] view plaincopy print? - (void)webView:(WKWebView *)webView didStartProv ...

  5. [Spring 深度解析]第7章 IoC容器的初始化过程

    7. IoC容器的初始化过程 ​ 简单来说,IoC容器的初始化是由前面介绍的refresh()方法来启动的,这个方法标志着IoC容器的正式启动.具体来说,这个启动包括BeanDefinition的Re ...

  6. IOS进阶之WKWebView

    前言 Xcode8发布以后,编译器开始不支持IOS7,所以很多应用在适配IOS10之后都不在适配IOS7了,其中包括了很多大公司,网易新闻,滴滴出行等.因此,我们公司的应用也打算淘汰IOS7. 支持到 ...

  7. 5首页加载慢_UIViewController 预加载方案浅谈

    作者 | hite,目前在网易严选iOS 组,主要工作内容 webview 相关,业余时间会写一些胡思乱想产品策划稿,各类游戏云玩家. 一. 引子 预加载作为常规性能优化手段,在所有性能敏感的场景都有 ...

  8. finishBeanFactoryInitialization 处理预实例化Bean

    当Bean 定义资源被载入IOC 容器之后, 容器将Bean 定义资源解析为容器内部的数据结构BeanDefinition 注册到容器中,AbstractApplicationContext 类中的f ...

  9. SQLite和NPoco的数据库初始化器

    目录 介绍 IDbInitialiser IDatabaseConfigurator 示例实现 注意事项 下载源代码 - 49.7 KB 介绍 这篇文章是在我创建一个小型博客风格的Web应用程序时出现 ...

最新文章

  1. Git npm相关命令
  2. DDoS攻击已成掩盖真实网络攻击的烟雾弹
  3. [Spring cloud 一步步实现广告系统] 10. 使用Ribbon 实现微服务调用
  4. poj 3662 Telephone Lines(好题!!!二分搜索+dijkstra)
  5. html批量翻译 github,英文单词短语批量翻译工具WordListTranslator
  6. EAI的Spring集成教程
  7. c语言加密shell脚本,shell脚本加密
  8. dax powerbi 生成表函数_Power BI应用技巧:如何为DAX建的表添加索引?
  9. vue快速复制快捷键_vue快捷键.doc
  10. extern ,extern C 与 __cplusplus
  11. 学计算机的用hd620,HD620核显相当于什么独立显卡 HD620核心显卡性能评测
  12. vivox9系统基于Android,vivo X9
  13. 小学期 BlueSky学长与友人帐
  14. Traffic Shifting
  15. 深入理解朴素贝叶斯(Naive Bayes)
  16. 如何在高德地图windowInfo弹窗中使用VUE组件
  17. matlab 理想变压器,Simscape Electrical
  18. 【学习笔记】Splay
  19. java List 根据某个字段进行升降序排列
  20. Springboot实战项目---从需求分析到项目部署一站式开发,给简历添加一点色彩

热门文章

  1. 水上乐园设备的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  2. android 开游艇游戏,游艇狂飙游戏-游艇狂飙安卓版预约_第一手游网
  3. 使用Python连接Redis集群
  4. 资产管理运维一体化 接入IOT、BIM的设备数字智慧化管理
  5. 深入浅出Zookeeper集群搭建
  6. Help Hanzo LightOJ - 1197
  7. 类似于萝卜书摘的书摘app推荐
  8. 剑指Offe面试题:用两个栈实现队列
  9. linux C-kermit 安装使用
  10. Mockplus: 让小白产品经理上手就用的原型图设计工具