lighthouse 11.7.0-dev.20240409 → 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 (134) hide show
  1. package/cli/cli-flags.js +3 -3
  2. package/cli/test/smokehouse/core-tests.js +0 -16
  3. package/cli/test/smokehouse/frontends/smokehouse-bin.js +2 -2
  4. package/core/audits/byte-efficiency/render-blocking-resources.js +25 -26
  5. package/core/audits/layout-shifts.js +1 -1
  6. package/core/computed/metrics/lantern-first-contentful-paint.js +3 -2
  7. package/core/computed/metrics/lantern-first-meaningful-paint.js +3 -2
  8. package/core/computed/metrics/lantern-interactive.js +3 -2
  9. package/core/computed/metrics/lantern-largest-contentful-paint.js +3 -2
  10. package/core/computed/metrics/lantern-max-potential-fid.js +3 -2
  11. package/core/computed/metrics/lantern-metric.d.ts +5 -0
  12. package/core/computed/metrics/lantern-metric.js +23 -1
  13. package/core/computed/metrics/lantern-speed-index.js +3 -2
  14. package/core/computed/navigation-insights.d.ts +36 -0
  15. package/core/computed/navigation-insights.js +35 -0
  16. package/core/computed/trace-engine-result.d.ts +16 -3
  17. package/core/computed/trace-engine-result.js +19 -14
  18. package/core/config/default-config.js +6 -51
  19. package/core/config/filters.js +0 -1
  20. package/core/gather/gatherers/root-causes.d.ts +2 -2
  21. package/core/gather/gatherers/root-causes.js +6 -5
  22. package/core/gather/gatherers/trace-elements.d.ts +2 -2
  23. package/core/gather/gatherers/trace-elements.js +2 -2
  24. package/core/lib/lantern/cpu-node.d.ts +7 -1
  25. package/core/lib/lantern/cpu-node.js +12 -2
  26. package/core/lib/lantern/lantern-error.d.ts +8 -0
  27. package/core/lib/lantern/lantern-error.js +9 -0
  28. package/core/lib/lantern/metrics/first-meaningful-paint.js +2 -4
  29. package/core/lib/lantern/metrics/interactive.js +1 -1
  30. package/core/lib/lantern/metrics/largest-contentful-paint.js +3 -3
  31. package/core/lib/lantern/network-node.js +28 -4
  32. package/core/lib/lantern/page-dependency-graph.js +14 -2
  33. package/core/lib/lantern/simulator/simulator.js +1 -1
  34. package/core/lib/lh-error.js +3 -3
  35. package/core/runner.js +0 -1
  36. package/dist/report/bundle.esm.js +11 -95
  37. package/dist/report/flow.js +16 -100
  38. package/dist/report/standalone.js +12 -96
  39. package/flow-report/src/help-dialog.tsx +0 -1
  40. package/flow-report/src/i18n/i18n.d.ts +0 -4
  41. package/flow-report/src/i18n/ui-strings.d.ts +0 -1
  42. package/flow-report/src/i18n/ui-strings.js +0 -2
  43. package/package.json +1 -1
  44. package/readme.md +2 -2
  45. package/report/assets/styles.css +1 -43
  46. package/report/assets/templates.html +0 -95
  47. package/report/renderer/components.d.ts +2 -2
  48. package/report/renderer/components.js +2 -103
  49. package/report/renderer/report-renderer.js +2 -12
  50. package/report/renderer/report-ui-features.js +1 -1
  51. package/report/renderer/report-utils.d.ts +0 -1
  52. package/report/renderer/report-utils.js +0 -3
  53. package/shared/localization/locales/ar-XB.json +0 -174
  54. package/shared/localization/locales/ar.json +0 -174
  55. package/shared/localization/locales/bg.json +0 -174
  56. package/shared/localization/locales/ca.json +0 -174
  57. package/shared/localization/locales/cs.json +0 -174
  58. package/shared/localization/locales/da.json +0 -174
  59. package/shared/localization/locales/de.json +0 -174
  60. package/shared/localization/locales/el.json +0 -174
  61. package/shared/localization/locales/en-GB.json +0 -174
  62. package/shared/localization/locales/en-US.json +0 -177
  63. package/shared/localization/locales/en-XA.json +0 -174
  64. package/shared/localization/locales/en-XL.json +0 -177
  65. package/shared/localization/locales/es-419.json +0 -174
  66. package/shared/localization/locales/es.json +0 -174
  67. package/shared/localization/locales/fi.json +0 -174
  68. package/shared/localization/locales/fil.json +0 -174
  69. package/shared/localization/locales/fr.json +0 -174
  70. package/shared/localization/locales/he.json +0 -174
  71. package/shared/localization/locales/hi.json +0 -174
  72. package/shared/localization/locales/hr.json +0 -174
  73. package/shared/localization/locales/hu.json +0 -174
  74. package/shared/localization/locales/id.json +0 -174
  75. package/shared/localization/locales/it.json +0 -174
  76. package/shared/localization/locales/ja.json +0 -174
  77. package/shared/localization/locales/ko.json +0 -174
  78. package/shared/localization/locales/lt.json +0 -174
  79. package/shared/localization/locales/lv.json +0 -174
  80. package/shared/localization/locales/nl.json +0 -174
  81. package/shared/localization/locales/no.json +0 -174
  82. package/shared/localization/locales/pl.json +0 -174
  83. package/shared/localization/locales/pt-PT.json +0 -174
  84. package/shared/localization/locales/pt.json +0 -174
  85. package/shared/localization/locales/ro.json +0 -174
  86. package/shared/localization/locales/ru.json +0 -174
  87. package/shared/localization/locales/sk.json +0 -174
  88. package/shared/localization/locales/sl.json +0 -174
  89. package/shared/localization/locales/sr-Latn.json +0 -174
  90. package/shared/localization/locales/sr.json +0 -174
  91. package/shared/localization/locales/sv.json +0 -174
  92. package/shared/localization/locales/ta.json +0 -174
  93. package/shared/localization/locales/te.json +0 -174
  94. package/shared/localization/locales/th.json +0 -174
  95. package/shared/localization/locales/tr.json +0 -174
  96. package/shared/localization/locales/uk.json +0 -174
  97. package/shared/localization/locales/vi.json +0 -174
  98. package/shared/localization/locales/zh-HK.json +0 -174
  99. package/shared/localization/locales/zh-TW.json +0 -174
  100. package/shared/localization/locales/zh.json +0 -174
  101. package/tsconfig.json +0 -1
  102. package/types/artifacts.d.ts +15 -90
  103. package/types/audit.d.ts +0 -10
  104. package/types/internal/smokehouse.d.ts +1 -1
  105. package/types/lhr/lhr.d.ts +0 -2
  106. package/core/audits/content-width.d.ts +0 -17
  107. package/core/audits/content-width.js +0 -76
  108. package/core/audits/installable-manifest.d.ts +0 -111
  109. package/core/audits/installable-manifest.js +0 -248
  110. package/core/audits/manual/pwa-cross-browser.d.ts +0 -12
  111. package/core/audits/manual/pwa-cross-browser.js +0 -40
  112. package/core/audits/manual/pwa-each-page-has-url.d.ts +0 -12
  113. package/core/audits/manual/pwa-each-page-has-url.js +0 -38
  114. package/core/audits/manual/pwa-page-transitions.d.ts +0 -12
  115. package/core/audits/manual/pwa-page-transitions.js +0 -38
  116. package/core/audits/maskable-icon.d.ts +0 -25
  117. package/core/audits/maskable-icon.js +0 -70
  118. package/core/audits/multi-check-audit.d.ts +0 -28
  119. package/core/audits/multi-check-audit.js +0 -82
  120. package/core/audits/splash-screen.d.ts +0 -37
  121. package/core/audits/splash-screen.js +0 -98
  122. package/core/audits/themed-omnibox.d.ts +0 -42
  123. package/core/audits/themed-omnibox.js +0 -102
  124. package/core/computed/manifest-values.d.ts +0 -24
  125. package/core/computed/manifest-values.js +0 -136
  126. package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.d.ts +0 -47
  127. package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.js +0 -233
  128. package/core/gather/gatherers/installability-errors.d.ts +0 -17
  129. package/core/gather/gatherers/installability-errors.js +0 -56
  130. package/core/gather/gatherers/web-app-manifest.d.ts +0 -32
  131. package/core/gather/gatherers/web-app-manifest.js +0 -106
  132. package/report/renderer/pwa-category-renderer.d.ts +0 -55
  133. package/report/renderer/pwa-category-renderer.js +0 -184
  134. package/third-party/chromium-synchronization/installability-errors-test.js +0 -79
