Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split waitingDuration to make it easier to understand redirect delays #458

Merged
merged 29 commits into from Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog

### v4.0.0-beta.2 (???)

- **[BREAKING]** Split `waitingDuration` in `TTFBAttribution` into `redirectDuration` and `cacheDuration` ([#458](https://github.com/GoogleChrome/web-vitals/pull/458))

### v4.0.0-beta.1 (2024-04-01)

- **[BREAKING]** Rename `TTFBAttribution` fields from `*Time` to `*Duration` ([#453](https://github.com/GoogleChrome/web-vitals/pull/453))
Expand Down
11 changes: 8 additions & 3 deletions README.md
Expand Up @@ -1024,11 +1024,16 @@ interface LCPAttribution {
```ts
interface TTFBAttribution {
/**
* The total time from when the user initiates loading the page to when the
* DNS lookup begins. This includes redirects, service worker startup, and
* The total time spent in redirects before the current page processes the
* request. Npote in future this may only include same-origin redirects.
tunetheweb marked this conversation as resolved.
Show resolved Hide resolved
*/
redirectDuration: number;
/**
* The total time spent looking up local caches for the navigation request.
* This includes service worker startup, service worker fetch processing, and
* HTTP cache lookup times.
*/
waitingDuration: number;
cacheDuration: number;
/**
* The total time to resolve the DNS for the current request.
*/
Expand Down
2 changes: 1 addition & 1 deletion docs/upgrading-to-v4.md
Expand Up @@ -36,7 +36,7 @@ npm install web-vitals@next

#### `TTFBAttribution`

- **Renamed** `waitingTime` to `waitingDuration` (see [#453](https://github.com/GoogleChrome/web-vitals/pull/453)).
- **Split** `waitingTime` into `redirectDuration` and `cacheDuration` ([#458](https://github.com/GoogleChrome/web-vitals/pull/458))
tunetheweb marked this conversation as resolved.
Show resolved Hide resolved
- **Renamed** `dnsTime` to `dnsDuration` (see [#453](https://github.com/GoogleChrome/web-vitals/pull/453)).
- **Renamed** `connectionTime` to `connectionDuration` (see [#453](https://github.com/GoogleChrome/web-vitals/pull/453)).
- **Renamed** `requestTime` to `requestDuration` (see [#453](https://github.com/GoogleChrome/web-vitals/pull/453)).
Expand Down
19 changes: 17 additions & 2 deletions src/attribution/onTTFB.ts
Expand Up @@ -28,6 +28,15 @@ const attributeTTFB = (metric: TTFBMetric): void => {
const navigationEntry = metric.entries[0];
const activationStart = navigationEntry.activationStart || 0;

const redirectEnd = Math.max(
tunetheweb marked this conversation as resolved.
Show resolved Hide resolved
navigationEntry.redirectEnd - activationStart,
0,
);
const cacheStart = Math.max(
(navigationEntry.workerStart || navigationEntry.fetchStart) -
philipwalton marked this conversation as resolved.
Show resolved Hide resolved
activationStart,
0,
);
const dnsStart = Math.max(
navigationEntry.domainLookupStart - activationStart,
0,
Expand All @@ -42,7 +51,12 @@ const attributeTTFB = (metric: TTFBMetric): void => {
);

(metric as TTFBMetricWithAttribution).attribution = {
waitingDuration: dnsStart,
// Set redirectend to be based on fetchStart and workerStart to get most
// accurate redirect time available now.
// Note this may change in future. See
// https://github.com/w3c/navigation-timing/issues/160
redirectDuration: redirectEnd || cacheStart,
tunetheweb marked this conversation as resolved.
Show resolved Hide resolved
cacheDuration: dnsStart - (redirectEnd || cacheStart),
dnsDuration: connectStart - dnsStart,
connectionDuration: requestStart - connectStart,
requestDuration: metric.value - requestStart,
Expand All @@ -52,7 +66,8 @@ const attributeTTFB = (metric: TTFBMetric): void => {
}
// Set an empty object if no other attribution has been set.
(metric as TTFBMetricWithAttribution).attribution = {
waitingDuration: 0,
redirectDuration: 0,
cacheDuration: 0,
dnsDuration: 0,
connectionDuration: 0,
requestDuration: 0,
Expand Down
11 changes: 8 additions & 3 deletions src/types/ttfb.ts
Expand Up @@ -31,11 +31,16 @@ export interface TTFBMetric extends Metric {
*/
export interface TTFBAttribution {
/**
* The total time from when the user initiates loading the page to when the
* DNS lookup begins. This includes redirects, service worker startup, and
* The total time spent in redirects before the current page processes the
* request. Npote in future this may only include same-origin redirects.
tunetheweb marked this conversation as resolved.
Show resolved Hide resolved
*/
redirectDuration: number;
/**
* The total time spent looking up local caches for the navigation request.
* This includes service worker startup, service worker fetch processing, and
* HTTP cache lookup times.
*/
waitingDuration: number;
cacheDuration: number;
/**
* The total time to resolve the DNS for the current request.
*/
Expand Down
37 changes: 32 additions & 5 deletions test/e2e/onTTFB-test.js
Expand Up @@ -261,8 +261,19 @@ describe('onTTFB()', async function () {

const navEntry = ttfb.entries[0];
assert.strictEqual(
ttfb.attribution.waitingDuration,
navEntry.domainLookupStart,
ttfb.attribution.redirectDuration,
Math.max(
tunetheweb marked this conversation as resolved.
Show resolved Hide resolved
0,
navEntry.redirectEnd || navEntry.workerStart || navEntry.fetchStart,
tunetheweb marked this conversation as resolved.
Show resolved Hide resolved
),
);
assert.strictEqual(
ttfb.attribution.cacheDuration,
Math.max(0, navEntry.domainLookupStart) -
Math.max(
0,
navEntry.redirectEnd || navEntry.workerStart || navEntry.fetchStart,
),
);
assert.strictEqual(
ttfb.attribution.dnsDuration,
Expand Down Expand Up @@ -303,8 +314,23 @@ describe('onTTFB()', async function () {

const navEntry = ttfb.entries[0];
assert.strictEqual(
ttfb.attribution.waitingDuration,
Math.max(0, navEntry.domainLookupStart - activationStart),
ttfb.attribution.redirectDuration,
Math.max(
0,
(navEntry.redirectEnd ||
navEntry.workerStart ||
navEntry.fetchStart) - activationStart,
),
);
assert.strictEqual(
ttfb.attribution.cacheDuration,
Math.max(0, navEntry.domainLookupStart - activationStart) -
Math.max(
0,
(navEntry.redirectEnd ||
navEntry.workerStart ||
navEntry.fetchStart) - activationStart,
),
);
assert.strictEqual(
ttfb.attribution.dnsDuration,
Expand Down Expand Up @@ -346,7 +372,8 @@ describe('onTTFB()', async function () {
assert.strictEqual(ttfb.navigationType, 'back-forward-cache');
assert.strictEqual(ttfb.entries.length, 0);

assert.strictEqual(ttfb.attribution.waitingDuration, 0);
assert.strictEqual(ttfb.attribution.redirectDuration, 0);
assert.strictEqual(ttfb.attribution.cacheDuration, 0);
assert.strictEqual(ttfb.attribution.dnsDuration, 0);
assert.strictEqual(ttfb.attribution.connectionDuration, 0);
assert.strictEqual(ttfb.attribution.requestDuration, 0);
Expand Down