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;@endHXWKWebViewPool.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预初始化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习和人工智能的关系
- 下一篇: easyexcel复杂模板导出(合并行列