Skip to content

Commit

Permalink
core(time-to-first-byte): use receiveHeadersStart (#15126)
Browse files Browse the repository at this point in the history
  • Loading branch information
connorjclark committed Jun 12, 2023
1 parent 1bae933 commit c741df0
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 8 deletions.
14 changes: 8 additions & 6 deletions core/computed/metrics/time-to-first-byte.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,17 @@ class TimeToFirstByte extends NavigationMetric {
* @return {Promise<LH.Artifacts.Metric>}
*/
static async computeObservedMetric(data, context) {
const {processedNavigation} = data;
const timeOriginTs = processedNavigation.timestamps.timeOrigin;
const mainResource = await MainResource.request(data, context);
if (!mainResource.timing) {
throw new Error('missing timing for main resource');
}

// Technically TTFB is the start of the response headers not the end.
// That signal isn't available to us so we use header end time as a best guess.
const timestamp = mainResource.responseHeadersEndTime * 1000;
const {processedNavigation} = data;
const timeOriginTs = processedNavigation.timestamps.timeOrigin;
const timestampMs =
mainResource.timing.requestTime * 1000 + mainResource.timing.receiveHeadersStart;
const timestamp = timestampMs * 1000;
const timing = (timestamp - timeOriginTs) / 1000;

return {timing, timestamp};
}
}
Expand Down
16 changes: 16 additions & 0 deletions core/lib/network-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ class NetworkRequest {
}

this._updateResponseHeadersEndTimeIfNecessary();
this._backfillReceiveHeaderStartTiming();
this._updateTransferSizeForLightrider();
this._updateTimingsForLightrider();
}
Expand All @@ -293,6 +294,7 @@ class NetworkRequest {
this.localizedFailDescription = data.errorText;

this._updateResponseHeadersEndTimeIfNecessary();
this._backfillReceiveHeaderStartTiming();
this._updateTransferSizeForLightrider();
this._updateTimingsForLightrider();
}
Expand All @@ -315,6 +317,7 @@ class NetworkRequest {
this.networkEndTime = data.timestamp * 1000;

this._updateResponseHeadersEndTimeIfNecessary();
this._backfillReceiveHeaderStartTiming();
}

/**
Expand Down Expand Up @@ -449,6 +452,19 @@ class NetworkRequest {
}
}

/**
* TODO(compat): remove M116.
* `timing.receiveHeadersStart` was added recently, and will be in M116. Until then,
* set it to receiveHeadersEnd, which is close enough, to allow consumers of NetworkRequest
* to use the new field without accounting for this backcompat.
*/
_backfillReceiveHeaderStartTiming() {
// Do nothing if a value is already present!
if (!this.timing || this.timing.receiveHeadersStart !== undefined) return;

this.timing.receiveHeadersStart = this.timing.receiveHeadersEnd;
}

/**
* LR gets additional, accurate timing information from its underlying fetch infrastructure. This
* is passed in via X-Headers similar to 'X-TotalFetchedSize'.
Expand Down
2 changes: 1 addition & 1 deletion core/test/computed/metrics/time-to-first-byte-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function mockNetworkRecords() {
networkRequestTime: 300,
responseHeadersEndTime: 400,
networkEndTime: 500,
timing: {sendEnd: 0, receiveHeadersEnd: 100},
timing: {sendEnd: 0, receiveHeadersStart: 100},
transferSize: 16_000,
url: mainDocumentUrl,
frameId: 'ROOT_FRAME',
Expand Down
13 changes: 12 additions & 1 deletion core/test/lib/network-request-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ describe('NetworkRequest', () => {
global.isLightrider = undefined;
});

it('backcompat for receiveHeadersStart', function() {
const req = {
timing: {receiveHeadersEnd: 123},
};
const devtoolsLog = networkRecordsToDevtoolsLog([req]);
const record = NetworkRecorder.recordsFromLogs(devtoolsLog)[0];

expect(record.timing.receiveHeadersStart).toEqual(123);
expect(record.timing.receiveHeadersEnd).toEqual(123);
});

describe('update transfer size for Lightrider', () => {
function getRequest() {
return {
Expand Down Expand Up @@ -108,7 +119,7 @@ describe('NetworkRequest', () => {
});
});

describe('update fetch stats for Lightrider', () => {
describe('update timings for Lightrider', () => {
function getRequest() {
return {
rendererStartTime: 0,
Expand Down

0 comments on commit c741df0

Please sign in to comment.