ios框架wkwebview
H5使用vue作为框架
现象:
一个聊天框,跳其他页面后再反回去内容被刷了
尝试打印pageshow-》e.persisted显示false。说明bfcahe失效
在看问题之前先了解下MessageChannel
然后看下webkit相关源码
首先是PageCache文件描述了页面缓存相关的信息
static bool canCacheFrame(Frame& frame, DiagnosticLoggingClient& diagnosticLoggingClient, unsigned indentLevel)
{
.....
Vector<ActiveDOMObject*> unsuspendableObjects;
if (frame.document() && !frame.document()->canSuspendActiveDOMObjectsForDocumentSuspension(&unsuspendableObjects)) {
PCLOG(" -The document cannot suspend its active DOM Objects");
for (auto* activeDOMObject : unsuspendableObjects) {
PCLOG(" - Unsuspendable: ", activeDOMObject->activeDOMObjectName());
diagnosticLoggingClient.logDiagnosticMessage(DiagnosticLoggingKeys::unsuspendableDOMObjectKey(), activeDOMObject->activeDOMObjectName(), ShouldSample::Yes);
UNUSED_PARAM(activeDOMObject);
}
logPageCacheFailureDiagnosticMessage(diagnosticLoggingClient, DiagnosticLoggingKeys::cannotSuspendActiveDOMObjectsKey());
isCacheable = false;
}
.......
}
//canSuspendActiveDOMObjectsForDocumentSuspension()主要处理是否可缓存信息
然后看下对应ScriptExecutionContext文件
有个canSuspendForDocumentSuspension方法
bool ScriptExecutionContext::canSuspendActiveDOMObjectsForDocumentSuspension(Vector<ActiveDOMObject*>* unsuspendableObjects)
{
checkConsistency();
bool canSuspend = true;
forEachActiveDOMObject([&](auto& activeDOMObject) {
if (!activeDOMObject.canSuspendForDocumentSuspension()) {
canSuspend = false;
if (unsuspendableObjects)
unsuspendableObjects->append(&activeDOMObject);
else
return ShouldContinue::No;
}
return ShouldContinue::Yes;
});
if (unsuspendableObjects) {
// Remove activeDOMObjects that have been destroyed while we were iterating above.
unsuspendableObjects->removeAllMatching([&](auto* activeDOMObject) {
return !m_activeDOMObjects.contains(activeDOMObject);
});
}
return canSuspend;
}
那有哪些activeDOMObject对象呢,在webcore下搜了下 53个
可以看下worker
bool Worker::canSuspendForDocumentSuspension() const
{
// FIXME: It is not currently possible to suspend a worker, so pages with workers can not go into page cache.
return false;
}
//canSuspendForDocumentSuspension 直接返回false 用了 new Worker也不会生效了
//
//idb操作的
bool IDBObjectStore::canSuspendForDocumentSuspension() const
{
return false;
}
//indexedDB.open('test')
//eventsource操作的
bool EventSource::canSuspendForDocumentSuspension() const
{
// FIXME: We should return true here when we can because this object is not actually currently active.
return false;
}
//new EventSource
再看(MessagePort文件)[https://github.com/WebKit/webkit/blob/master/Source/WebCore/dom/MessagePort.cpp]
bool MessagePort::canSuspendForDocumentSuspension() const
{
return !hasPendingActivity() || (!m_started || m_closed);
}
//canSuspendForDocumentSuspension拿到false(由于条件限制无法开调试看具体原因)
实际现象是使用
var nmc= new MessageChannel();
//必须有下面这句
nmc.port1.onmessage =function(){}
//vue2.6之前版本用了MessageChannel
//解决办法
//1. MessageChannel=null
//2.ios多开webview
网友评论