使用vue ios bfcache失效

2019-05-07  本文已影响0人  小银

ios框架wkwebview
H5使用vue作为框架
现象:
一个聊天框,跳其他页面后再反回去内容被刷了
尝试打印pageshow-》e.persisted显示false。说明bfcahe失效

在看问题之前先了解下MessageChannel

参考1
参考2

然后看下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
上一篇下一篇

猜你喜欢

热点阅读