Title: [290969] trunk/Source
Revision
290969
Author
pvol...@apple.com
Date
2022-03-07 18:12:38 -0800 (Mon, 07 Mar 2022)

Log Message

Preconnecting after process swap is a page load time improvement on some devices
https://bugs.webkit.org/show_bug.cgi?id=237055
<rdar://problem/89638872>

Reviewed by Geoffrey Garen.

Source/WebCore:

Export method.

* platform/network/NetworkLoadMetrics.h:

Source/WebKit:

On some devices we see that doing a second preconnect on HTTP/1.1 is a significant page load time improvement.
This is due to the fact that most page loads on HTTP/1.1 will open several connections, and having two
preconnected connections instead of one, will speed up page load time. This patch implements this by starting
a second preconnect after the first has finished. It is important to wait until the first preconnect has
finished, otherwise the second preconnect will go to waste, since the underlying network layer does not yet
know if this is HTTP/1.1 or not. Since we do not see page load time improvement on iOS with this behavior,
it is currently only enabled for macOS. The next step is to investigate why it does not seem to be a page
load time improvement on iOS. We probably need to make sure the main resource load has started before we
start the second preconect. This will avoid that the second preconnect returns immediately.

* NetworkProcess/NetworkConnectionToWebProcess.cpp:
(WebKit::NetworkConnectionToWebProcess::sendH2Ping):
(WebKit::NetworkConnectionToWebProcess::preconnectTo):
* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::preconnectTo):
* NetworkProcess/PreconnectTask.cpp:
(WebKit::PreconnectTask::PreconnectTask):
(WebKit::PreconnectTask::didFinishLoading):
(WebKit::PreconnectTask::didFailLoading):
(WebKit::PreconnectTask::didFinish):
* NetworkProcess/PreconnectTask.h:
* NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp:
(WebKit::NetworkCache::SpeculativeLoadManager::preconnectForSubresource):

Source/WTF:

Add ENABLE guard for this behavior.

* wtf/PlatformEnableCocoa.h:

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (290968 => 290969)


--- trunk/Source/WTF/ChangeLog	2022-03-08 01:39:15 UTC (rev 290968)
+++ trunk/Source/WTF/ChangeLog	2022-03-08 02:12:38 UTC (rev 290969)
@@ -1,3 +1,15 @@
+2022-03-07  Per Arne Vollan  <pvol...@apple.com>
+
+        Preconnecting after process swap is a page load time improvement on some devices
+        https://bugs.webkit.org/show_bug.cgi?id=237055
+        <rdar://problem/89638872>
+
+        Reviewed by Geoffrey Garen.
+
+        Add ENABLE guard for this behavior.
+
+        * wtf/PlatformEnableCocoa.h:
+
 2022-03-07  Chris Dumez  <cdu...@apple.com>
 
         Optimize the passing of data across threads

Modified: trunk/Source/WTF/wtf/PlatformEnableCocoa.h (290968 => 290969)


--- trunk/Source/WTF/wtf/PlatformEnableCocoa.h	2022-03-08 01:39:15 UTC (rev 290968)
+++ trunk/Source/WTF/wtf/PlatformEnableCocoa.h	2022-03-08 02:12:38 UTC (rev 290969)
@@ -758,3 +758,7 @@
 #define ENABLE_ARKIT_INLINE_PREVIEW_ANIMATIONS_CONTROL 1
 #define ENABLE_ARKIT_INLINE_PREVIEW_AUDIO_CONTROL 1
 #endif
+
+#if !defined(ENABLE_ADDITIONAL_PRECONNECT_ON_HTTP_1X) && PLATFORM(MAC)
+#define ENABLE_ADDITIONAL_PRECONNECT_ON_HTTP_1X 1
+#endif

Modified: trunk/Source/WebCore/ChangeLog (290968 => 290969)


