iOS WKWebView白屏(卡顿)

通过腾讯bugly卡顿日志发现,有许多WebKit的卡顿信息,但是却没有定位到项目中的具体代码。通过大量观察发现很多日志中都有调用WebKit::WebPageProxy::processDidTerminate函数或WebKit::WebMemoryPressureHandler::WebMemoryPressureHandler()函数。参考WKWebView代理函数中的- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView;函数成因及含有*Memory*字段,因此大胆猜测可能是WKWebView内存占用过大,内存不足引起。

《WKWebView 那些坑》文章中WKWebView白屏问题小节介绍到在WKWebView上当总体的内存占用比较大的时候,webContent process会crash,从而出现白屏现象。此时系统会调用- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView;函数,在该函数里执行[webView reload] (这个时候webView.URL取值尚不为nil)解决白屏问题。

两者成因皆为WKWebView内存占用过大引起,故本次卡顿解决方式参考WKWebView白屏问题解决方法。

@property (nonatomic ,assign) BOOL webViewLoadTitle;//是否已获取当前webView的title

#pragma mark -

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    if (YES == self.webViewLoadTitle && [NSString isNullDataString:self.webView.title]) {
        //webView已获取title,但返回时无法获取title,可能是内存不足原因造成,此时需重新加载同时避免第一次进入时重新加载
        [self.webView reload];
    }
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    if (![NSString isNullDataString:self.webView.title]) {
        self.webViewLoadTitle = YES;
    }
}

#pragma mark - WKNavigationDelegate

//web内存过大,进程终止,重新加载webView
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
    [webView reload];
}

结果:经生产版本检验,可有效防止WKWebView内存占用过大引起的卡顿问题。

  • 参考文档:WKWebView那些坑

卡顿日志参考

