WKWebView预初始化
開篇語:
由于業(yè)務(wù)需求,我們采用了WKWebView和其它view混合布局的展現(xiàn)方案。如果你的WKWebView個數(shù)不多,例如同一個頁面不超過3個WKWebView,是很難發(fā)現(xiàn)這個瓶頸問題。不是內(nèi)存占用太多,是init確實占用太多主線程時間。如果你嘗試異步初始化WKWebView發(fā)現(xiàn)是不行的,init必須在主線程中執(zhí)行。這就導(dǎo)致如果一個頁面同時需要多個WKWebView,會產(chǎn)生卡頓問題(當(dāng)然,新款設(shè)備CPU性能強悍,和老設(shè)備對比非常明顯)。
方案:
船到橋頭自然直,車到山前必有路…… 既然躲不過,那就直接面對吧!解決方法就是預(yù)初始化N個WKWebView備用,當(dāng)使用的時候,直接設(shè)置HTML。那,預(yù)初始化的時候不會卡主線程嗎?當(dāng)然會,不過我們可以將這個過程放到頁面加載(網(wǎng)絡(luò)請求轉(zhuǎn)圈圈)的地方,也就是犧牲用戶網(wǎng)速體驗,提升頁面渲染速度。總體下來,我感覺加載變流暢了呢?,畢竟更多的人已經(jīng)習(xí)慣了網(wǎng)絡(luò)加載緩慢,反而更關(guān)心頁面流暢度。況且,根據(jù)實際測試,初始化20個WKWebView的時間也就1秒--1.5秒(都是針對老設(shè)備而言的),新款設(shè)備基本體驗不出差別。
說了這么多,無非就是寫一個WKWebView池,必要的時間點初始化N個WKWebView,用的時候直接拿即可。如果池中的WKWebView不夠用了,那就用一個初始化一個,反正都在主線程,沒必要再預(yù)初始化更多了。
實現(xiàn):
簡單實現(xiàn),一個單例管理所有預(yù)初始化的WKWebView。
HXWKWebViewPool.h
#import <Foundation/Foundation.h> #import <WebKit/WebKit.h>@interface HXWKWebViewPool : NSObject+ (instancetype)sharedInstance;/**預(yù)初始化若干WKWebView@param count 個數(shù)*/ - (void)prepareWithCount:(NSUInteger)count;/**從池中獲取一個WKWebView@return WKWebView*/ - (WKWebView *)getWKWebViewFromPool;@endHXWKWebViewPool.m
#import "HXWKWebViewPool.h"@interface HXWKWebViewPool ()@property (nonatomic) NSUInteger initialViewsMaxCount; //最多初始化的個數(shù) @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; }/**預(yù)初始化若干WKWebView@param count 個數(shù)*/ - (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;} }/**創(chuàng)建一個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];//根據(jù)自己的業(yè)務(wù)需求初始化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使用的時候,根據(jù)業(yè)務(wù)需求提前預(yù)初始化?prepareWithCount:多個WKWebView。使用是時候直接調(diào)用單例的getWKWebViewFromPool 得到一個WKWebView即可。
實際測試中,發(fā)現(xiàn)頁面渲染實際縮短了一倍,舊款設(shè)備提升明顯。
?
相關(guān)文章:讓你的WKWebView支持自動布局----Auto Layout
?
?
?
總結(jié)
以上是生活随笔為你收集整理的WKWebView预初始化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习和人工智能的关系
- 下一篇: easyexcel复杂模板导出(合并行列