-
Notifications
You must be signed in to change notification settings - Fork 9.4k
/
trace-engine-result.js
78 lines (68 loc) · 3.06 KB
/
trace-engine-result.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import * as TraceEngine from '../lib/trace-engine.js';
import {makeComputedArtifact} from './computed-artifact.js';
import {CumulativeLayoutShift} from './metrics/cumulative-layout-shift.js';
import {ProcessedTrace} from './processed-trace.js';
import * as LH from '../../types/lh.js';
/**
* @fileoverview Processes trace with the shared trace engine.
*/
class TraceEngineResult {
/**
* @param {LH.TraceEvent[]} traceEvents
* @return {Promise<LH.Artifacts.TraceEngineResult>}
*/
static async runTraceEngine(traceEvents) {
const traceHandlers = {...TraceEngine.TraceHandlers};
// @ts-expect-error Temporarily disable this handler
// It's not currently used anywhere in trace engine insights or Lighthouse.
// TODO: Re-enable this when its memory usage is improved in the trace engine
// https://github.com/GoogleChrome/lighthouse/issues/16111
delete traceHandlers.Invalidations;
const processor = new TraceEngine.TraceProcessor(traceHandlers);
// eslint-disable-next-line max-len
await processor.parse(/** @type {import('@paulirish/trace_engine').Types.TraceEvents.TraceEventData[]} */ (
traceEvents
));
if (!processor.traceParsedData) throw new Error('No data');
if (!processor.insights) throw new Error('No insights');
return {data: processor.traceParsedData, insights: processor.insights};
}
/**
* @param {{trace: LH.Trace}} data
* @param {LH.Artifacts.ComputedContext} context
* @return {Promise<LH.Artifacts.TraceEngineResult>}
*/
static async compute_(data, context) {
// In CumulativeLayoutShift.getLayoutShiftEvents we handle a bug in Chrome layout shift
// trace events re: changing the viewport emulation resulting in incorrectly set `had_recent_input`.
// Below, the same logic is applied to set those problem events' `had_recent_input` to false, so that
// the trace engine will count them.
// The trace events are copied-on-write, so the original trace remains unmodified.
const processedTrace = await ProcessedTrace.request(data.trace, context);
const layoutShiftEvents = new Set(
CumulativeLayoutShift.getLayoutShiftEvents(processedTrace).map(e => e.event));
// Avoid modifying the input array.
const traceEvents = [...data.trace.traceEvents];
for (let i = 0; i < traceEvents.length; i++) {
let event = traceEvents[i];
if (event.name !== 'LayoutShift') continue;
if (!event.args.data) continue;
const isConsidered = layoutShiftEvents.has(event);
if (event.args.data.had_recent_input && isConsidered) {
event = JSON.parse(JSON.stringify(event));
// @ts-expect-error impossible for data to be missing.
event.args.data.had_recent_input = false;
traceEvents[i] = event;
}
}
const result = await TraceEngineResult.runTraceEngine(traceEvents);
return result;
}
}
const TraceEngineResultComputed = makeComputedArtifact(TraceEngineResult, ['trace']);
export {TraceEngineResultComputed as TraceEngineResult};