package/cli/cli-flags.js CHANGED
@@ -53,8 +53,8 @@ function getYargsParser(manualArgv) {
53
53
  'lighthouse <url> --extra-headers=./path/to/file.json',
54
54
  'Path to JSON file of HTTP Header key/value pairs to send in requests')
55
55
  .example(
56
- 'lighthouse <url> --only-categories=performance,pwa',
57
- 'Only run the specified categories. Available categories: accessibility, best-practices, performance, pwa, seo')
56
+ 'lighthouse <url> --only-categories=performance,seo',
57
+ 'Only run the specified categories. Available categories: accessibility, best-practices, performance, seo')
58
58
 
59
59
  // We only have the single string positional argument, the url.
60
60
  .option('_', {
@@ -188,7 +188,7 @@ function getYargsParser(manualArgv) {
188
188
  array: true,
189
189
  type: 'string',
190
190
  coerce: splitCommaSeparatedValues,
191
- describe: 'Only run the specified categories. Available categories: accessibility, best-practices, performance, pwa, seo',
191
+ describe: 'Only run the specified categories. Available categories: accessibility, best-practices, performance, seo',
192
192
  },
193
193
  'skip-audits': {
194
194
  array: true,
@@ -32,9 +32,6 @@ import metricsDelayedFcp from './test-definitions/metrics-delayed-fcp.js';
32
32
  import metricsDelayedLcp from './test-definitions/metrics-delayed-lcp.js';
33
33
  import metricsTrickyTti from './test-definitions/metrics-tricky-tti.js';
34
34
  import metricsTrickyTtiLateFcp from './test-definitions/metrics-tricky-tti-late-fcp.js';
35
- import offlineOnlineOnly from './test-definitions/offline-online-only.js';
36
- import offlineReady from './test-definitions/offline-ready.js';
37
- import offlineSwBroken from './test-definitions/offline-sw-broken.js';
38
35
  import oopifRequests from './test-definitions/oopif-requests.js';
39
36
  import oopifScripts from './test-definitions/oopif-scripts.js';
40
37
  import perfBudgets from './test-definitions/perf-budgets.js';
@@ -46,11 +43,6 @@ import perfFonts from './test-definitions/perf-fonts.js';
46
43
  import perfFrameMetrics from './test-definitions/perf-frame-metrics.js';
47
44
  import perfPreload from './test-definitions/perf-preload.js';
48
45
  import perfTraceElements from './test-definitions/perf-trace-elements.js';
49
- import pwaAirhorner from './test-definitions/pwa-airhorner.js';
50
- import pwaCaltrain from './test-definitions/pwa-caltrain.js';
51
- import pwaChromestatus from './test-definitions/pwa-chromestatus.js';
52
- import pwaRocks from './test-definitions/pwa-rocks.js';
53
- import pwaSvgomg from './test-definitions/pwa-svgomg.js';
54
46
  import redirectsClientPaintServer from './test-definitions/redirects-client-paint-server.js';
55
47
  import redirectsHistoryPushState from './test-definitions/redirects-history-push-state.js';
56
48
  import redirectsHttp from './test-definitions/redirects-http.js';
@@ -98,9 +90,6 @@ const smokeTests = [
98
90
  metricsDelayedLcp,
99
91
  metricsTrickyTti,
100
92
  metricsTrickyTtiLateFcp,
101
- offlineOnlineOnly,
102
- offlineReady,
103
- offlineSwBroken,
104
93
  oopifRequests,
105
94
  oopifScripts,
106
95
  perfBudgets,
@@ -112,11 +101,6 @@ const smokeTests = [
112
101
  perfFrameMetrics,
113
102
  perfPreload,
114
103
  perfTraceElements,
115
- pwaAirhorner,
116
- pwaCaltrain,
117
- pwaChromestatus,
118
- pwaRocks,
119
- pwaSvgomg,
120
104
  redirectsClientPaintServer,
121
105
  redirectsHistoryPushState,
122
106
  redirectsHttp,
@@ -59,7 +59,7 @@ function getDefinitionsToRun(allTestDefns, requestedIds, excludedTests) {
59
59
  } else {
60
60
  smokes = allTestDefns.filter(test => {
61
61
  // Include all tests that *include* requested id.
62
- // e.g. a requested 'pwa' will match 'pwa-airhorner', 'pwa-caltrain', etc
62
+ // e.g. a requested 'perf' will match 'perf-preload', 'perf-trace-elements', etc
63
63
  return requestedIds.some(requestedId => test.id.includes(requestedId));
64
64
  });
65
65
  console.log(`Running ONLY smoketests for: ${smokes.map(t => t.id).join(' ')}\n`);
@@ -125,7 +125,7 @@ async function begin() {
125
125
  const rawArgv = y
126
126
  .help('help')
127
127
  .usage('node $0 [<options>] <test-ids>')
128
- .example('node $0 -j=1 pwa seo', 'run pwa and seo tests serially')
128
+ .example('node $0 -j=1 perf seo', 'run perf and seo tests serially')
129
129
  .option('_', {
130
130
  array: true,
131
131
  type: 'string',
@@ -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
  }