in src/sdk/trace-metrics.ts [103:156]
static compute(trace: LHProcessedNavigation) {
const traces: Array<TraceOutput> = [];
const { timestamps, timings, lcpInvalidated } = trace;
traces.push(this.buildMetric('navigationStart', timestamps.timeOrigin));
traces.push(
this.buildMetric('firstContentfulPaint', timestamps.firstContentfulPaint)
);
/**
* lcpInvalidated - Denotes when all of the LCP events that comes from the
* current trace are invalidated. Happens if the previous LCP candidates were
* suppressed by another event coming later during the page load
* More info - https://github.com/WICG/largest-contentful-paint/#the-last-candidate
*/
!lcpInvalidated &&
traces.push(
this.buildMetric(
'largestContentfulPaint',
timestamps.largestContentfulPaint
)
);
traces.push(
this.buildMetric('domContentLoaded', timestamps.domContentLoaded)
);
traces.push(this.buildMetric('loadEvent', timestamps.load));
/**
* Lighthouse tracer extracts these metrics in milliseconds resolution,
* we convert them to microseconds resolution to keep them in sync with
* other timings
*/
const millisToMicros = (value?: number) =>
value ? value * 1000 : undefined;
const keys = [
'firstContentfulPaint',
'largestContentfulPaint',
'domContentLoaded',
'load',
];
const values = ['fcp', 'lcp', 'dcl', 'load'];
const metrics = {};
for (let i = 0; i < keys.length; i++) {
const microSecs = millisToMicros(timings[keys[i]]);
if (microSecs) {
metrics[values[i]] = { us: microSecs };
}
}
return {
metrics,
traces: traces.filter(b => Boolean(b)),
};
}