Changeset 245053 in webkit


Ignore:
Timestamp:
May 8, 2019 5:40:10 AM (5 years ago)
Author:
commit-queue@webkit.org
Message:

Link prefetch not useful for top-level navigation
https://bugs.webkit.org/show_bug.cgi?id=195623

Patch by Rob Buis <rbuis@igalia.com> on 2019-05-08
Reviewed by Youenn Fablet.

Source/WebCore:

Cache cross-domain top-level prefetches in a dedicated cache and not in the
memory cache.

Tests: http/tests/cache/link-prefetch-main-resource-iframe.html

http/tests/cache/link-prefetch-main-resource.html
http/tests/contentextensions/prefetch-blocked.html

  • loader/LinkLoader.cpp:

(WebCore::LinkLoader::prefetchIfNeeded):

  • loader/ResourceLoadInfo.cpp:

(WebCore::toResourceType):

Source/WebKit:

Cache cross-domain top-level prefetches in a dedicated cache. When a navigation
to the same url is done within a threshold (5 seconds), reuse the
prefetch cache entry, move it to the disk cache and navigate to
the url, meaning no extra network trip is needed. When not used within
the threshold period, the prefetch entry will be erased using a timer.

  • NetworkProcess/NetworkProcess.cpp:

(WebKit::NetworkProcess::lowMemoryHandler):

  • NetworkProcess/NetworkResourceLoader.cpp:

(WebKit::NetworkResourceLoader::retrieveCacheEntry):
(WebKit::NetworkResourceLoader::didReceiveResponse):
(WebKit::NetworkResourceLoader::didReceiveBuffer):
(WebKit::NetworkResourceLoader::tryStoreAsCacheEntry):
(WebKit::NetworkResourceLoader::isCrossOriginPrefetch const):

  • NetworkProcess/NetworkResourceLoader.h:
  • NetworkProcess/NetworkSession.h:

(WebKit::NetworkSession::prefetchCache):
(WebKit::NetworkSession::clearPrefetchCache):

  • NetworkProcess/cache/PrefetchCache.cpp: Added.

(WebKit::PrefetchCache::Entry::Entry):
(WebKit::PrefetchCache::PrefetchCache):
(WebKit::PrefetchCache::~PrefetchCache):
(WebKit::PrefetchCache::clear):
(WebKit::PrefetchCache::take):
(WebKit::PrefetchCache::store):
(WebKit::PrefetchCache::clearExpiredEntries):

  • NetworkProcess/cache/PrefetchCache.h: Added.

(WebKit::PrefetchCache::Entry::releaseBuffer):

  • Shared/WebPreferences.yaml:
  • Sources.txt:
  • WebKit.xcodeproj/project.pbxproj:

LayoutTests:

Verify that prefetching a cross-domain top-level main resource
is cached in the prefetch cache and only loaded once, and that non
top-level prefetches keep the old behavior.

  • http/tests/cache/link-prefetch-main-resource-expected.txt: Added.
  • http/tests/cache/link-prefetch-main-resource-iframe-expected.txt: Added.
  • http/tests/cache/link-prefetch-main-resource-iframe.html: Added.
  • http/tests/cache/link-prefetch-main-resource.html: Added.
  • http/tests/cache/resources/prefetched-main-resource-iframe.php: Added.
  • http/tests/cache/resources/prefetched-main-resource.php: Added.
  • http/tests/contentextensions/prefetch-blocked-expected.txt: Added.
  • http/tests/contentextensions/prefetch-blocked.html: Added.
  • http/tests/contentextensions/prefetch-blocked.html.json: Added.
  • platform/mac-wk1/TestExpectations:
  • platform/win/TestExpectations:
