通過騰訊bugly卡頓日志發(fā)現(xiàn),有許多WebKit的卡頓信息,但是卻沒有定位到項目中的具體代碼。通過大量觀察發(fā)現(xiàn)很多日志中都有調(diào)用WebKit::WebPageProxy::processDidTerminate
函數(shù)或WebKit::WebMemoryPressureHandler::WebMemoryPressureHandler()
函數(shù)。參考WKWebView代理函數(shù)中的- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView;
函數(shù)成因及含有*Memory*
字段,因此大膽猜測可能是WKWebView內(nèi)存占用過大,內(nèi)存不足引起。
《WKWebView 那些坑》文章中WKWebView白屏問題小節(jié)介紹到在WKWebView上當(dāng)總體的內(nèi)存占用比較大的時候,webContent process會crash,從而出現(xiàn)白屏現(xiàn)象。此時系統(tǒng)會調(diào)用- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView;
函數(shù),在該函數(shù)里執(zhí)行[webView reload]
(這個時候webView.URL取值尚不為nil)解決白屏問題。
兩者成因皆為WKWebView內(nèi)存占用過大引起,故本次卡頓解決方式參考WKWebView白屏問題解決方法。
@property (nonatomic ,assign) BOOL webViewLoadTitle;//是否已獲取當(dāng)前webView的title
#pragma mark -
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (YES == self.webViewLoadTitle && [NSString isNullDataString:self.webView.title]) {
//webView已獲取title,但返回時無法獲取title,可能是內(nèi)存不足原因造成,此時需重新加載同時避免第一次進入時重新加載
[self.webView reload];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (![NSString isNullDataString:self.webView.title]) {
self.webViewLoadTitle = YES;
}
}
#pragma mark - WKNavigationDelegate
//web內(nèi)存過大,進程終止,重新加載webView
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
[webView reload];
}
結(jié)果:經(jīng)生產(chǎn)版本檢驗,可有效防止WKWebView內(nèi)存占用過大引起的卡頓問題。
- 參考文檔: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<WebCore::ReloadOption>) + 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<WebKit::WebProcessProxy, WTF::DumbPtrTraits<WebKit::WebProcessProxy> >&&, 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<WebCore::ReloadOption>) + 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<void ()>&&) + 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<WebCore::ReloadOption>) + 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<WebCore::ReloadOption>) + 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::Vector<WTF::String, 0ul, WTF::CrashOnOverflow, 16ul> WTF::copyToVectorOf<WTF::String, WTF::HashSet<WTF::String, WTF::StringHash, WTF::HashTraits<WTF::String> > >(WTF::HashSet<WTF::String, WTF::StringHash, WTF::HashTraits<WTF::String> > const&)::'lambda'(WTF::String const&), WTF::HashSet<WTF::String, WTF::StringHash, WTF::HashTraits<WTF::String> > const&, void>::map(WTF::HashSet<WTF::String, WTF::StringHash, WTF::HashTraits<WTF::String> > const&, WTF::Vector<WTF::String, 0ul, WTF::CrashOnOverflow, 16ul> WTF::copyToVectorOf<WTF::String, WTF::HashSet<WTF::String, WTF::StringHash, WTF::HashTraits<WTF::String> > >(WTF::HashSet<WTF::String, WTF::StringHash, WTF::HashTraits<WTF::String> > 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<WebCore::ReloadOption>) + 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<WebCore::ReloadOption>) + 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