Skip to content

Commit 52eb22c

Browse files
authored
core(lantern): use LCP instead of FMP for TTI simulation bounds (#16046)
1 parent 2fe8847 commit 52eb22c

16 files changed

+104
-69
lines changed

core/audits/metrics/interactive.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
1818

1919
/**
2020
* @fileoverview This audit identifies the time the page is "consistently interactive".
21-
* Looks for the first period of at least 5 seconds after FMP where both CPU and network were quiet,
21+
* Looks for the first period of at least 5 seconds after FCP where both CPU and network were quiet,
2222
* and returns the timestamp of the beginning of the CPU quiet period.
2323
* @see https://docs.google.com/document/d/1GGiI9-7KeY3TPqS3YT271upUVimo-XiL5mwWorDUD4c/edit#
2424
*/

core/computed/metrics/lantern-interactive.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66

77
import {makeComputedArtifact} from '../computed-artifact.js';
8-
import {LanternFirstMeaningfulPaint} from './lantern-first-meaningful-paint.js';
8+
import {LanternLargestContentfulPaint} from './lantern-largest-contentful-paint.js';
99
import {Interactive} from '../../lib/lantern/metrics/interactive.js';
1010
import {getComputationDataParams, lanternErrorAdapter} from './lantern-metric.js';
1111

@@ -29,8 +29,8 @@ class LanternInteractive extends Interactive {
2929
* @return {Promise<LH.Artifacts.LanternMetric>}
3030
*/
3131
static async compute_(data, context) {
32-
const fmpResult = await LanternFirstMeaningfulPaint.request(data, context);
33-
return this.computeMetricWithGraphs(data, context, {fmpResult});
32+
const lcpResult = await LanternLargestContentfulPaint.request(data, context);
33+
return this.computeMetricWithGraphs(data, context, {lcpResult});
3434
}
3535
}
3636

core/lib/lantern/metric.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {RESOURCE_TYPES} from '../../lib/network-request.js';
1616
* @typedef Extras
1717
* @property {boolean} optimistic
1818
* @property {LH.Artifacts.LanternMetric=} fcpResult
19-
* @property {LH.Artifacts.LanternMetric=} fmpResult
19+
* @property {LH.Artifacts.LanternMetric=} lcpResult
2020
* @property {LH.Artifacts.LanternMetric=} interactiveResult
2121
* @property {{speedIndex: number}=} speedline
2222
*/

core/lib/lantern/metrics/interactive.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ class Interactive extends Metric {
6666
* @return {LH.Gatherer.Simulation.Result}
6767
*/
6868
static getEstimateFromSimulation(simulationResult, extras) {
69-
if (!extras.fmpResult) throw new Error('missing fmpResult');
69+
if (!extras.lcpResult) throw new Error('missing lcpResult');
7070

7171
const lastTaskAt = Interactive.getLastLongTaskEndTime(simulationResult.nodeTimings);
7272
const minimumTime = extras.optimistic
73-
? extras.fmpResult.optimisticEstimate.timeInMs
74-
: extras.fmpResult.pessimisticEstimate.timeInMs;
73+
? extras.lcpResult.optimisticEstimate.timeInMs
74+
: extras.lcpResult.pessimisticEstimate.timeInMs;
7575
return {
7676
timeInMs: Math.max(minimumTime, lastTaskAt),
7777
nodeTimings: simulationResult.nodeTimings,
@@ -84,13 +84,13 @@ class Interactive extends Metric {
8484
* @return {Promise<LH.Artifacts.LanternMetric>}
8585
*/
8686
static async compute(data, extras) {
87-
const fmpResult = extras?.fmpResult;
88-
if (!fmpResult) {
89-
throw new Error('FMP is required to calculate the Interactive metric');
87+
const lcpResult = extras?.lcpResult;
88+
if (!lcpResult) {
89+
throw new Error('LCP is required to calculate the Interactive metric');
9090
}
9191

9292
const metricResult = await super.compute(data, extras);
93-
metricResult.timing = Math.max(metricResult.timing, fmpResult.timing);
93+
metricResult.timing = Math.max(metricResult.timing, lcpResult.timing);
9494
return metricResult;
9595
}
9696

core/test/audits/byte-efficiency/offscreen-images-test.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,11 @@ describe('OffscreenImages audit', () => {
458458
src: recordB.url,
459459
}),
460460
],
461-
traces: {defaultPass: createTestTrace({topLevelTasks, networkRecords})},
461+
traces: {defaultPass: createTestTrace({
462+
largestContentfulPaint: 15,
463+
topLevelTasks,
464+
networkRecords,
465+
})},
462466
devtoolsLogs: {defaultPass: devtoolsLog},
463467
URL: {
464468
requestedUrl: recordA.url,
@@ -523,7 +527,11 @@ describe('OffscreenImages audit', () => {
523527
src: recordB.url,
524528
}),
525529
],
526-
traces: {defaultPass: createTestTrace({topLevelTasks, networkRecords})},
530+
traces: {defaultPass: createTestTrace({
531+
largestContentfulPaint: 15,
532+
topLevelTasks,
533+
networkRecords,
534+
})},
527535
devtoolsLogs: {defaultPass: devtoolsLog},
528536
URL: {
529537
requestedUrl: recordA.url,

core/test/audits/dobetterweb/dom-size-test.js

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ describe('DOMSize audit', () => {
2020
const mainDocumentUrl = 'https://example.com/';
2121
const networkRecords = [{url: mainDocumentUrl, priority: 'High'}];
2222
const trace = createTestTrace({
23+
largestContentfulPaint: 15,
2324
topLevelTasks: [
2425
{ts: 1000, duration: 1000, children: [
2526
{ts: 1100, duration: 200, eventName: 'ScheduleStyleRecalculation'},

core/test/audits/long-tasks-test.js

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ function generateTraceWithLongTasks(args) {
5252
traceTasks.push(task);
5353
}
5454
return createTestTrace({
55+
largestContentfulPaint: BASE_TS + 15,
5556
topLevelTasks: traceTasks,
5657
timeOrigin: BASE_TS,
5758
traceEnd: BASE_TS + 20_000,

core/test/audits/redirects-test.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,12 @@ describe('Performance: Redirects audit', () => {
129129
const devtoolsLog = networkRecordsToDevtoolsLog(networkRecords);
130130
const frameUrl = networkRecords[0].url;
131131

132-
const trace = createTestTrace({frameUrl, traceEnd: 5000, networkRecords});
132+
const trace = createTestTrace({
133+
frameUrl,
134+
largestContentfulPaint: 15,
135+
traceEnd: 5000,
136+
networkRecords,
137+
});
133138
const navStart = trace.traceEvents.find(e => e.name === 'navigationStart');
134139
navStart.args.data.navigationId = '1';
135140

core/test/audits/third-party-facades-test.js

+24-4
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ describe('Third party facades audit', () => {
4444
devtoolsLogs: {
4545
defaultPass: networkRecordsToDevtoolsLog(networkRecords),
4646
},
47-
traces: {defaultPass: createTestTrace({timeOrigin: 0, traceEnd: 2000, networkRecords})},
47+
traces: {defaultPass: createTestTrace({
48+
timeOrigin: 0,
49+
largestContentfulPaint: 15,
50+
traceEnd: 2000,
51+
networkRecords,
52+
})},
4853
URL: {
4954
requestedUrl: 'https://example.com',
5055
mainDocumentUrl: 'https://example.com',
@@ -99,7 +104,12 @@ describe('Third party facades audit', () => {
99104
devtoolsLogs: {
100105
defaultPass: networkRecordsToDevtoolsLog(networkRecords),
101106
},
102-
traces: {defaultPass: createTestTrace({timeOrigin: 0, traceEnd: 2000, networkRecords})},
107+
traces: {defaultPass: createTestTrace({
108+
timeOrigin: 0,
109+
largestContentfulPaint: 15,
110+
traceEnd: 2000,
111+
networkRecords,
112+
})},
103113
URL: {
104114
requestedUrl: 'https://example.com',
105115
mainDocumentUrl: 'https://example.com',
@@ -175,7 +185,12 @@ describe('Third party facades audit', () => {
175185
devtoolsLogs: {
176186
defaultPass: networkRecordsToDevtoolsLog(networkRecords),
177187
},
178-
traces: {defaultPass: createTestTrace({timeOrigin: 0, traceEnd: 2000, networkRecords})},
188+
traces: {defaultPass: createTestTrace({
189+
timeOrigin: 0,
190+
largestContentfulPaint: 15,
191+
traceEnd: 2000,
192+
networkRecords,
193+
})},
179194
URL: {
180195
requestedUrl: 'https://example.com',
181196
mainDocumentUrl: 'https://example.com',
@@ -226,7 +241,12 @@ describe('Third party facades audit', () => {
226241
devtoolsLogs: {
227242
defaultPass: networkRecordsToDevtoolsLog(networkRecords),
228243
},
229-
traces: {defaultPass: createTestTrace({timeOrigin: 0, traceEnd: 2000, networkRecords})},
244+
traces: {defaultPass: createTestTrace({
245+
timeOrigin: 0,
246+
largestContentfulPaint: 15,
247+
traceEnd: 2000,
248+
networkRecords,
249+
})},
230250
URL: {
231251
requestedUrl: 'https://intercomcdn.com',
232252
mainDocumentUrl: 'https://intercomcdn.com',

core/test/computed/metrics/interactive-test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ describe('Metrics: TTI', () => {
105105
assert.deepEqual(result.networkQuietPeriod, {start: 0, end: traceEnd / 1000});
106106
});
107107

108-
it('should throw when trace ended too soon after FMP', () => {
108+
it('should throw when trace ended too soon after FCP', () => {
109109
const timeOrigin = 220023532;
110110
const firstContentfulPaint = 2500 * 1000 + timeOrigin;
111111
const traceEnd = 5000 * 1000 + timeOrigin;
@@ -190,7 +190,7 @@ describe('Metrics: TTI', () => {
190190
);
191191

192192
const cpu = [
193-
// quiet period before FMP
193+
// quiet period before FCP
194194
{start: 9000, end: 9900},
195195
{start: 11000, end: 13000},
196196
// quiet period during network activity

core/test/computed/tbt-impact-tasks-test.js

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ describe('TBTImpactTasks', () => {
3434
beforeEach(() => {
3535
metricComputationData = {
3636
trace: createTestTrace({
37+
largestContentfulPaint: 15,
3738
traceEnd: 10_000,
3839
frameUrl: mainDocumentUrl,
3940
topLevelTasks: [

core/test/fixtures/lantern-baseline-accuracy.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
"p95": 0.6524087591240876
1616
},
1717
"roughEstimateOfTTI": {
18-
"p50": 0.28936170212765955,
19-
"p90": 0.6481503092542887,
20-
"p95": 0.7325279801030379
18+
"p50": 0.27433435181143606,
19+
"p90": 0.583952617757166,
20+
"p95": 0.7259561558741738
2121
},
2222
"roughEstimateOfLCP": {
2323
"p50": 0.20067905646890635,

0 commit comments

Comments
 (0)