--- trunk/Source/WebCore/ChangeLog	2022-03-08 01:39:15 UTC (rev 290968)
+++ trunk/Source/WebCore/ChangeLog	2022-03-08 02:12:38 UTC (rev 290969)
@@ -1,3 +1,15 @@
+2022-03-07  Per Arne Vollan  <pvol...@apple.com>
+
+        Preconnecting after process swap is a page load time improvement on some devices
+        https://bugs.webkit.org/show_bug.cgi?id=237055
+        <rdar://problem/89638872>
+
+        Reviewed by Geoffrey Garen.
+
+        Export method.
+
+        * platform/network/NetworkLoadMetrics.h:
+
 2022-03-07  Jean-Yves Avenard  <j...@apple.com>
 
         Add ability to convert FragmentedSharedBuffer to CMBlockBuffer

Modified: trunk/Source/WebCore/platform/network/NetworkLoadMetrics.h (290968 => 290969)


--- trunk/Source/WebCore/platform/network/NetworkLoadMetrics.h	2022-03-08 01:39:15 UTC (rev 290968)
+++ trunk/Source/WebCore/platform/network/NetworkLoadMetrics.h	2022-03-08 02:12:38 UTC (rev 290969)
@@ -65,7 +65,7 @@
 public:
     WEBCORE_EXPORT NetworkLoadMetrics();
 
-    static const NetworkLoadMetrics& emptyMetrics();
+    WEBCORE_EXPORT static const NetworkLoadMetrics& emptyMetrics();
 
     WEBCORE_EXPORT NetworkLoadMetrics isolatedCopy() const;
 

Modified: trunk/Source/WebKit/ChangeLog (290968 => 290969)


--- trunk/Source/WebKit/ChangeLog	2022-03-08 01:39:15 UTC (rev 290968)
+++ trunk/Source/WebKit/ChangeLog	2022-03-08 02:12:38 UTC (rev 290969)
@@ -1,3 +1,35 @@
+2022-03-07  Per Arne Vollan  <pvol...@apple.com>
+
+        Preconnecting after process swap is a page load time improvement on some devices
+        https://bugs.webkit.org/show_bug.cgi?id=237055
+        <rdar://problem/89638872>
+
+        Reviewed by Geoffrey Garen.
+
+        On some devices we see that doing a second preconnect on HTTP/1.1 is a significant page load time improvement.
+        This is due to the fact that most page loads on HTTP/1.1 will open several connections, and having two
+        preconnected connections instead of one, will speed up page load time. This patch implements this by starting
+        a second preconnect after the first has finished. It is important to wait until the first preconnect has
+        finished, otherwise the second preconnect will go to waste, since the underlying network layer does not yet
+        know if this is HTTP/1.1 or not. Since we do not see page load time improvement on iOS with this behavior,
+        it is currently only enabled for macOS. The next step is to investigate why it does not seem to be a page
+        load time improvement on iOS. We probably need to make sure the main resource load has started before we
+        start the second preconect. This will avoid that the second preconnect returns immediately.
+
+        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+        (WebKit::NetworkConnectionToWebProcess::sendH2Ping):
+        (WebKit::NetworkConnectionToWebProcess::preconnectTo):
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::preconnectTo):
+        * NetworkProcess/PreconnectTask.cpp:
+        (WebKit::PreconnectTask::PreconnectTask):
+        (WebKit::PreconnectTask::didFinishLoading):
+        (WebKit::PreconnectTask::didFailLoading):
+        (WebKit::PreconnectTask::didFinish):
+        * NetworkProcess/PreconnectTask.h:
+        * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp:
+        (WebKit::NetworkCache::SpeculativeLoadManager::preconnectForSubresource):
+
 2022-03-07  Richard Houle  <rho...@apple.com>
 
         [macCatalyst] Compilation error: WebContentProcess.xib: error: macOS xibs do not support target device type "ipad".

Modified: trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp (290968 => 290969)


--- trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp	2022-03-08 01:39:15 UTC (rev 290968)
+++ trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp	2022-03-08 02:12:38 UTC (rev 290969)
@@ -692,7 +692,7 @@
         return completionHandler(makeUnexpected(internalError(parameters.request.url())));
 
     URL url = ""
