Skip to content

Commit 14bbe4e

Browse files
committed
Implement service worker resource timing API
rdar://168499249 https://bugs.webkit.org/show_bug.cgi?id=305831 Reviewed by Chris Dumez. We add support for https://w3c.github.io/ServiceWorker/#service-worker-timing-info worker router evaluation start, worker cache lookup start, worker matched router source and worker final router source. This is stored in NetworkResourceLoader and set by ServiceWorkerFetchTask and WebSWServerConnection. We update SWServerWorker::getRouterSource to return null or a source, as per spec to be able to properly set worker router evaluation start. From NetworkResourceLoader, we send this additional information to WebResourceLoader just before sending the actual response. We add the necessary WebIDL API and stubs in PerformanceResourceTiming, as well as the plumbery in NetworkLoadMetrics. For two new timestamp properties, we make sure that reducing the precision of the values will not make them back to 0.0, which is equivalent to not being set. Instead, these values will be set to 1ms, the precision limit. A follow-up patch will make these two timstamps consistent with other timestamps Covered by rebased test. We update this test to use the standardized names of the properties if available. Canonical link: https://commits.webkit.org/306006@main
1 parent c740257 commit 14bbe4e

23 files changed

+289
-34
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11

2-
FAIL Main resource matched the rule with fetch-event source assert_equals: fetch-event as source on main resource expected (string) "fetch-event" but got (undefined) undefined
3-
FAIL Main resource load matched with the condition and resource timing assert_equals: network as source on main resource expected (string) "network" but got (undefined) undefined
4-
FAIL Main resource load not matched with the condition and resource timing assert_equals: no rule matched on main resource expected (string) "" but got (undefined) undefined
2+
PASS Main resource matched the rule with fetch-event source
3+
PASS Main resource load matched with the condition and resource timing
4+
PASS Main resource load not matched with the condition and resource timing
55
FAIL Main resource load matched with the cache source and resource timing assert_equals: cache as source on main resource and cache hit expected 1 but got 0
6-
FAIL Main resource fallback to the network when there is no cache entry and resource timing assert_equals: cache as source on main resource and cache miss, fallback to network expected (string) "cache" but got (undefined) undefined
7-
FAIL Subresource load matched the rule fetch-event source assert_equals: fetch-event as source on sub resource expected (string) "fetch-event" but got (undefined) undefined
8-
FAIL Subresource load not matched with URLPattern condition assert_equals: no source type matched expected (string) "" but got (undefined) undefined
9-
FAIL Subresource load matched with URLPattern condition assert_equals: network as source on subresource expected (string) "network" but got (undefined) undefined
10-
FAIL Subresource load matched with the cache source rule assert_equals: cache as source on subresource and cache hits expected (string) "cache" but got (undefined) undefined
11-
FAIL Subresource load did not match with the cache and fallback to the network assert_equals: cache as source on subresource and cache misses expected (string) "cache" but got (undefined) undefined
12-
FAIL Main resource load matched the rule with race-network-and-fetch-handler source, and the fetch handler response is faster than the server response assert_equals: race as source on main resource, and fetch-event wins expected (string) "race-network-and-fetch-handler" but got (undefined) undefined
13-
FAIL Main resource load matched the rule with race-network-and-fetch-handler source, and the server reseponse is faster than the fetch handler assert_equals: race as source on main resource, and network wins expected (string) "race-network-and-fetch-handler" but got (undefined) undefined
14-
FAIL Subresource load matched the rule with race-network-and-fetch-handler source, and the fetch handler response is faster than the server response assert_equals: race as source on subresource and fetch wins expected (string) "race-network-and-fetch-handler" but got (undefined) undefined
15-
FAIL Subresource load matched the rule with race-network-and-fetch-handler source, and the server reseponse is faster than the fetch handler assert_equals: race as source on subresource and network wins expected (string) "race-network-and-fetch-handler" but got (undefined) undefined
6+
PASS Main resource fallback to the network when there is no cache entry and resource timing
7+
FAIL Subresource load matched the rule fetch-event source assert_equals: fetch-event as source on sub resource expected "fetch-event" but got ""
8+
FAIL Subresource load not matched with URLPattern condition assert_greater_than: no source type matched expected a number greater than 0 but got 0
9+
PASS Subresource load matched with URLPattern condition
10+
FAIL Subresource load matched with the cache source rule assert_equals: cache as source on subresource and cache hits expected "cache" but got ""
11+
PASS Subresource load did not match with the cache and fallback to the network
12+
PASS Main resource load matched the rule with race-network-and-fetch-handler source, and the fetch handler response is faster than the server response
13+
PASS Main resource load matched the rule with race-network-and-fetch-handler source, and the server reseponse is faster than the fetch handler
14+
FAIL Subresource load matched the rule with race-network-and-fetch-handler source, and the fetch handler response is faster than the server response assert_equals: race as source on subresource and fetch wins expected "race-network-and-fetch-handler" but got ""
15+
PASS Subresource load matched the rule with race-network-and-fetch-handler source, and the server reseponse is faster than the fetch handler
1616

LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/tentative/static-router/static-router-resource-timing.https.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,12 @@
4747
assert_equals(entryList.length, 1, description);
4848
const entry = entryList[0];
4949

50-
assert_equals(entry.workerMatchedSourceType, options.matched_source_type, description);
51-
assert_equals(entry.workerFinalSourceType, options.final_source_type, description);
50+
// FIXME: Remove workerMatchedSourceType and workerFinalSourceType when moved out of tentative.
51+
const workerMatchedRouterSource = "workerMatchedRouterSource" in entry ? entry.workerMatchedRouterSource : entry.workerMatchedSourceType;
52+
const workerFinalRouterSource = "workerFinalRouterSource" in entry ? entry.workerFinalRouterSource : entry.workerFinalSourceType;
53+
54+
assert_equals(workerMatchedRouterSource, options.matched_source_type, description);
55+
assert_equals(workerFinalRouterSource, options.final_source_type, description);
5256

5357
assert_greater_than(entry.workerRouterEvaluationStart, 0, description);
5458
switch (entry.matchedSouceType) {

Source/WebCore/page/PerformanceResourceTiming.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,4 +339,34 @@ uint64_t PerformanceResourceTiming::decodedBodySize() const
339339
return decodedBodySize;
340340
}
341341

342+
double PerformanceResourceTiming::workerRouterEvaluationStart() const
343+
{
344+
// FIXME: Align time computation with other timestamps.
345+
Seconds difference = m_resourceTiming.networkLoadMetrics().workerRouterEvaluationStart - m_timeOrigin;
346+
if (difference.value() <= 0)
347+
return 0.0;
348+
auto reducedPrecision = Performance::reduceTimeResolution(difference).milliseconds();
349+
return reducedPrecision ? reducedPrecision : 1;
350+
}
351+
352+
double PerformanceResourceTiming::workerCacheLookupStart() const
353+
{
354+
// FIXME: Align time computation with other timestamps.
355+
Seconds difference = m_resourceTiming.networkLoadMetrics().workerCacheLookupStart - m_timeOrigin;
356+
if (difference.value() <= 0)
357+
return 0.0;
358+
auto reducedPrecision = Performance::reduceTimeResolution(difference).milliseconds();
359+
return reducedPrecision ? reducedPrecision : 1;
360+
}
361+
362+
const String& PerformanceResourceTiming::workerMatchedRouterSource() const
363+
{
364+
return m_resourceTiming.networkLoadMetrics().workerMatchedRouterSource;
365+
}
366+
367+
const String& PerformanceResourceTiming::workerFinalRouterSource() const
368+
{
369+
return m_resourceTiming.networkLoadMetrics().workerFinalRouterSource;
370+
}
371+
342372
} // namespace WebCore