0 WebKit    WebKit::SandboxExtension::HandleArray::HandleArray()
1 WebKit    WebKit::WebProcessCreationParameters::WebProcessCreationParameters() + 36
2 WebKit    WebKit::WebProcessPool::initializeNewWebProcess(WebKit::WebProcessProxy&, WebKit::WebsiteDataStore&) + 156
3 WebKit    WebKit::WebProcessPool::createNewWebProcess(WebKit::WebsiteDataStore&, WebKit::WebProcessProxy::IsInPrewarmedPool) + 60
4 WebKit    WebKit::WebProcessPool::createNewWebProcessRespectingProcessCountLimit(WebKit::WebsiteDataStore&) + 232
5 WebKit    WebKit::WebPageProxy::reattachToWebProcess() + 36
6 WebKit    WebKit::WebPageProxy::reattachToWebProcessForReload() + 52
7 WebKit    WebKit::WebPageProxy::reload(WTF::OptionSet) + 268
8 WebKit    WebKit::WebPageProxy::tryReloadAfterProcessTermination() + 308
9 WebKit    WebKit::WebPageProxy::processDidTerminate(WebKit::ProcessTerminationReason) + 644
10 WebKit   WebKit::WebProcessProxy::processDidTerminateOrFailedToLaunch() + 736
11 WebKit   WebKit::WebProcessProxy::didClose(IPC::Connection&) + 160
12 JavaScriptCore   WTF::RunLoop::performWork() + 276
13 JavaScriptCore   WTF::RunLoop::performWork(void*) + 36
14 CoreFoundation   ___CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
0 libobjc.A.dylib   class_createInstance + 36
1 libobjc.A.dylib   _objc_rootAlloc + 52
2 libobjc.A.dylib   _objc_rootAlloc + 52
3 UIKitCore +[UITextInteraction textInteractionsForSet:] + 36
4 UIKitCore -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) addGestureRecognizersToView:] + 388
5 UIKitCore -[UIWKTextInteractionAssistant addGestureRecognizersToView:] + 68
6 UIKitCore -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) setGestureRecognizers] + 204
7 UIKitCore -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) initWithView:textInteractionSet:] + 124
8 UIKitCore -[UIWKTextInteractionAssistant initWithView:] + 44
9 WebKit    -[WKContentView(WKInteraction) setUpTextSelectionAssistant] + 92
10 WebKit   -[WKContentView(WKInteraction) setupInteraction] + 1356
11 WebKit   WebKit::PageClientImpl::didRelaunchProcess() + 36
12 WebKit   WebKit::WebPageProxy::reattachToWebProcess(WTF::Ref >&&, API::Navigation*, WebKit::WebPageProxy::ReattachForBackForward) + 912
13 WebKit   WebKit::WebPageProxy::reattachToWebProcess() + 80
14 WebKit   WebKit::WebPageProxy::reattachToWebProcessForReload() + 52
15 WebKit   WebKit::WebPageProxy::reload(WTF::OptionSet) + 268
16 WebKit   WebKit::WebPageProxy::tryReloadAfterProcessTermination() + 308
17 WebKit   WebKit::WebPageProxy::processDidTerminate(WebKit::ProcessTerminationReason) + 644
18 WebKit   WebKit::WebProcessProxy::processDidTerminateOrFailedToLaunch() + 736
19 WebKit   WebKit::WebProcessProxy::didClose(IPC::Connection&) + 160
20 JavaScriptCore   WTF::RunLoop::performWork() + 276
21 JavaScriptCore   WTF::RunLoop::performWork(void*) + 36
22 CoreFoundation   ___CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
0 WebKit    0x00000001c05f4000 + 4428800
1 WebKit    WebKit::ViewSnapshotStore::singleton() + 52
2 WebKit    _ZN3WTF8FunctionIFvNS_8CriticalENS_11SynchronousEEE15CallableWrapperIZN6WebKit28installMemoryPressureHandlerEvE3$_0E4callES1_S2_ + 24
3 JavaScriptCore    WTF::MemoryPressureHandler::releaseMemory(WTF::Critical, WTF::Synchronous) + 92
4 JavaScriptCore    ___ZN3WTF21MemoryPressureHandler7installEv_block_invoke_2 + 140
0 libsystem_kernel.dylib    kevent_id + 8
1 libdispatch.dylib __dispatch_kq_poll + 332
2 libdispatch.dylib __dispatch_event_loop_wait_for_ownership$VARIANT$mp + 412
3 libdispatch.dylib ___DISPATCH_WAIT_FOR_QUEUE__ + 296
4 libdispatch.dylib __dispatch_sync_f_slow + 140
5 AssertionServices -[BKSAssertion setInvalidationHandler:] + 144
6 WebKit    WebKit::ProcessAssertion::ProcessAssertion(int, WebKit::AssertionState, WTF::Function&&) + 472
7 WebKit    WebKit::ProcessAndUIAssertion::ProcessAndUIAssertion(int, WebKit::AssertionState) + 96
8 WebKit    WebKit::ProcessThrottler::didConnectToProcess(int) + 224
9 WebKit    WebKit::WebProcessProxy::didFinishLaunching(WebKit::ProcessLauncher*, IPC::Connection::Identifier) + 576
10 WebKit   WebKit::ProcessLauncher::didFinishLaunchingProcess(int, IPC::Connection::Identifier) + 124
11 WebKit   ___ZN6WebKit15ProcessLauncher13launchProcessEv_block_invoke + 136
12 libxpc.dylib __xpc_connection_reply_callout + 60
0 WebKit    -[WKContentView(WKInteraction) isEditable]
1 UIKitCore -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) addGestureRecognizersToView:] + 120
2 UIKitCore -[UIWKTextInteractionAssistant addGestureRecognizersToView:] + 68
3 UIKitCore -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) setGestureRecognizers] + 200
4 UIKitCore -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) initWithView:textInteractionSet:] + 124
5 UIKitCore -[UIWKTextInteractionAssistant initWithView:] + 44
6 WebKit    -[WKContentView(WKInteraction) setUpTextSelectionAssistant] + 92
7 WebKit    -[WKContentView(WKInteraction) setupInteraction] + 1636
8 WebKit    WebKit::PageClientImpl::didRelaunchProcess() + 36
9 WebKit    WebKit::WebPageProxy::finishAttachingToWebProcess(WebKit::WebPageProxy::ShouldInitializeWebPage) + 460
10 WebKit   WebKit::WebPageProxy::reattachToWebProcess() + 388
11 WebKit   WebKit::WebPageProxy::reattachToWebProcessForReload() + 348
12 WebKit   WebKit::WebPageProxy::reload(WTF::OptionSet) + 436
13 WebKit   WebKit::WebPageProxy::tryReloadAfterProcessTermination() + 272
14 WebKit   WebKit::WebPageProxy::dispatchProcessDidTerminate(WebKit::ProcessTerminationReason) + 268
15 WebKit   WebKit::WebPageProxy::processDidTerminate(WebKit::ProcessTerminationReason) + 684
16 WebKit   WebKit::WebProcessProxy::processDidTerminateOrFailedToLaunch() + 916
17 WebKit   WebKit::WebProcessProxy::didClose(IPC::Connection&) + 140
18 JavaScriptCore   WTF::RunLoop::performWork() + 340
19 JavaScriptCore   WTF::RunLoop::performWork(void*) + 36
20 CoreFoundation   0x000000023a172000 + 700188
0 WebKit    API::Navigation::Navigation(WebKit::WebNavigationState&)
1 WebKit    WebKit::WebNavigationState::createReloadNavigation() + 44
2 WebKit    WebKit::WebPageProxy::reattachToWebProcessForReload() + 372
3 WebKit    WebKit::WebPageProxy::reload(WTF::OptionSet) + 436
4 WebKit    WebKit::WebPageProxy::tryReloadAfterProcessTermination() + 272
5 WebKit    WebKit::WebPageProxy::dispatchProcessDidTerminate(WebKit::ProcessTerminationReason) + 268
6 WebKit    WebKit::WebPageProxy::processDidTerminate(WebKit::ProcessTerminationReason) + 684
7 WebKit    WebKit::WebProcessProxy::processDidTerminateOrFailedToLaunch() + 916
8 WebKit    WebKit::WebProcessProxy::didClose(IPC::Connection&) + 140
9 JavaScriptCore    WTF::RunLoop::performWork() + 276
10 JavaScriptCore   WTF::RunLoop::performWork(void*) + 36
0 WebKit    WTF::Mapper WTF::copyToVectorOf > >(WTF::HashSet > const&)::'lambda'(WTF::String const&), WTF::HashSet > const&, void>::map(WTF::HashSet > const&, WTF::Vector WTF::copyToVectorOf > >(WTF::HashSet > const&)::'lambda'(WTF::String const&) const&)
1 WebKit    WebKit::WebProcessPool::initializeNewWebProcess(WebKit::WebProcessProxy&, WebKit::WebsiteDataStore&) + 836
2 WebKit    WebKit::WebProcessPool::createNewWebProcess(WebKit::WebsiteDataStore&, WebKit::WebProcessProxy::IsPrewarmed) + 84
3 WebKit    WebKit::WebProcessPool::createNewWebProcessRespectingProcessCountLimit(WebKit::WebsiteDataStore&) + 228
4 WebKit    WebKit::WebPageProxy::reattachToWebProcess() + 252
5 WebKit    WebKit::WebPageProxy::reattachToWebProcessForReload() + 348
6 WebKit    WebKit::WebPageProxy::reload(WTF::OptionSet) + 436
7 WebKit    WebKit::WebPageProxy::tryReloadAfterProcessTermination() + 272
8 WebKit    WebKit::WebPageProxy::dispatchProcessDidTerminate(WebKit::ProcessTerminationReason) + 268
9 WebKit    WebKit::WebPageProxy::processDidTerminate(WebKit::ProcessTerminationReason) + 684
10 WebKit   WebKit::WebProcessProxy::processDidTerminateOrFailedToLaunch() + 916
11 WebKit   WebKit::WebProcessProxy::didClose(IPC::Connection&) + 140
12 JavaScriptCore   WTF::RunLoop::performWork() + 340
13 JavaScriptCore   WTF::RunLoop::performWork(void*) + 36
0 WebKit    WebKit::ViewSnapshotStore::singleton()
1 WebKit    invocation function for block in WebKit::WebMemoryPressureHandler::WebMemoryPressureHandler() + 12
2 libdispatch.dylib __dispatch_client_callout + 16
0 WebKit    WebKit::SecItemShimProxy::singleton()
1 WebKit    WebKit::WebProcessProxy::connectionWillOpen(IPC::Connection&) + 48
2 WebKit    WebKit::ChildProcessProxy::didFinishLaunching(WebKit::ProcessLauncher*, IPC::Connection::Identifier) + 196
3 WebKit    WebKit::WebProcessProxy::didFinishLaunching(WebKit::ProcessLauncher*, IPC::Connection::Identifier) + 96
4 WebKit    WebKit::ProcessLauncher::didFinishLaunchingProcess(int, IPC::Connection::Identifier) + 124
5 WebKit    ___ZN6WebKit15ProcessLauncher13launchProcessEv_block_invoke + 136
6 libxpc.dylib  __xpc_connection_reply_callout + 60
0 WebCore   WebCore::HTTPHeaderMap::HTTPHeaderMap() + 0
1 WebKit    WebCore::ResourceRequestBase::ResourceRequestBase(WTF::URL const&, WebCore::ResourceRequestCachePolicy) + 152
2 WebKit    WebCore::ResourceRequest::ResourceRequest() + 48
3 WebKit    API::Navigation::Navigation(WebKit::WebNavigationState&) + 64
4 WebKit    WebKit::WebNavigationState::createReloadNavigation() + 44
5 WebKit    WebKit::WebPageProxy::reattachToWebProcessForReload() + 372
6 WebKit    WebKit::WebPageProxy::reload(WTF::OptionSet) + 436
7 WebKit    WebKit::WebPageProxy::tryReloadAfterProcessTermination() + 272
8 WebKit    WebKit::WebPageProxy::dispatchProcessDidTerminate(WebKit::ProcessTerminationReason) + 268
9 WebKit    WebKit::WebPageProxy::processDidTerminate(WebKit::ProcessTerminationReason) + 684
10 WebKit   WebKit::WebProcessProxy::processDidTerminateOrFailedToLaunch() + 916
11 WebKit   WebKit::WebProcessProxy::didClose(IPC::Connection&) + 140
12 JavaScriptCore   WTF::RunLoop::performWork() + 340
13 JavaScriptCore   WTF::RunLoop::performWork(void*) + 36
14 CoreFoundation   0x00000001a728a000 + 700188

你可能感兴趣的:(iOS WKWebView白屏(卡顿))