lighthouse 11.7.0-dev.20240410 → 11.7.0-dev.20240411

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/core/audits/byte-efficiency/render-blocking-resources.js +25 -26
  2. package/core/audits/layout-shifts.js +1 -1
  3. package/core/computed/metrics/lantern-first-contentful-paint.js +3 -2
  4. package/core/computed/metrics/lantern-first-meaningful-paint.js +3 -2
  5. package/core/computed/metrics/lantern-interactive.js +3 -2
  6. package/core/computed/metrics/lantern-largest-contentful-paint.js +3 -2
  7. package/core/computed/metrics/lantern-max-potential-fid.js +3 -2
  8. package/core/computed/metrics/lantern-metric.d.ts +5 -0
  9. package/core/computed/metrics/lantern-metric.js +23 -1
  10. package/core/computed/metrics/lantern-speed-index.js +3 -2
  11. package/core/computed/navigation-insights.d.ts +36 -0
  12. package/core/computed/navigation-insights.js +35 -0
  13. package/core/computed/trace-engine-result.d.ts +16 -3
  14. package/core/computed/trace-engine-result.js +19 -14
  15. package/core/config/default-config.js +0 -1
  16. package/core/config/filters.js +0 -1
  17. package/core/gather/gatherers/root-causes.d.ts +2 -2
  18. package/core/gather/gatherers/root-causes.js +6 -5
  19. package/core/gather/gatherers/trace-elements.d.ts +2 -2
  20. package/core/gather/gatherers/trace-elements.js +2 -2
  21. package/core/lib/lantern/cpu-node.d.ts +7 -1
  22. package/core/lib/lantern/cpu-node.js +12 -2
  23. package/core/lib/lantern/lantern-error.d.ts +8 -0
  24. package/core/lib/lantern/lantern-error.js +9 -0
  25. package/core/lib/lantern/metrics/first-meaningful-paint.js +2 -4
  26. package/core/lib/lantern/metrics/interactive.js +1 -1
  27. package/core/lib/lantern/metrics/largest-contentful-paint.js +3 -3
  28. package/core/lib/lantern/page-dependency-graph.js +14 -2
  29. package/core/lib/lantern/simulator/simulator.js +1 -1
  30. package/core/lib/lh-error.js +3 -3
  31. package/core/runner.js +0 -1
  32. package/package.json +1 -1
  33. package/tsconfig.json +0 -1
  34. package/types/artifacts.d.ts +15 -63
  35. package/types/lhr/lhr.d.ts +0 -2
  36. package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.d.ts +0 -47
  37. package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.js +0 -233
@@ -14,10 +14,10 @@ import * as i18n from '../../lib/i18n/i18n.js';
14
14
  import {BaseNode} from '../../lib/lantern/base-node.js';
15
15
  import {UnusedCSS} from '../../computed/unused-css.js';
16
16
  import {NetworkRequest} from '../../lib/network-request.js';
17
- import {ProcessedNavigation} from '../../computed/processed-navigation.js';
18
17
  import {LoadSimulator} from '../../computed/load-simulator.js';
19
18
  import {FirstContentfulPaint} from '../../computed/metrics/first-contentful-paint.js';
20
19
  import {LCPImageRecord} from '../../computed/lcp-image-record.js';
20
+ import {NavigationInsights} from '../../computed/navigation-insights.js';
21
21
 
22
22
 
23
23
  /** @typedef {import('../../lib/lantern/simulator/simulator.js').Simulator} Simulator */
@@ -44,21 +44,19 @@ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
44
44
  /**
45
45
  * Given a simulation's nodeTimings, return an object with the nodes/timing keyed by network URL
46
46
  * @param {LH.Gatherer.Simulation.Result['nodeTimings']} nodeTimings
47
- * @return {Object<string, {node: Node, nodeTiming: LH.Gatherer.Simulation.NodeTiming}>}
47
+ * @return {Map<string, {node: Node, nodeTiming: LH.Gatherer.Simulation.NodeTiming}>}
48
48
  */