Source/WebCore/page/PerformanceResourceTiming.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ class PerformanceResourceTiming : public PerformanceEntry {
6767
uint64_t transferSize() const;
6868
uint64_t encodedBodySize() const;
6969
uint64_t decodedBodySize() const;
70+
double workerRouterEvaluationStart() const;
71+
double workerCacheLookupStart() const;
72+
const String& workerMatchedRouterSource() const;
73+
const String& workerFinalRouterSource() const;
7074

7175
const Vector<Ref<PerformanceServerTiming>>& serverTiming() const { return m_serverTiming; }
7276
ResourceTiming& resourceTiming() { return m_resourceTiming; }

Source/WebCore/page/PerformanceResourceTiming.idl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ typedef double DOMHighResTimeStamp;
5757
readonly attribute unsigned long long encodedBodySize;
5858
readonly attribute unsigned long long decodedBodySize;
5959

60+
readonly attribute DOMHighResTimeStamp workerRouterEvaluationStart;
61+
readonly attribute DOMHighResTimeStamp workerCacheLookupStart;
62+
readonly attribute DOMString workerMatchedRouterSource;
63+
readonly attribute DOMString workerFinalRouterSource;
64+
6065
// https://w3c.github.io/resource-timing/#dfn-delivery-type
6166
readonly attribute DOMString deliveryType;
6267

Source/WebCore/platform/network/NetworkLoadMetrics.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "config.h"
2727
#include "NetworkLoadMetrics.h"
2828

29+
#include <wtf/CrossThreadCopier.h>
2930
#include <wtf/NeverDestroyed.h>
3031

3132
namespace WebCore {
@@ -81,6 +82,11 @@ void NetworkLoadMetrics::updateFromFinalMetrics(const NetworkLoadMetrics& other)
8182
bool originalFromPrefetch = fromPrefetch;
8283
bool originalFromCache = fromCache;
8384

85+
auto originalWorkerRouterEvaluationStart = workerRouterEvaluationStart;
86+
auto originalWorkerCacheLookupStart = workerCacheLookupStart;
87+
auto originalWorkerMatchedRouterSource = workerMatchedRouterSource;
88+
auto originalWorkerFinalRouterSource = workerFinalRouterSource;
89+
8490
*this = other;
8591

8692
if (!redirectStart)
@@ -112,6 +118,15 @@ void NetworkLoadMetrics::updateFromFinalMetrics(const NetworkLoadMetrics& other)
112118
if (!fromCache)
113119
fromCache = originalFromCache;
114120

121+
if (!workerRouterEvaluationStart)
122+
workerRouterEvaluationStart = originalWorkerRouterEvaluationStart;
123+
if (!workerCacheLookupStart)
124+
workerCacheLookupStart = originalWorkerCacheLookupStart;
125+
if (!workerMatchedRouterSource)
126+
workerMatchedRouterSource = originalWorkerMatchedRouterSource;
127+
if (!workerFinalRouterSource)
128+
workerFinalRouterSource = originalWorkerFinalRouterSource;
129+
115130
if (!responseEnd)
116131
responseEnd = MonotonicTime::now();
117132
complete = true;
@@ -176,6 +191,11 @@ NetworkLoadMetrics NetworkLoadMetrics::isolatedCopy() const
176191
copy.responseBodyBytesReceived = responseBodyBytesReceived;
177192
copy.responseBodyDecodedSize = responseBodyDecodedSize;
178193

194+
copy.workerRouterEvaluationStart = workerRouterEvaluationStart.isolatedCopy();
195+
copy.workerCacheLookupStart = workerCacheLookupStart.isolatedCopy();
196+
copy.workerMatchedRouterSource = crossThreadCopy(workerMatchedRouterSource);
197+
copy.workerFinalRouterSource = crossThreadCopy(workerFinalRouterSource);
198+
179199
if (RefPtr metrics = additionalNetworkLoadMetricsForWebInspector)
180200
copy.additionalNetworkLoadMetricsForWebInspector = metrics->isolatedCopy();
181201

Source/WebCore/platform/network/NetworkLoadMetrics.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ class NetworkLoadMetrics {
9595
MonotonicTime responseStart;
9696
MonotonicTime responseEnd;
9797
MonotonicTime workerStart;
98+
MonotonicTime workerRouterEvaluationStart;
99+
MonotonicTime workerCacheLookupStart;
100+
String workerMatchedRouterSource;
101+
String workerFinalRouterSource;
98102

99103
// https://github.com/w3c/resource-timing/pull/408
100104
// Timing for interim (1xx) vs final (2xx/3xx/4xx/5xx) responses

Source/WebCore/workers/service/server/SWServerWorker.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,13 +534,18 @@ std::optional<ExceptionData> SWServerWorker::addRoutes(Vector<ServiceWorkerRoute
534534
}
535535

536536
// https://w3c.github.io/ServiceWorker/#get-router-source
537-
RouterSource SWServerWorker::getRouterSource(const FetchOptions& options, const ResourceRequest& request) const
537+
std::optional<RouterSource> SWServerWorker::getRouterSource(const FetchOptions& options, const ResourceRequest& request) const
538538
{
539539
for (auto& route : m_routes) {
540540
if (matchRouterCondition(route.condition, options, request, isRunning()))
541541
return route.source;
542542
}
543543

544+
return { };
545+
}
546+
547+
RouterSource SWServerWorker::defaultRouterSource() const
548+
{
544549
return m_shouldSkipHandleFetch ? RouterSourceEnum::Network : RouterSourceEnum::FetchEvent;
545550
}
546551

Source/WebCore/workers/service/server/SWServerWorker.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,10 @@ class SWServerWorker : public RefCountedAndCanMakeWeakPtr<SWServerWorker> {
130130
WEBCORE_EXPORT SWServerToContextConnection* contextConnection();
131131
String userAgent() const;
132132

133-
WEBCORE_EXPORT RouterSource getRouterSource(const FetchOptions&, const ResourceRequest&) const;
134-
133+
bool hasRouterRules() const { return !m_routes.isEmpty(); }
134+
WEBCORE_EXPORT std::optional<RouterSource> getRouterSource(const FetchOptions&, const ResourceRequest&) const;
135+
WEBCORE_EXPORT RouterSource defaultRouterSource() const;
136+
135137
WEBCORE_EXPORT SWServerRegistration* registration() const;
136138

137139
void setHasTimedOutAnyFetchTasks() { m_hasTimedOutAnyFetchTasks = true; }

Source/WebKit/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ set(WebKit_SERIALIZATION_IN_FILES
526526
Shared/ScriptTrackingPrivacyFilter.serialization.in
527527
Shared/ScrollingAccelerationCurve.serialization.in
528528
Shared/SerializedNode.serialization.in
529+
Shared/ServiceWorkerTimingInfo.serialization.in
529530
Shared/SessionState.serialization.in
530531
Shared/SyntheticEditingCommandType.serialization.in
531532
Shared/TextFlags.serialization.in

0 commit comments

Comments
 (0)