-    auto* task = new PreconnectTask(*networkSession, WTFMove(parameters), [] (const ResourceError&) { });
+    auto* task = new PreconnectTask(*networkSession, WTFMove(parameters), [] (const ResourceError&, const WebCore::NetworkLoadMetrics&) { });
     task->setH2PingCallback(url, WTFMove(completionHandler));
     task->start();
 #else
@@ -722,7 +722,7 @@
 #if ENABLE(SERVER_PRECONNECT)
     auto* session = networkSession();
     if (session && session->allowsServerPreconnect()) {
-        (new PreconnectTask(*session, WTFMove(loadParameters), [completionHandler = WTFMove(completionHandler)] (const ResourceError& error) {
+        (new PreconnectTask(*session, WTFMove(loadParameters), [completionHandler = WTFMove(completionHandler)] (const ResourceError& error, const WebCore::NetworkLoadMetrics&) {
             completionHandler(error);
         }))->start();
         return;

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (290968 => 290969)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2022-03-08 01:39:15 UTC (rev 290968)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2022-03-08 02:12:38 UTC (rev 290969)
@@ -1322,10 +1322,20 @@
     parameters.storedCredentialsPolicy = storedCredentialsPolicy;
     parameters.shouldPreconnectOnly = PreconnectOnly::Yes;
 
+    NetworkLoadParameters parametersForAdditionalPreconnect = parameters;
+
     session->networkLoadScheduler().startedPreconnectForMainResource(url, userAgent);
-    auto task = new PreconnectTask(*session, WTFMove(parameters), [session = WeakPtr { *session }, url, userAgent](const WebCore::ResourceError& error) {
-        if (session)
+    auto task = new PreconnectTask(*session, WTFMove(parameters), [session = WeakPtr { *session }, url, userAgent, parametersForAdditionalPreconnect = WTFMove(parametersForAdditionalPreconnect)](const WebCore::ResourceError& error, const WebCore::NetworkLoadMetrics& metrics) mutable {
+        if (session) {
             session->networkLoadScheduler().finishedPreconnectForMainResource(url, userAgent, error);
+#if ENABLE(ADDITIONAL_PRECONNECT_ON_HTTP_1X)
+            if (equalIgnoringASCIICase(metrics.protocol, "http/1.1")) {
+                auto parameters = parametersForAdditionalPreconnect;
+                auto task = new PreconnectTask(*session, WTFMove(parameters), [](const WebCore::ResourceError& error, const WebCore::NetworkLoadMetrics& metrics) { });
+                task->start();
+            }
+#endif // ENABLE(ADDITIONAL_PRECONNECT_ON_HTTP_1X)
+        }
     });
     task->setTimeout(10_s);
     task->start();

Modified: trunk/Source/WebKit/NetworkProcess/PreconnectTask.cpp (290968 => 290969)


--- trunk/Source/WebKit/NetworkProcess/PreconnectTask.cpp	2022-03-08 01:39:15 UTC (rev 290968)
+++ trunk/Source/WebKit/NetworkProcess/PreconnectTask.cpp	2022-03-08 02:12:38 UTC (rev 290969)
@@ -39,10 +39,10 @@
 
 using namespace WebCore;
 
-PreconnectTask::PreconnectTask(NetworkSession& networkSession, NetworkLoadParameters&& parameters, CompletionHandler<void(const ResourceError&)>&& completionHandler)
+PreconnectTask::PreconnectTask(NetworkSession& networkSession, NetworkLoadParameters&& parameters, CompletionHandler<void(const ResourceError&, const WebCore::NetworkLoadMetrics&)>&& completionHandler)
     : m_completionHandler(WTFMove(completionHandler))
     , m_timeout(60_s)
-    , m_timeoutTimer([this] { didFinish(ResourceError { String(), 0, m_networkLoad->parameters().request.url(), "Preconnection timed out"_s, ResourceError::Type::Timeout }); })
+    , m_timeoutTimer([this] { didFinish(ResourceError { String(), 0, m_networkLoad->parameters().request.url(), "Preconnection timed out"_s, ResourceError::Type::Timeout }, { }); })
 {
     RELEASE_LOG(Network, "%p - PreconnectTask::PreconnectTask()", this);
 
@@ -84,16 +84,16 @@
     ASSERT_NOT_REACHED();
 }
 
-void PreconnectTask::didFinishLoading(const NetworkLoadMetrics&)
+void PreconnectTask::didFinishLoading(const NetworkLoadMetrics& metrics)
 {
     RELEASE_LOG(Network, "%p - PreconnectTask::didFinishLoading", this);
-    didFinish({ });
+    didFinish({ }, metrics);
 }
 
 void PreconnectTask::didFailLoading(const ResourceError& error)
 {
     RELEASE_LOG(Network, "%p - PreconnectTask::didFailLoading, error_code=%d", this, error.errorCode());
-    didFinish(error);
+    didFinish(error, NetworkLoadMetrics::emptyMetrics());
 }
 
 void PreconnectTask::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
@@ -101,10 +101,10 @@
     ASSERT_NOT_REACHED();
 }
 
-void PreconnectTask::didFinish(const ResourceError& error)
+void PreconnectTask::didFinish(const ResourceError& error, const NetworkLoadMetrics& metrics)
 {
     if (m_completionHandler)
-        m_completionHandler(error);
+        m_completionHandler(error, metrics);
     delete this;
 }
 

Modified: trunk/Source/WebKit/NetworkProcess/PreconnectTask.h (290968 => 290969)


--- trunk/Source/WebKit/NetworkProcess/PreconnectTask.h	2022-03-08 01:39:15 UTC (rev 290968)
+++ trunk/Source/WebKit/NetworkProcess/PreconnectTask.h	2022-03-08 02:12:38 UTC (rev 290969)
@@ -41,7 +41,7 @@
 
 class PreconnectTask final : public NetworkLoadClient {
 public:
-    PreconnectTask(NetworkSession&, NetworkLoadParameters&&, CompletionHandler<void(const WebCore::ResourceError&)>&&);
+    PreconnectTask(NetworkSession&, NetworkLoadParameters&&, CompletionHandler<void(const WebCore::ResourceError&, const WebCore::NetworkLoadMetrics&)>&&);
     ~PreconnectTask();
 
     void setH2PingCallback(const URL&, CompletionHandler<void(Expected<WTF::Seconds, WebCore::ResourceError>&&)>&&);
@@ -59,10 +59,10 @@
     void didFinishLoading(const WebCore::NetworkLoadMetrics&) final;
     void didFailLoading(const WebCore::ResourceError&) final;
 
-    void didFinish(const WebCore::ResourceError&);
+    void didFinish(const WebCore::ResourceError&, const WebCore::NetworkLoadMetrics&);
 
     std::unique_ptr<NetworkLoad> m_networkLoad;
-    CompletionHandler<void(const WebCore::ResourceError&)> m_completionHandler;
+    CompletionHandler<void(const WebCore::ResourceError&, const WebCore::NetworkLoadMetrics&)> m_completionHandler;
     Seconds m_timeout;
     WebCore::Timer m_timeoutTimer;
 };

Modified: trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp (290968 => 290969)


--- trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp	2022-03-08 01:39:15 UTC (rev 290968)
+++ trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp	2022-03-08 02:12:38 UTC (rev 290969)
@@ -470,7 +470,7 @@
     parameters.shouldPreconnectOnly = PreconnectOnly::Yes;
     parameters.request = constructRevalidationRequest(subresourceInfo.key(), subresourceInfo, entry);
     parameters.isNavigatingToAppBoundDomain = isNavigatingToAppBoundDomain;
-    (new PreconnectTask(*networkSession, WTFMove(parameters), [](const WebCore::ResourceError&) { }))->start();
+    (new PreconnectTask(*networkSession, WTFMove(parameters), [](const WebCore::ResourceError&, const WebCore::NetworkLoadMetrics&) { }))->start();
 #else
     UNUSED_PARAM(subresourceInfo);
     UNUSED_PARAM(entry);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to