49
- function getNodesAndTimingByUrl(nodeTimings) {
50
- /** @type {Object<string, {node: Node, nodeTiming: LH.Gatherer.Simulation.NodeTiming}>} */
51
- const urlMap = {};
52
- const nodes = Array.from(nodeTimings.keys());
53
- nodes.forEach(node => {
54
- if (node.type !== 'network') return;
55
- const nodeTiming = nodeTimings.get(node);
56
- if (!nodeTiming) return;
57
-
58
- urlMap[node.record.url] = {node, nodeTiming};
59
- });
49
+ function getNodesAndTimingByRequestId(nodeTimings) {
50
+ /** @type {Map<string, {node: Node, nodeTiming: LH.Gatherer.Simulation.NodeTiming}>} */
51
+ const requestIdToNode = new Map();
52
+
53
+ for (const [node, nodeTiming] of nodeTimings) {
54
+ if (node.type !== 'network') continue;
60
55
 
61
- return urlMap;
56
+ requestIdToNode.set(node.record.requestId, {node, nodeTiming});
57
+ }
58
+
59
+ return requestIdToNode;
62
60
  }
63
61
 
64
62
  /**
@@ -119,8 +117,7 @@ class RenderBlockingResources extends Audit {
119
117
  guidanceLevel: 2,
120
118
  // TODO: look into adding an `optionalArtifacts` property that captures the non-required nature
121
119
  // of CSSUsage
122
- requiredArtifacts: ['URL', 'TagsBlockingFirstPaint', 'traces', 'devtoolsLogs', 'CSSUsage',
123
- 'GatherContext', 'Stacks'],
120
+ requiredArtifacts: ['URL', 'traces', 'devtoolsLogs', 'CSSUsage', 'GatherContext', 'Stacks'],
124
121
  };
125
122
  }
126
123
 
@@ -134,9 +131,12 @@ class RenderBlockingResources extends Audit {
134
131
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
135
132
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
136
133
  const simulatorData = {devtoolsLog, settings: context.settings};
137
- const processedNavigation = await ProcessedNavigation.request(trace, context);
138
134
  const simulator = await LoadSimulator.request(simulatorData, context);
139
135
  const wastedCssBytes = await RenderBlockingResources.computeWastedCSSBytes(artifacts, context);
136
+ const navInsights = await NavigationInsights.request(trace, context);
137
+
138
+ const renderBlocking = navInsights.RenderBlocking;
139
+ if (renderBlocking instanceof Error) throw renderBlocking;
140
140
 
141
141
  /** @type {LH.Audit.Context['settings']} */
142
142
  const metricSettings = {
@@ -150,19 +150,18 @@ class RenderBlockingResources extends Audit {
150
150
  // Cast to just `LanternMetric` since we explicitly set `throttlingMethod: 'simulate'`.
151
151
  const fcpSimulation = /** @type {LH.Artifacts.LanternMetric} */
152
152
  (await FirstContentfulPaint.request(metricComputationData, context));
153
- const fcpTsInMs = processedNavigation.timestamps.firstContentfulPaint / 1000;
154
153
 
155
- const nodesByUrl = getNodesAndTimingByUrl(fcpSimulation.optimisticEstimate.nodeTimings);
154
+ const nodesAndTimingsByRequestId =
155
+ getNodesAndTimingByRequestId(fcpSimulation.optimisticEstimate.nodeTimings);
156
156
 
157
157
  const results = [];
158
158
  const deferredNodeIds = new Set();
159
- for (const resource of artifacts.TagsBlockingFirstPaint) {
160
- // Ignore any resources that finished after observed FCP (they're clearly not render-blocking)
161
- if (resource.endTime > fcpTsInMs) continue;
159
+ for (const resource of renderBlocking.renderBlockingRequests) {
160
+ const nodeAndTiming = nodesAndTimingsByRequestId.get(resource.args.data.requestId);
162
161
  // TODO: beacon to Sentry, https://github.com/GoogleChrome/lighthouse/issues/7041
163
- if (!nodesByUrl[resource.tag.url]) continue;
162
+ if (!nodeAndTiming) continue;
164
163
 
165
- const {node, nodeTiming} = nodesByUrl[resource.tag.url];
164
+ const {node, nodeTiming} = nodeAndTiming;
166
165
 
167
166
  const stackSpecificTiming = computeStackSpecificTiming(node, nodeTiming, artifacts.Stacks);
168
167
 
@@ -174,8 +173,8 @@ class RenderBlockingResources extends Audit {
174
173
  if (wastedMs < MINIMUM_WASTED_MS) continue;
175
174
 
176
175
  results.push({
177
- url: resource.tag.url,
178
- totalBytes: resource.transferSize,
176
+ url: resource.args.data.url,
177
+ totalBytes: resource.args.data.encodedDataLength,
179
178
  wastedMs,
180
179
  });
181
180
  }
@@ -61,7 +61,7 @@ class LayoutShifts extends Audit {
61
61
  static async audit(artifacts, context) {
62
62
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
63
63
  const traceEngineResult = await TraceEngineResult.request({trace}, context);
64
- const clusters = traceEngineResult.LayoutShifts.clusters ?? [];
64
+ const clusters = traceEngineResult.data.LayoutShifts.clusters ?? [];
65
65
  const {cumulativeLayoutShift: clsSavings, impactByNodeId} =
66
66
  await CumulativeLayoutShiftComputed.request(trace, context);
67
67
  const traceElements = artifacts.TraceElements
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import {makeComputedArtifact} from '../computed-artifact.js';
8
- import {getComputationDataParams} from './lantern-metric.js';
8
+ import {getComputationDataParams, lanternErrorAdapter} from './lantern-metric.js';
9
9
  import {FirstContentfulPaint} from '../../lib/lantern/metrics/first-contentful-paint.js';
10
10
 
11
11
  /** @typedef {import('../../lib/lantern/metric.js').Extras} Extras */
@@ -18,7 +18,8 @@ class LanternFirstContentfulPaint extends FirstContentfulPaint {
18
18
  * @return {Promise<LH.Artifacts.LanternMetric>}
19
19
  */
20
20
  static async computeMetricWithGraphs(data, context, extras) {
21
- return this.compute(await getComputationDataParams(data, context), extras);
21
+ return this.compute(await getComputationDataParams(data, context), extras)
22
+ .catch(lanternErrorAdapter);
22
23
  }
23
24
 
24
25
  /**
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import {makeComputedArtifact} from '../computed-artifact.js';
8
- import {getComputationDataParams} from './lantern-metric.js';
8
+ import {getComputationDataParams, lanternErrorAdapter} from './lantern-metric.js';
9
9
  import {FirstMeaningfulPaint} from '../../lib/lantern/metrics/first-meaningful-paint.js';
10
10
  import {LanternFirstContentfulPaint} from './lantern-first-contentful-paint.js';
11
11
 
@@ -19,7 +19,8 @@ class LanternFirstMeaningfulPaint extends FirstMeaningfulPaint {
19
19
  * @return {Promise<LH.Artifacts.LanternMetric>}
20
20
  */
21
21
  static async computeMetricWithGraphs(data, context, extras) {
22
- return this.compute(await getComputationDataParams(data, context), extras);
22
+ return this.compute(await getComputationDataParams(data, context), extras)
23
+ .catch(lanternErrorAdapter);
23
24
  }
24
25
 
25
26
  /**
@@ -7,7 +7,7 @@
7
7
  import {makeComputedArtifact} from '../computed-artifact.js';
8
8
  import {LanternFirstMeaningfulPaint} from './lantern-first-meaningful-paint.js';
9
9
  import {Interactive} from '../../lib/lantern/metrics/interactive.js';
10
- import {getComputationDataParams} from './lantern-metric.js';
10
+ import {getComputationDataParams, lanternErrorAdapter} from './lantern-metric.js';
11
11
 
12
12
  /** @typedef {import('../../lib/lantern/metric.js').Extras} Extras */
13
13
 
@@ -19,7 +19,8 @@ class LanternInteractive extends Interactive {
19
19
  * @return {Promise<LH.Artifacts.LanternMetric>}
20
20
  */
21
21
  static async computeMetricWithGraphs(data, context, extras) {
22
- return this.compute(await getComputationDataParams(data, context), extras);
22
+ return this.compute(await getComputationDataParams(data, context), extras)
23
+ .catch(lanternErrorAdapter);
23
24
  }
24
25
 
25
26
  /**
@@ -6,7 +6,7 @@
6
6
 
7
7
  import {makeComputedArtifact} from '../computed-artifact.js';
8
8
  import {LargestContentfulPaint} from '../../lib/lantern/metrics/largest-contentful-paint.js';
9
- import {getComputationDataParams} from './lantern-metric.js';
9
+ import {getComputationDataParams, lanternErrorAdapter} from './lantern-metric.js';
10
10
  import {LanternFirstContentfulPaint} from './lantern-first-contentful-paint.js';
11
11
 
12
12
  /** @typedef {import('../../lib/lantern/metric.js').Extras} Extras */
@@ -19,7 +19,8 @@ class LanternLargestContentfulPaint extends LargestContentfulPaint {
19
19
  * @return {Promise<LH.Artifacts.LanternMetric>}
20
20
  */
21
21
  static async computeMetricWithGraphs(data, context, extras) {
22
- return this.compute(await getComputationDataParams(data, context), extras);
22
+ return this.compute(await getComputationDataParams(data, context), extras)
23
+ .catch(lanternErrorAdapter);
23
24
  }
24
25
 
25
26
  /**
@@ -6,7 +6,7 @@
6
6
 
7
7
  import {makeComputedArtifact} from '../computed-artifact.js';
8
8
  import {MaxPotentialFID} from '../../lib/lantern/metrics/max-potential-fid.js';
9
- import {getComputationDataParams} from './lantern-metric.js';
9
+ import {getComputationDataParams, lanternErrorAdapter} from './lantern-metric.js';
10
10
  import {LanternFirstContentfulPaint} from './lantern-first-contentful-paint.js';
11
11
 
12
12
  /** @typedef {import('../../lib/lantern/metric.js').Extras} Extras */
@@ -19,7 +19,8 @@ class LanternMaxPotentialFID extends MaxPotentialFID {
19
19
  * @return {Promise<LH.Artifacts.LanternMetric>}
20
20
  */
21
21
  static async computeMetricWithGraphs(data, context, extras) {
22
- return this.compute(await getComputationDataParams(data, context), extras);
22
+ return this.compute(await getComputationDataParams(data, context), extras)
23
+ .catch(lanternErrorAdapter);
23
24
  }
24
25
 
25
26
  /**
@@ -7,4 +7,9 @@ export function getComputationDataParams(data: LH.Artifacts.MetricComputationDat
7
7
  graph: import("../page-dependency-graph.js").Node;
8
8
  processedNavigation: import("../../index.js").Artifacts.ProcessedNavigation;
9
9
  }>;
10
+ /**
11
+ * @param {unknown} err
12
+ * @return {never}
13
+ */
14
+ export function lanternErrorAdapter(err: unknown): never;
10
15
  //# sourceMappingURL=lantern-metric.d.ts.map
@@ -4,6 +4,8 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
+ import {LanternError} from '../../lib/lantern/lantern-error.js';
8
+ import {LighthouseError} from '../../lib/lh-error.js';
7
9
  import {LoadSimulator} from '../load-simulator.js';
8
10
  import {PageDependencyGraph} from '../page-dependency-graph.js';
9
11
  import {ProcessedNavigation} from '../processed-navigation.js';
@@ -24,4 +26,24 @@ async function getComputationDataParams(data, context) {
24
26
  return {simulator, graph, processedNavigation};
25
27
  }
26
28
 
27
- export {getComputationDataParams};
29
+ /**
30
+ * @param {unknown} err
31
+ * @return {never}
32
+ */
33
+ function lanternErrorAdapter(err) {
34
+ if (!(err instanceof LanternError)) {
35
+ throw err;
36
+ }
37
+
38
+ const code = /** @type {keyof LighthouseError.errors} */ (err.message);
39
+ if (LighthouseError.errors[code]) {
40
+ throw new LighthouseError(LighthouseError.errors[code]);
41
+ }
42
+
43
+ throw err;
44
+ }
45
+
46
+ export {
47
+ getComputationDataParams,
48
+ lanternErrorAdapter,
49
+ };
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import {makeComputedArtifact} from '../computed-artifact.js';
8
- import {getComputationDataParams} from './lantern-metric.js';
8
+ import {getComputationDataParams, lanternErrorAdapter} from './lantern-metric.js';
9
9
  import {Speedline} from '../speedline.js';
10
10
  import {LanternFirstContentfulPaint} from './lantern-first-contentful-paint.js';
11
11
  import {SpeedIndex} from '../../lib/lantern/metrics/speed-index.js';
@@ -20,7 +20,8 @@ class LanternSpeedIndex extends SpeedIndex {
20
20
  * @return {Promise<LH.Artifacts.LanternMetric>}
21
21
  */
22
22
  static async computeMetricWithGraphs(data, context, extras) {
23
- return this.compute(await getComputationDataParams(data, context), extras);
23
+ return this.compute(await getComputationDataParams(data, context), extras)
24
+ .catch(lanternErrorAdapter);
24
25
  }
25
26
 
26
27
  /**
@@ -0,0 +1,36 @@
1
+ export { NavigationInsightsComputed as NavigationInsights };
2
+ declare const NavigationInsightsComputed: typeof NavigationInsights & {
3
+ request: (dependencies: import("../index.js").Trace, context: import("../../types/utility-types.js").default.ImmutableObject<{
4
+ computedCache: Map<string, import("../lib/arbitrary-equality-map.js").ArbitraryEqualityMap>;
5
+ }>) => Promise<import("@paulirish/trace_engine/models/trace/insights/types.js").NavigationInsightData<{
6
+ AuctionWorklets: typeof import("@paulirish/trace_engine/models/trace/handlers/AuctionWorkletsHandler.js");
7
+ Initiators: typeof import("@paulirish/trace_engine/models/trace/handlers/InitiatorsHandler.js");
8
+ LayoutShifts: typeof import("@paulirish/trace_engine/models/trace/handlers/LayoutShiftsHandler.js");
9
+ NetworkRequests: typeof import("@paulirish/trace_engine/models/trace/handlers/NetworkRequestsHandler.js");
10
+ Renderer: typeof import("@paulirish/trace_engine/models/trace/handlers/RendererHandler.js");
11
+ Samples: typeof import("@paulirish/trace_engine/models/trace/handlers/SamplesHandler.js");
12
+ Screenshots: typeof import("@paulirish/trace_engine/models/trace/handlers/ScreenshotsHandler.js");
13
+ PageLoadMetrics: typeof import("@paulirish/trace_engine/models/trace/handlers/PageLoadMetricsHandler.js");
14
+ }>>;
15
+ };
16
+ /**
17
+ * @fileoverview Gets insights from the shared trace engine for the navigation audited by Lighthouse.
18
+ * Only usable in navigation mode.
19
+ */
20
+ declare class NavigationInsights {
21
+ /**
22
+ * @param {LH.Trace} trace
23
+ * @param {LH.Artifacts.ComputedContext} context
24
+ */
25
+ static compute_(trace: LH.Trace, context: LH.Artifacts.ComputedContext): Promise<import("@paulirish/trace_engine/models/trace/insights/types.js").NavigationInsightData<{
26
+ AuctionWorklets: typeof import("@paulirish/trace_engine/models/trace/handlers/AuctionWorkletsHandler.js");
27
+ Initiators: typeof import("@paulirish/trace_engine/models/trace/handlers/InitiatorsHandler.js");
28
+ LayoutShifts: typeof import("@paulirish/trace_engine/models/trace/handlers/LayoutShiftsHandler.js");
29
+ NetworkRequests: typeof import("@paulirish/trace_engine/models/trace/handlers/NetworkRequestsHandler.js");
30
+ Renderer: typeof import("@paulirish/trace_engine/models/trace/handlers/RendererHandler.js");
31
+ Samples: typeof import("@paulirish/trace_engine/models/trace/handlers/SamplesHandler.js");
32
+ Screenshots: typeof import("@paulirish/trace_engine/models/trace/handlers/ScreenshotsHandler.js");
33
+ PageLoadMetrics: typeof import("@paulirish/trace_engine/models/trace/handlers/PageLoadMetricsHandler.js");
34
+ }>>;
35
+ }
36
+ //# sourceMappingURL=navigation-insights.d.ts.map
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import {makeComputedArtifact} from './computed-artifact.js';
8
+ import {ProcessedTrace} from './processed-trace.js';
9
+ import {TraceEngineResult} from './trace-engine-result.js';
10
+
11
+ /**
12
+ * @fileoverview Gets insights from the shared trace engine for the navigation audited by Lighthouse.
13
+ * Only usable in navigation mode.
14
+ */
15
+ class NavigationInsights {
16
+ /**
17
+ * @param {LH.Trace} trace
18
+ * @param {LH.Artifacts.ComputedContext} context
19
+ */
20
+ static async compute_(trace, context) {
21
+ const processedTrace = await ProcessedTrace.request(trace, context);
22
+ const traceEngineResult = await TraceEngineResult.request({trace}, context);
23
+
24
+ const navigationId = processedTrace.timeOriginEvt.args.data?.navigationId;
25
+ if (!navigationId) throw new Error('No navigationId found');
26
+
27
+ const navInsights = traceEngineResult.insights.get(navigationId);
28
+ if (!navInsights) throw new Error('No navigations insights found');
29
+
30
+ return navInsights;
31
+ }
32
+ }
33
+
34
+ const NavigationInsightsComputed = makeComputedArtifact(NavigationInsights, null);
35
+ export {NavigationInsightsComputed as NavigationInsights};
@@ -1,19 +1,31 @@
1
1
  export { TraceEngineResultComputed as TraceEngineResult };
2
+ export type EnabledHandlers = typeof ENABLED_HANDLERS;
2
3
  declare const TraceEngineResultComputed: typeof TraceEngineResult & {
3
4
  request: (dependencies: {
4
5
  trace: LH.Trace;
5
- }, context: import("../../types/utility-types.js").default.ImmutableObject<{
6
+ }, context: LH.Util.ImmutableObject<{
6
7
  computedCache: Map<string, import("../lib/arbitrary-equality-map.js").ArbitraryEqualityMap>;
7
- }>) => Promise<Readonly<import("@paulirish/trace_engine/models/trace/handlers/types.js").EnabledHandlerDataWithMeta<typeof import("@paulirish/trace_engine/models/trace/handlers/ModelHandlers.js")>>>;
8
+ }>) => Promise<LH.Artifacts.TraceEngineResult>;
8
9
  };
10
+ declare namespace ENABLED_HANDLERS {
11
+ const AuctionWorklets: typeof import("@paulirish/trace_engine/models/trace/handlers/AuctionWorkletsHandler.js");
12
+ const Initiators: typeof import("@paulirish/trace_engine/models/trace/handlers/InitiatorsHandler.js");
13
+ const LayoutShifts: typeof import("@paulirish/trace_engine/models/trace/handlers/LayoutShiftsHandler.js");
14
+ const NetworkRequests: typeof import("@paulirish/trace_engine/models/trace/handlers/NetworkRequestsHandler.js");
15
+ const Renderer: typeof import("@paulirish/trace_engine/models/trace/handlers/RendererHandler.js");
16
+ const Samples: typeof import("@paulirish/trace_engine/models/trace/handlers/SamplesHandler.js");
17
+ const Screenshots: typeof import("@paulirish/trace_engine/models/trace/handlers/ScreenshotsHandler.js");
18
+ const PageLoadMetrics: typeof import("@paulirish/trace_engine/models/trace/handlers/PageLoadMetricsHandler.js");
19
+ }
9
20
  /**
10
21
  * @fileoverview Processes trace with the shared trace engine.
11
22
  */
12
23
  declare class TraceEngineResult {
13
24
  /**
14
25
  * @param {LH.TraceEvent[]} traceEvents
26
+ * @return {Promise<LH.Artifacts.TraceEngineResult>}
15
27
  */
16
- static runTraceEngine(traceEvents: LH.TraceEvent[]): Promise<Readonly<import("@paulirish/trace_engine/models/trace/handlers/types.js").EnabledHandlerDataWithMeta<typeof import("@paulirish/trace_engine/models/trace/handlers/ModelHandlers.js")>>>;
28
+ static runTraceEngine(traceEvents: LH.TraceEvent[]): Promise<LH.Artifacts.TraceEngineResult>;
17
29
  /**
18
30
  * @param {{trace: LH.Trace}} data
19
31
  * @param {LH.Artifacts.ComputedContext} context
@@ -23,4 +35,5 @@ declare class TraceEngineResult {
23
35
  trace: LH.Trace;
24
36
  }, context: LH.Artifacts.ComputedContext): Promise<LH.Artifacts.TraceEngineResult>;
25
37
  }
38
+ import * as LH from '../../types/lh.js';
26
39
  //# sourceMappingURL=trace-engine-result.d.ts.map
@@ -8,6 +8,20 @@ import * as TraceEngine from '../lib/trace-engine.js';
8
8
  import {makeComputedArtifact} from './computed-artifact.js';
9
9
  import {CumulativeLayoutShift} from './metrics/cumulative-layout-shift.js';
10
10
  import {ProcessedTrace} from './processed-trace.js';
11
+ import * as LH from '../../types/lh.js';
12
+
13
+ /** @typedef {typeof ENABLED_HANDLERS} EnabledHandlers */
14
+
15
+ const ENABLED_HANDLERS = {
16
+ AuctionWorklets: TraceEngine.TraceHandlers.AuctionWorklets,
17
+ Initiators: TraceEngine.TraceHandlers.Initiators,
18
+ LayoutShifts: TraceEngine.TraceHandlers.LayoutShifts,
19
+ NetworkRequests: TraceEngine.TraceHandlers.NetworkRequests,
20
+ Renderer: TraceEngine.TraceHandlers.Renderer,
21
+ Samples: TraceEngine.TraceHandlers.Samples,
22
+ Screenshots: TraceEngine.TraceHandlers.Screenshots,
23
+ PageLoadMetrics: TraceEngine.TraceHandlers.PageLoadMetrics,
24
+ };
11
25
 
12
26
  /**
13
27
  * @fileoverview Processes trace with the shared trace engine.
@@ -15,24 +29,18 @@ import {ProcessedTrace} from './processed-trace.js';
15
29
  class TraceEngineResult {
16
30
  /**
17
31
  * @param {LH.TraceEvent[]} traceEvents
32
+ * @return {Promise<LH.Artifacts.TraceEngineResult>}
18
33
  */
19
34
  static async runTraceEngine(traceEvents) {
20
- const engine = new TraceEngine.TraceProcessor({
21
- AuctionWorklets: TraceEngine.TraceHandlers.AuctionWorklets,
22
- Initiators: TraceEngine.TraceHandlers.Initiators,
23
- LayoutShifts: TraceEngine.TraceHandlers.LayoutShifts,
24
- NetworkRequests: TraceEngine.TraceHandlers.NetworkRequests,
25
- Renderer: TraceEngine.TraceHandlers.Renderer,
26
- Samples: TraceEngine.TraceHandlers.Samples,
27
- Screenshots: TraceEngine.TraceHandlers.Screenshots,
28
- });
35
+ const engine = new TraceEngine.TraceProcessor(ENABLED_HANDLERS);
29
36
  // eslint-disable-next-line max-len
30
37
  await engine.parse(/** @type {import('@paulirish/trace_engine').Types.TraceEvents.TraceEventData[]} */ (
31
38
  traceEvents
32
39
  ));
33
40
  // TODO: use TraceEngine.TraceProcessor.createWithAllHandlers above.
34
- return /** @type {import('@paulirish/trace_engine').Handlers.Types.TraceParseData} */(
35
- engine.traceParsedData);
41
+ if (!engine.traceParsedData) throw new Error('No data');
42
+ if (!engine.insights) throw new Error('No insights');
43
+ return {data: engine.traceParsedData, insights: engine.insights};
36
44
  }
37
45
 
38
46
  /**
@@ -67,9 +75,6 @@ class TraceEngineResult {
67
75
  }
68
76
 
69
77
  const result = await TraceEngineResult.runTraceEngine(traceEvents);
70
- if (!result) {
71
- throw new Error('null trace engine result');
72
- }
73
78
  return result;
74
79
  }
75
80
  }
@@ -137,7 +137,6 @@ const defaultConfig = {
137
137
  {id: 'Scripts', gatherer: 'scripts'},
138
138
  {id: 'SourceMaps', gatherer: 'source-maps'},
139
139
  {id: 'Stacks', gatherer: 'stacks'},
140
- {id: 'TagsBlockingFirstPaint', gatherer: 'dobetterweb/tags-blocking-first-paint'},
141
140
  {id: 'TraceElements', gatherer: 'trace-elements'},
142
141
  {id: 'ViewportDimensions', gatherer: 'viewport-dimensions'},
143
142
 
@@ -13,7 +13,6 @@ const baseArtifactKeySource = {
13
13
  fetchTime: '',
14
14
  LighthouseRunWarnings: '',
15
15
  BenchmarkIndex: '',
16
- BenchmarkIndexes: '',
17
16
  settings: '',
18
17
  Timing: '',
19
18
  URL: '',
@@ -3,10 +3,10 @@ declare class RootCauses extends BaseGatherer {
3
3
  static symbol: symbol;
4
4
  /**
5
5
  * @param {LH.Gatherer.Driver} driver
6
- * @param {LH.Artifacts.TraceEngineResult} traceEngineResult
6
+ * @param {LH.Artifacts.TraceEngineResult['data']} traceParsedData
7
7
  * @return {Promise<LH.Artifacts.TraceEngineRootCauses>}
8
8
  */
9
- static runRootCauseAnalysis(driver: LH.Gatherer.Driver, traceEngineResult: LH.Artifacts.TraceEngineResult): Promise<LH.Artifacts.TraceEngineRootCauses>;
9
+ static runRootCauseAnalysis(driver: LH.Gatherer.Driver, traceParsedData: LH.Artifacts.TraceEngineResult['data']): Promise<LH.Artifacts.TraceEngineRootCauses>;
10
10
  /** @type {LH.Gatherer.GathererMeta<'Trace'>} */
11
11
  meta: LH.Gatherer.GathererMeta<'Trace'>;
12
12
  /**
@@ -21,10 +21,10 @@ class RootCauses extends BaseGatherer {
21
21
 
22
22
  /**
23
23
  * @param {LH.Gatherer.Driver} driver
24
- * @param {LH.Artifacts.TraceEngineResult} traceEngineResult
24
+ * @param {LH.Artifacts.TraceEngineResult['data']} traceParsedData
25
25
  * @return {Promise<LH.Artifacts.TraceEngineRootCauses>}
26
26
  */
27
- static async runRootCauseAnalysis(driver, traceEngineResult) {
27
+ static async runRootCauseAnalysis(driver, traceParsedData) {
28
28
  await driver.defaultSession.sendCommand('DOM.enable');
29
29
  await driver.defaultSession.sendCommand('CSS.enable');
30
30
 
@@ -112,9 +112,10 @@ class RootCauses extends BaseGatherer {
112
112
  layoutShifts: {},
113
113
  };
114
114
  const rootCausesEngine = new TraceEngine.RootCauses(protocolInterface);
115
- const layoutShiftEvents = traceEngineResult.LayoutShifts.clusters.flatMap(c => c.events);
115
+ const layoutShiftEvents = traceParsedData.LayoutShifts.clusters.flatMap(c => c.events);
116
116
  for (const event of layoutShiftEvents) {
117
- const r = await rootCausesEngine.layoutShifts.rootCausesForEvent(traceEngineResult, event);
117
+ // @ts-expect-error The data we do get in the trace processor is still enough here
118
+ const r = await rootCausesEngine.layoutShifts.rootCausesForEvent(traceParsedData, event);
118
119
  if (!r) continue;
119
120
 
120
121
  for (const cause of r.fontChanges) {
@@ -137,7 +138,7 @@ class RootCauses extends BaseGatherer {
137
138
  async getArtifact(context) {
138
139
  const trace = context.dependencies.Trace;
139
140
  const traceEngineResult = await TraceEngineResult.request({trace}, context);
140
- return RootCauses.runRootCauseAnalysis(context.driver, traceEngineResult);
141
+ return RootCauses.runRootCauseAnalysis(context.driver, traceEngineResult.data);
141
142
  }
142
143
  }
143
144
 
@@ -25,12 +25,12 @@ declare class TraceElements extends BaseGatherer {
25
25
  * that may have caused the shift.
26
26
  *
27
27
  * @param {LH.Trace} trace
28
- * @param {LH.Artifacts.TraceEngineResult} traceEngineResult
28
+ * @param {LH.Artifacts.TraceEngineResult['data']} traceEngineResult
29
29
  * @param {LH.Artifacts.TraceEngineRootCauses} rootCauses
30
30
  * @param {LH.Gatherer.Context} context
31
31
  * @return {Promise<Array<{nodeId: number}>>}
32
32
  */
33
- static getTopLayoutShifts(trace: LH.Trace, traceEngineResult: LH.Artifacts.TraceEngineResult, rootCauses: LH.Artifacts.TraceEngineRootCauses, context: LH.Gatherer.Context): Promise<Array<{
33
+ static getTopLayoutShifts(trace: LH.Trace, traceEngineResult: LH.Artifacts.TraceEngineResult['data'], rootCauses: LH.Artifacts.TraceEngineRootCauses, context: LH.Gatherer.Context): Promise<Array<{
34
34
  nodeId: number;
35
35
  }>>;
36
36
  /**
@@ -122,7 +122,7 @@ class TraceElements extends BaseGatherer {
122
122
  * that may have caused the shift.
123
123
  *
124
124
  * @param {LH.Trace} trace
125
- * @param {LH.Artifacts.TraceEngineResult} traceEngineResult
125
+ * @param {LH.Artifacts.TraceEngineResult['data']} traceEngineResult
126
126
  * @param {LH.Artifacts.TraceEngineRootCauses} rootCauses
127
127
  * @param {LH.Gatherer.Context} context
128
128
  * @return {Promise<Array<{nodeId: number}>>}
@@ -322,7 +322,7 @@ class TraceElements extends BaseGatherer {
322
322
 
323
323
  const lcpNodeData = await TraceElements.getLcpElement(trace, context);
324
324
  const shiftsData = await TraceElements.getTopLayoutShifts(
325
- trace, traceEngineResult, rootCauses, context);
325
+ trace, traceEngineResult.data, rootCauses, context);
326
326
  const animatedElementData = await this.getAnimatedElements(mainThreadEvents);
327
327
  const responsivenessElementData = await TraceElements.getResponsivenessElement(trace, context);
328
328
 
@@ -6,11 +6,17 @@ export class CPUNode<T = any> extends BaseNode<T> {
6
6
  /**
7
7
  * @param {LH.TraceEvent} parentEvent
8
8
  * @param {LH.TraceEvent[]=} childEvents
9
+ * @param {number=} correctedEndTs
9
10
  */
10
- constructor(parentEvent: LH.TraceEvent, childEvents?: LH.TraceEvent[] | undefined);
11
+ constructor(parentEvent: LH.TraceEvent, childEvents?: LH.TraceEvent[] | undefined, correctedEndTs?: number | undefined);
11
12
  _event: LH.TraceEvent;
12
13
  _childEvents: LH.TraceEvent[];
14
+ _correctedEndTs: number | undefined;
13
15
  get type(): "cpu";
16
+ /**
17
+ * @return {number}
18
+ */
19
+ get duration(): number;
14
20
  /**
15
21
  * @return {LH.TraceEvent}
16
22
  */
@@ -15,13 +15,15 @@ class CPUNode extends BaseNode {
15
15
  /**
16
16
  * @param {LH.TraceEvent} parentEvent
17
17
  * @param {LH.TraceEvent[]=} childEvents
18
+ * @param {number=} correctedEndTs
18
19
  */
19
- constructor(parentEvent, childEvents = []) {
20
+ constructor(parentEvent, childEvents = [], correctedEndTs) {
20
21
  const nodeId = `${parentEvent.tid}.${parentEvent.ts}`;
21
22
  super(nodeId);
22
23
 
23
24
  this._event = parentEvent;
24
25
  this._childEvents = childEvents;
26
+ this._correctedEndTs = correctedEndTs;
25
27
  }
26
28
 
27
29
  get type() {
@@ -39,9 +41,17 @@ class CPUNode extends BaseNode {
39
41
  * @return {number}
40
42
  */
41
43
  get endTime() {
44
+ if (this._correctedEndTs) return this._correctedEndTs;
42
45
  return this._event.ts + this._event.dur;
43
46
  }
44
47
 
48
+ /**
49
+ * @return {number}
50
+ */
51
+ get duration() {
52
+ return this.endTime - this.startTime;
53
+ }
54
+
45
55
  /**
46
56
  * @return {LH.TraceEvent}
47
57
  */
@@ -83,7 +93,7 @@ class CPUNode extends BaseNode {
83
93
  * @return {CPUNode}
84
94
  */
85
95
  cloneWithoutRelationships() {
86
- return new CPUNode(this._event, this._childEvents);
96
+ return new CPUNode(this._event, this._childEvents, this._correctedEndTs);
87
97
  }
88
98
  }
89
99
 
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export class LanternError extends Error {
7
+ }
8
+ //# sourceMappingURL=lantern-error.d.ts.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ class LanternError extends Error {}
8
+
9
+ export {LanternError};