Location:
trunk
Files:
11 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r245052 r245053  
     12019-05-08  Rob Buis  <rbuis@igalia.com>
     2
     3        Link prefetch not useful for top-level navigation
     4        https://bugs.webkit.org/show_bug.cgi?id=195623
     5
     6        Reviewed by Youenn Fablet.
     7
     8        Verify that prefetching a cross-domain top-level main resource
     9        is cached in the prefetch cache and only loaded once, and that non
     10        top-level prefetches keep the old behavior.
     11
     12        * http/tests/cache/link-prefetch-main-resource-expected.txt: Added.
     13        * http/tests/cache/link-prefetch-main-resource-iframe-expected.txt: Added.
     14        * http/tests/cache/link-prefetch-main-resource-iframe.html: Added.
     15        * http/tests/cache/link-prefetch-main-resource.html: Added.
     16        * http/tests/cache/resources/prefetched-main-resource-iframe.php: Added.
     17        * http/tests/cache/resources/prefetched-main-resource.php: Added.
     18        * http/tests/contentextensions/prefetch-blocked-expected.txt: Added.
     19        * http/tests/contentextensions/prefetch-blocked.html: Added.
     20        * http/tests/contentextensions/prefetch-blocked.html.json: Added.
     21        * platform/mac-wk1/TestExpectations:
     22        * platform/win/TestExpectations:
     23
    1242019-05-08  Jiewen Tan  <jiewen_tan@apple.com>
    225
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r244813 r245053  
    703703
    704704webkit.org/b/196915 [ Debug ] inspector/timeline/timeline-recording.html [ Pass Failure ]
     705
     706webkit.org/b/195623 http/tests/cache/link-prefetch-main-resource.html [ Skip ]
     707webkit.org/b/195623 http/tests/cache/link-prefetch-main-resource-iframe.html [ Skip ]
  • trunk/LayoutTests/platform/win/TestExpectations

    r244948 r245053  
    43964396[ Win10 ] svg/repaint/remove-background-property-on-root.html [ ImageOnlyFailure ]
    43974397[ Win10 ] fast/spatial-navigation/snav-media-elements.html [ Crash ]
     4398
     4399webkit.org/b/195623 http/tests/cache/link-prefetch-main-resource.html [ Skip ]
     4400webkit.org/b/195623 http/tests/cache/link-prefetch-main-resource-iframe.html [ Skip ]
  • trunk/Source/WebCore/ChangeLog

    r245049 r245053  
     12019-05-08  Rob Buis  <rbuis@igalia.com>
     2
     3        Link prefetch not useful for top-level navigation
     4        https://bugs.webkit.org/show_bug.cgi?id=195623
     5
     6        Reviewed by Youenn Fablet.
     7
     8        Cache cross-domain top-level prefetches in a dedicated cache and not in the
     9        memory cache.
     10
     11        Tests: http/tests/cache/link-prefetch-main-resource-iframe.html
     12               http/tests/cache/link-prefetch-main-resource.html
     13               http/tests/contentextensions/prefetch-blocked.html
     14
     15        * loader/LinkLoader.cpp:
     16        (WebCore::LinkLoader::prefetchIfNeeded):
     17        * loader/ResourceLoadInfo.cpp:
     18        (WebCore::toResourceType):
     19
    1202019-05-07  Don Olmstead  <don.olmstead@sony.com>
    221
  • trunk/Source/WebCore/loader/LinkLoader.cpp

    r244700 r245053  
    278278        m_cachedLinkResource = nullptr;
    279279    }
     280    // FIXME: Add further prefetch restrictions/limitations:
     281    // - third-party iframes cannot trigger prefetches
     282    // - Number of prefetches of a given page is limited (to 1 maybe?)
    280283    ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
    281284    options.contentSecurityPolicyImposition = ContentSecurityPolicyImposition::SkipPolicyCheck;
     285    options.certificateInfoPolicy = CertificateInfoPolicy::IncludeCertificateInfo;
     286    options.credentials = FetchOptions::Credentials::SameOrigin;
     287    options.redirect = FetchOptions::Redirect::Manual;
     288    options.mode = FetchOptions::Mode::Navigate;
     289    options.serviceWorkersMode = ServiceWorkersMode::None;
     290    options.cachingPolicy = CachingPolicy::DisallowCaching;
    282291    m_cachedLinkResource = document.cachedResourceLoader().requestLinkResource(type, CachedResourceRequest(ResourceRequest(document.completeURL(href)), options, priority)).value_or(nullptr);
    283292    if (m_cachedLinkResource)
  • trunk/Source/WebCore/loader/ResourceLoadInfo.cpp

    r244794 r245053  
    3838{
    3939    switch (type) {
     40    case CachedResource::Type::LinkPrefetch:
    4041    case CachedResource::Type::MainResource:
    4142        return ResourceType::Document;
     
    7273        return ResourceType::Media;
    7374#endif
    74     case CachedResource::Type::LinkPrefetch:
    75         ASSERT_NOT_REACHED();
    76         break;
    7775#if ENABLE(APPLICATION_MANIFEST)
    7876    case CachedResource::Type::ApplicationManifest:
  • trunk/Source/WebKit/ChangeLog

    r245048 r245053  
     12019-05-08  Rob Buis  <rbuis@igalia.com>
     2
     3        Link prefetch not useful for top-level navigation
     4        https://bugs.webkit.org/show_bug.cgi?id=195623
     5
     6        Reviewed by Youenn Fablet.
     7
     8        Cache cross-domain top-level prefetches in a dedicated cache. When a navigation
     9        to the same url is done within a threshold (5 seconds), reuse the
     10        prefetch cache entry, move it to the disk cache and navigate to
     11        the url, meaning no extra network trip is needed. When not used within
     12        the threshold period, the prefetch entry will be erased using a timer.
     13
     14        * NetworkProcess/NetworkProcess.cpp:
     15        (WebKit::NetworkProcess::lowMemoryHandler):
     16        * NetworkProcess/NetworkResourceLoader.cpp:
     17        (WebKit::NetworkResourceLoader::retrieveCacheEntry):
     18        (WebKit::NetworkResourceLoader::didReceiveResponse):
     19        (WebKit::NetworkResourceLoader::didReceiveBuffer):
     20        (WebKit::NetworkResourceLoader::tryStoreAsCacheEntry):
     21        (WebKit::NetworkResourceLoader::isCrossOriginPrefetch const):
     22        * NetworkProcess/NetworkResourceLoader.h:
     23        * NetworkProcess/NetworkSession.h:
     24        (WebKit::NetworkSession::prefetchCache):
     25        (WebKit::NetworkSession::clearPrefetchCache):
     26        * NetworkProcess/cache/PrefetchCache.cpp: Added.
     27        (WebKit::PrefetchCache::Entry::Entry):
     28        (WebKit::PrefetchCache::PrefetchCache):
     29        (WebKit::PrefetchCache::~PrefetchCache):
     30        (WebKit::PrefetchCache::clear):
     31        (WebKit::PrefetchCache::take):
     32        (WebKit::PrefetchCache::store):
     33        (WebKit::PrefetchCache::clearExpiredEntries):
     34        * NetworkProcess/cache/PrefetchCache.h: Added.
     35        (WebKit::PrefetchCache::Entry::releaseBuffer):
     36        * Shared/WebPreferences.yaml:
     37        * Sources.txt:
     38        * WebKit.xcodeproj/project.pbxproj:
     39
    1402019-05-07  Chris Dumez  <cdumez@apple.com>
    241
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp

    r245025 r245053  
    271271
    272272    WTF::releaseFastMallocFreeMemory();
     273
     274    for (auto& networkSession : m_networkSessions.values())
     275        networkSession.get().clearPrefetchCache();
    273276}
    274277
  • trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp

    r244910 r245053  
    212212
    213213    RefPtr<NetworkResourceLoader> loader(this);
     214    if (isMainFrameLoad()) {
     215        ASSERT(m_parameters.options.mode == FetchOptions::Mode::Navigate);
     216        if (auto session = m_connection->networkProcess().networkSession(sessionID())) {
     217            if (auto entry = session->prefetchCache().take(request.url()))
     218                m_cache->store(request, entry->response, entry->releaseBuffer(), nullptr);
     219        }
     220    }
    214221    m_cache->retrieve(request, { m_parameters.webPageID, m_parameters.webFrameID }, [this, loader = WTFMove(loader), request = ResourceRequest { request }](auto entry, auto info) mutable {
    215222        if (loader->hasOneRef()) {
     
    470477    }
    471478
     479    if (isCrossOriginPrefetch())
     480        return completionHandler(PolicyAction::Use);
     481
    472482    // We wait to receive message NetworkResourceLoader::ContinueDidReceiveResponse before continuing a load for
    473483    // a main resource because the embedding client must decide whether to allow the load.
     
    507517            m_bufferedDataForCache = nullptr;
    508518    }
     519    if (isCrossOriginPrefetch())
     520        return;
    509521    // FIXME: At least on OS X Yosemite we always get -1 from the resource handle.
    510522    unsigned encodedDataLength = reportedEncodedDataLength >= 0 ? reportedEncodedDataLength : buffer->size();
     
    798810        return;
    799811
     812    if (isCrossOriginPrefetch()) {
     813        if (auto session = m_connection->networkProcess().networkSession(sessionID()))
     814            session->prefetchCache().store(m_networkLoad->currentRequest().url(), WTFMove(m_response), WTFMove(m_bufferedDataForCache));
     815        return;
     816    }
    800817    m_cache->store(m_networkLoad->currentRequest(), m_response, WTFMove(m_bufferedDataForCache), [loader = makeRef(*this)](auto& mappedBody) mutable {
    801818#if ENABLE(SHAREABLE_RESOURCE)
     
    11281145}
    11291146
     1147bool NetworkResourceLoader::isCrossOriginPrefetch() const
     1148{
     1149    auto request = originalRequest();
     1150    return request.httpHeaderField(HTTPHeaderName::Purpose) == "prefetch" && !m_parameters.sourceOrigin->canRequest(request.url());
     1151}
     1152
    11301153} // namespace WebKit
    11311154
  • trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h

    r244700 r245053  
    105105    bool isMainResource() const { return m_parameters.request.requester() == WebCore::ResourceRequest::Requester::Main; }
    106106    bool isMainFrameLoad() const { return isMainResource() && m_parameters.frameAncestorOrigins.isEmpty(); }
     107    bool isCrossOriginPrefetch() const;
    107108
    108109    bool isAlwaysOnLoggingAllowed() const;
  • trunk/Source/WebKit/NetworkProcess/NetworkSession.h

    r244818 r245053  
    2626#pragma once
    2727
     28#include "PrefetchCache.h"
    2829#include "WebResourceLoadStatisticsStore.h"
    2930#include <WebCore/AdClickAttribution.h>
     
    9495    void removeKeptAliveLoad(NetworkResourceLoader&);
    9596
     97    PrefetchCache& prefetchCache() { return m_prefetchCache; }
     98    void clearPrefetchCache() { m_prefetchCache.clear(); }
     99
    96100protected:
    97101    NetworkSession(NetworkProcess&, PAL::SessionID);
     
    110114
    111115    HashSet<Ref<NetworkResourceLoader>> m_keptAliveLoads;
     116
     117    PrefetchCache m_prefetchCache;
    112118};
    113119
  • trunk/Source/WebKit/Shared/WebPreferences.yaml

    r245023 r245053  
    16661666  type: bool
    16671667
     1668LinkPrefetchEnabled:
     1669  type: bool
     1670  defaultValue: false
     1671  humanReadableName: "LinkPrefetch"
     1672  humanReadableDescription: "Enable LinkedPrefetch"
     1673  webcoreBinding: RuntimeEnabledFeatures
     1674  category: experimental
     1675
    16681676# Deprecated
    16691677
  • trunk/Source/WebKit/Sources.txt

    r244428 r245053  
    8181NetworkProcess/cache/NetworkCacheStorage.cpp
    8282NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp
     83NetworkProcess/cache/PrefetchCache.cpp
    8384
    8485NetworkProcess/webrtc/NetworkMDNSRegister.cpp
  • trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj

    r245044 r245053  
    13341334                A78CCDDC193AC9FB005ECC25 /* com.apple.WebKit.WebContent.sb in CopyFiles */ = {isa = PBXBuildFile; fileRef = A78CCDD9193AC9E3005ECC25 /* com.apple.WebKit.WebContent.sb */; };
    13351335                A7D792D81767CCA300881CBE /* ActivityAssertion.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D792D41767CB0900881CBE /* ActivityAssertion.h */; };
     1336                AAB145E6223F931200E489D8 /* PrefetchCache.h in Headers */ = {isa = PBXBuildFile; fileRef = AAB145E4223F931200E489D8 /* PrefetchCache.h */; };
    13361337                B62E7312143047B00069EC35 /* WKHitTestResult.h in Headers */ = {isa = PBXBuildFile; fileRef = B62E7311143047B00069EC35 /* WKHitTestResult.h */; settings = {ATTRIBUTES = (Private, ); }; };
    13371338                B878B615133428DC006888E9 /* CorrectionPanel.h in Headers */ = {isa = PBXBuildFile; fileRef = B878B613133428DC006888E9 /* CorrectionPanel.h */; };
     
    39973998                A7D792D51767CB6E00881CBE /* ActivityAssertion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActivityAssertion.cpp; sourceTree = "<group>"; };
    39983999                A7E93CEB192531AA00A1DC48 /* AuxiliaryProcessIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AuxiliaryProcessIOS.mm; path = ios/AuxiliaryProcessIOS.mm; sourceTree = "<group>"; };
     4000                AAB145E4223F931200E489D8 /* PrefetchCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrefetchCache.h; sourceTree = "<group>"; };
     4001                AAB145E5223F931200E489D8 /* PrefetchCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrefetchCache.cpp; sourceTree = "<group>"; };
    39994002                B396EA5512E0ED2D00F4FEB7 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
    40004003                B62E730F143047A60069EC35 /* WKHitTestResult.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKHitTestResult.cpp; sourceTree = "<group>"; };
     
    89598962                                8310428A1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp */,
    89608963                                831042891BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.h */,
     8964                                AAB145E5223F931200E489D8 /* PrefetchCache.cpp */,
     8965                                AAB145E4223F931200E489D8 /* PrefetchCache.h */,
    89618966                        );
    89628967                        path = cache;
     
    94369441                                1A6FB7AF11E64B6800DB1371 /* PluginView.h in Headers */,
    94379442                                83A0ED351F747CCF003299EB /* PreconnectTask.h in Headers */,
     9443                                AAB145E6223F931200E489D8 /* PrefetchCache.h in Headers */,
    94389444                                E1CC1B9012D7EADF00625838 /* PrintInfo.h in Headers */,
    94399445                                86F9536518FF58F5001DB2EF /* ProcessAssertion.h in Headers */,
Note: See TracChangeset for help on using the changeset viewer.