lighthouse 13.5.0-dev.20261016 → 13.5.0-dev.20261020

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 (102) hide show
  1. package/.agents/skills/update-trace-engine/SKILL.md +154 -0
  2. package/cli/test/smokehouse/__snapshots__/report-assert-test.js.snap +1 -1
  3. package/commitlint.config.js +1 -1
  4. package/core/audits/baseline.js +1 -1
  5. package/core/audits/insights/insight-audit.js +3 -2
  6. package/core/audits/script-treemap-data.js +12 -2
  7. package/core/computed/metrics/time-to-first-byte.js +5 -3
  8. package/core/computed/navigation-insights.js +3 -2
  9. package/core/computed/trace-engine-result.js +22 -4
  10. package/core/config/config-helpers.js +2 -3
  11. package/core/config/config.js +1 -2
  12. package/core/gather/base-artifacts.js +6 -0
  13. package/core/gather/gatherers/full-page-screenshot.js +2 -2
  14. package/core/gather/gatherers/inspector-issues.js +2 -0
  15. package/core/gather/gatherers/js-usage.js +2 -0
  16. package/core/gather/gatherers/scripts.d.ts +16 -3
  17. package/core/gather/gatherers/scripts.js +157 -14
  18. package/core/gather/gatherers/stylesheets.js +2 -0
  19. package/core/gather/gatherers/trace-elements.js +2 -1
  20. package/core/lib/cdt/Common.d.ts +1 -1
  21. package/core/lib/cdt/Common.js +2 -2
  22. package/core/lib/cdt/Platform.d.ts +7 -7
  23. package/core/lib/cdt/Platform.js +11 -8
  24. package/core/lib/cdt/SDK.d.ts +5 -1
  25. package/core/lib/cdt/SDK.js +4 -2
  26. package/core/lib/cdt/generated/ParsedURL.d.ts +0 -1
  27. package/core/lib/cdt/generated/ParsedURL.js +3 -9
  28. package/core/lib/cdt/generated/SourceMap.d.ts +24 -25
  29. package/core/lib/cdt/generated/SourceMap.js +7 -15
  30. package/core/lib/i18n/i18n.d.ts +0 -1
  31. package/core/lib/i18n/i18n.js +17 -11
  32. package/core/lib/legacy-javascript/legacy-javascript.d.ts +2 -2
  33. package/core/lib/legacy-javascript/legacy-javascript.js +1 -1
  34. package/core/lib/sentry.d.ts +1 -0
  35. package/core/lib/sentry.js +3 -0
  36. package/core/runner.js +2 -2
  37. package/dist/report/flow.js +4 -4
  38. package/package.json +16 -41
  39. package/report/generator/flow-report-assets.js +1 -3
  40. package/report/generator/report-assets.js +1 -2
  41. package/shared/esm-utils.d.ts +0 -8
  42. package/shared/esm-utils.js +0 -18
  43. package/shared/localization/format.js +1 -2
  44. package/shared/localization/locales/ar-XB.json +0 -6
  45. package/shared/localization/locales/ar.json +0 -6
  46. package/shared/localization/locales/bg.json +0 -6
  47. package/shared/localization/locales/ca.json +0 -6
  48. package/shared/localization/locales/cs.json +0 -6
  49. package/shared/localization/locales/da.json +0 -6
  50. package/shared/localization/locales/de.json +0 -6
  51. package/shared/localization/locales/el.json +0 -6
  52. package/shared/localization/locales/en-GB.json +0 -6
  53. package/shared/localization/locales/en-US.json +4 -7
  54. package/shared/localization/locales/en-XL.json +4 -7
  55. package/shared/localization/locales/es-419.json +22 -28
  56. package/shared/localization/locales/es.json +0 -6
  57. package/shared/localization/locales/fi.json +0 -6
  58. package/shared/localization/locales/fil.json +0 -6
  59. package/shared/localization/locales/fr.json +0 -6
  60. package/shared/localization/locales/he.json +127 -133
  61. package/shared/localization/locales/hi.json +0 -6
  62. package/shared/localization/locales/hr.json +0 -6
  63. package/shared/localization/locales/hu.json +0 -6
  64. package/shared/localization/locales/id.json +0 -6
  65. package/shared/localization/locales/it.json +0 -6
  66. package/shared/localization/locales/ja.json +115 -121
  67. package/shared/localization/locales/ko.json +2 -8
  68. package/shared/localization/locales/lt.json +0 -6
  69. package/shared/localization/locales/lv.json +0 -6
  70. package/shared/localization/locales/nl.json +0 -6
  71. package/shared/localization/locales/no.json +0 -6
  72. package/shared/localization/locales/pl.json +0 -6
  73. package/shared/localization/locales/pt-PT.json +0 -6
  74. package/shared/localization/locales/pt.json +0 -6
  75. package/shared/localization/locales/ro.json +3 -9
  76. package/shared/localization/locales/ru.json +3 -9
  77. package/shared/localization/locales/sk.json +0 -6
  78. package/shared/localization/locales/sl.json +0 -6
  79. package/shared/localization/locales/sr-Latn.json +0 -6
  80. package/shared/localization/locales/sr.json +0 -6
  81. package/shared/localization/locales/sv.json +0 -6
  82. package/shared/localization/locales/ta.json +0 -6
  83. package/shared/localization/locales/te.json +0 -6
  84. package/shared/localization/locales/th.json +0 -6
  85. package/shared/localization/locales/tr.json +0 -6
  86. package/shared/localization/locales/uk.json +0 -6
  87. package/shared/localization/locales/vi.json +0 -6
  88. package/shared/localization/locales/zh-HK.json +18 -24
  89. package/shared/localization/locales/zh-TW.json +60 -66
  90. package/shared/localization/locales/zh.json +2 -8
  91. package/shared/root.js +1 -3
  92. package/tsconfig.json +0 -2
  93. package/types/artifacts.d.ts +8 -1
  94. package/types/internal/test.d.ts +1 -0
  95. package/core/lib/cdt/package.json +0 -4
  96. package/eslint-local-rules.d.cts +0 -9
  97. package/eslint.config.mjs +0 -242
  98. package/third-party/esbuild-plugins-polyfills/LICENSE +0 -3
  99. package/third-party/esbuild-plugins-polyfills/README.md +0 -7
  100. package/third-party/esbuild-plugins-polyfills/esbuild-polyfills.d.ts +0 -9
  101. package/third-party/esbuild-plugins-polyfills/esbuild-polyfills.js +0 -129
  102. package/types/internal/lookup-closest-locale.d.ts +0 -13
@@ -0,0 +1,154 @@
1
+ ---
2
+ name: update-trace-engine
3
+ description: Build, validate, publish, and roll @paulirish/trace_engine from devtools-frontend into Lighthouse. Invoke when asked to update or roll the trace_engine package.
4
+ ---
5
+
6
+ # Update `@paulirish/trace_engine`
7
+
8
+ Lighthouse consumes Chrome DevTools' trace processor (`front_end/models/trace`) via the standalone `@paulirish/trace_engine` npm package, built from the `trace-engine-lib` branch of `paulirish/devtools-frontend`.
9
+
10
+ ## What lives where
11
+
12
+ | Location | Purpose | Notes |
13
+ |---|---|---|
14
+ | `devtools-frontend` checkout (branch `trace-engine-lib`) | Source & packaging scripts | Tracks `origin/main` (`https://chromium.googlesource.com/devtools/devtools-frontend`) + packaging scripts in `scripts/trace/`. Common local path: `~/devtools/devtools-frontend` (ask user if not found). |
15
+ | `scripts/trace/prep-trace-engine-package.sh` (in `devtools-frontend`) | Builds `out/TraceEngine` and prepares standalone package | Converts `export const enum` → `export enum` in `front_end/models/trace/**/*.ts`, builds with `gn` + `autoninja`, applies shims from `scripts/trace/replacements/`, extracts insight locale strings, and invokes `copy-build-trace-engine-for-publish.sh`. |
16
+ | `scripts/trace/copy-build-trace-engine-for-publish.sh` (in `devtools-frontend`) | Copies dist to `$HOME/code/trace_engine` and tests | Copies `out/TraceEngine/dist` to `$HOME/code/trace_engine`, runs `npm install` and `npm test` (Mocha tests in `test/test-trace-engine.mjs` + `tsc --build ./tsconfig.json`). |
17
+ | `$HOME/code/trace_engine` | Standalone npm package staging directory | Where `npm version` and `npm publish` are run. |
18
+ | `core/lib/trace-engine.js` (in Lighthouse) | Lighthouse entry point for `@paulirish/trace_engine` | Re-exports `TraceProcessor`, `TraceHandlers`, `Insights`, `Helpers`, and `Types`. |
19
+
20
+ ## Procedure
21
+
22
+ ### 1. Merge `origin/main` into `trace-engine-lib` in `devtools-frontend`
23
+
24
+ 1. Find the previous `devtools-frontend` `main` commit SHA from the most recent `deps: upgrade trace_engine` commit or PR in Lighthouse (or via `git log -n 1 --merges --pretty=format:"%P"` on `trace-engine-lib`).
25
+ 2. In the `devtools-frontend` checkout:
26
+ ```sh
27
+ git checkout trace-engine-lib
28
+ git fetch origin main
29
+ git merge origin/main --no-edit
30
+ ```
31
+ 3. Record the commit range `<old_sha>...<new_sha>` and inspect upstream changes:
32
+ ```sh
33
+ git log --oneline <old_sha>..<new_sha> -- front_end/models/trace front_end/models/cpu_profile
34
+ ```
35
+ 4. If there are merge conflicts in `front_end/models/trace/**/*.ts` due to `export const enum` vs `export enum`, resolve in favor of `origin/main` — `prep-trace-engine-package.sh` automatically converts `export const enum` to `export enum`.
36
+
37
+ ### 2. Build and test the standalone package
38
+
39
+ Ensure `depot_tools` (`gn`, `autoninja`) and Node/npm are on `PATH`, then run:
40
+
41
+ ```sh
42
+ scripts/trace/prep-trace-engine-package.sh
43
+ ```
44
+
45
+ This builds `out/TraceEngine`, populates `$HOME/code/trace_engine`, and runs `npm test` (`mocha` + `tsc --build ./tsconfig.json`).
46
+
47
+ #### Fixing build or test failures in `trace-engine-lib`
48
+
49
+ - **TypeScript (`tsc --build ./tsconfig.json`) errors in `$HOME/code/trace_engine`**:
50
+ - `prep-trace-engine-package.sh` replaces several DevTools modules using `scripts/trace/replacements/` so Lighthouse can bundle `trace_engine` into an IIFE (`esbuild`) and defer localization (`LH.IcuMessage`):
51
+ - `HostRuntime.js`: synchronous stub replacing top-level `await` in `core/platform/HostRuntime.js`.
52
+ - `UIString.d.ts` & `i18n.{js,d.ts}`: types `LocalizedString` as a deferred `{i18nId, values}` object instead of a branded `string`. If a file in `core/platform/` (such as `UserVisibleError.d.ts`) fails type-checking because it expects `LocalizedString` to be assignable to `string` and isn't needed by `models/trace`, stub its `.d.ts` in `prep-trace-engine-package.sh` (`echo 'export {};' > "$dist/core/platform/<File>.d.ts"`).
53
+ - `common.{js,d.ts}`, `sdk.d.ts`, `crux-manager.d.ts`: minimal stubs for `core/common`, `core/sdk`, and `models/crux-manager`. Update these if `models/trace` references new symbols from those modules.
54
+ - **Mocha (`test/test-trace-engine.mjs`) failures**:
55
+ - If an assertion in `scripts/trace/test/test-trace-engine.mjs` fails due to an intentional upstream calculation change in `front_end/models/trace`, update `scripts/trace/test/test-trace-engine.mjs` and re-run `scripts/trace/copy-build-trace-engine-for-publish.sh`.
56
+ - Commit any updated files on `trace-engine-lib` and push to Paul's fork (`git push paulirish trace-engine-lib`) when requested.
57
+
58
+ ### 3. Bump the package version
59
+
60
+ Determine the next patch version (`0.0.X` → `0.0.(X+1)`) from `package.json` in Lighthouse or `npm view @paulirish/trace_engine version --registry https://registry.npmjs.org/`:
61
+
62
+ ```sh
63
+ cd $HOME/code/trace_engine
64
+ npm version v0.0.XXX --no-git-tag-version
65
+ ```
66
+
67
+ ### 4. Validate locally in Lighthouse before publishing
68
+
69
+ Copy the built package into Lighthouse's `node_modules/@paulirish/trace_engine` to validate before publishing to npm:
70
+
71
+ ```sh
72
+ rm -rf node_modules/@paulirish/trace_engine/{models,core,generated,third_party,locales,test}
73
+ cp -rp $HOME/code/trace_engine/{models,core,generated,third_party,locales,package.json,tsconfig.json} node_modules/@paulirish/trace_engine/
74
+ ```
75
+
76
+ Run the Lighthouse validation checks:
77
+
78
+ 1. **Type-checking**:
79
+ ```sh
80
+ yarn type-check
81
+ ```
82
+ Fix any Lighthouse code or JSDoc types broken by upstream `TraceEngine` API/type changes (commonly in `core/audits/insights/`, `core/computed/`, `core/gather/gatherers/trace-elements.js`, or `core/lib/trace-engine.js`).
83
+
84
+ 2. **Bundles**:
85
+ ```sh
86
+ yarn build-devtools && yarn build-lr && yarn build-devtools-mcp
87
+ ```
88
+ Confirms `esbuild` can bundle `trace_engine` into IIFE (`dt-bundle.js`, Lightrider) and ESM without top-level `await` or missing module errors.
89
+
90
+ 3. **Unit tests**:
91
+ ```sh
92
+ yarn mocha core/test/audits/insights/*-test.js core/test/audits/metrics-test.js core/test/audits/predictive-perf-test.js core/test/audits/byte-efficiency/byte-efficiency-audit-test.js core/test/computed/metrics/*-test.js core/test/computed/trace-engine-result-test.js core/test/computed/navigation-insights-test.js core/test/computed/entity-classification-test.js core/test/computed/tbt-impact-tasks-test.js
93
+ INTERNAL_LANTERN_USE_TRACE=1 yarn mocha core/test/computed/metrics/*-test.js core/test/audits/metrics-test.js core/test/audits/predictive-perf-test.js
94
+ ```
95
+ Update test expectations and snapshots (`yarn mocha --update <test-file>`) where upstream changes intentionally affect metrics, insights, or Lantern trace simulations.
96
+
97
+ 4. **Sample JSON, locale strings, flow fixtures, and Lantern baselines**:
98
+ ```sh
99
+ yarn update:sample-json
100
+ bash core/scripts/assert-baseline-flow-result-unchanged.sh
101
+ yarn test-lantern
102
+ ```
103
+ - If `assert-baseline-flow-result-unchanged.sh` fails due to expected changes, update flow fixtures with `yarn update:flow-fixtures`.
104
+ - If `yarn test-lantern` reports expected metric changes on the Lantern dataset (or if `models/trace/lantern` changed upstream), update the Lantern baseline files (`core/test/fixtures/lantern-baseline-computed-values.json` and `core/test/fixtures/lantern-baseline-accuracy.json`):
105
+ ```sh
106
+ FORCE=1 ./core/scripts/lantern/update-baseline-lantern-values.js
107
+ ./core/scripts/lantern/assert-baseline-lantern-values-unchanged.js
108
+ ```
109
+ - Review `git diff core/test/results/sample_v2.json` and `git diff shared/localization/locales/en-US.json` to make sure every change is accounted for by an upstream commit.
110
+
111
+ 5. **Linter**:
112
+ ```sh
113
+ yarn lint --fix
114
+ ```
115
+
116
+ ### 5. Pause for npm publish
117
+
118
+ Once local validation passes, pause and ask the user to publish `$HOME/code/trace_engine` to npm (requires interactive npm authentication):
119
+
120
+ ```sh
121
+ cd $HOME/code/trace_engine
122
+ npm publish --access public --registry https://registry.npmjs.org/
123
+ ```
124
+
125
+ ### 6. Roll `package.json`, `yarn.lock`, and open the PR
126
+
127
+ After the user confirms `@paulirish/trace_engine@0.0.XXX` is published on npm:
128
+
129
+ 1. Update `"@paulirish/trace_engine": "0.0.XXX"` in `package.json` and run `yarn` to update `yarn.lock`.
130
+ 2. Commit all changes (`deps: upgrade trace_engine to 0.0.XXX`).
131
+ 3. Run `yarn diff:sample-json` after committing (note: `assert-strings-collected.sh` runs `git diff --exit-code shared/localization/locales/`, so uncommitted locale changes will cause it to fail).
132
+ 4. Push the branch and open a PR against `GoogleChrome/lighthouse` with title `deps: upgrade trace_engine to 0.0.XXX` and description formatted like [PR #17307](https://github.com/GoogleChrome/lighthouse/pull/17307) (including the collapsible `<details><summary>` block with the full `git log <old_sha>...<new_sha> -- front_end/models/trace` output):
133
+
134
+ ````markdown
135
+ Roll `@paulirish/trace_engine` from `0.0.OLD` to `0.0.NEW` (`<old_sha>...<new_sha>`).
136
+
137
+ https://chromium.googlesource.com/devtools/devtools-frontend.git/+log/<old_sha>..<new_sha>
138
+
139
+ ### Highlights for Lighthouse
140
+
141
+ - **<Category>**:
142
+ - **<Highlight>** ([CL <cl_number>](https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/<cl_number>)): <summary of upstream change and impact on Lighthouse>
143
+
144
+ `git log <old_sha>...<new_sha> -- front_end/models/trace`:
145
+
146
+ <details>
147
+ <summary>Changelog (just front_end/models/trace, mostly relevant to our usage in LH)</summary>
148
+
149
+ ```
150
+ <full output of: git log <old_sha>...<new_sha> -- front_end/models/trace>
151
+ ```
152
+
153
+ </details>
154
+ ````
@@ -1,4 +1,4 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
1
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
2
 
3
3
  exports[`getAssertionReport works (multiple failing) 1`] = `
4
4
  "X difference at cumulative-layout-shift audit.details.items.length
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
- module.exports = {
7
+ export default {
8
8
  extends: ['cz'],
9
9
  rules: {
10
10
  'body-leading-blank': [1, 'always'],
@@ -18,7 +18,7 @@ const UIStrings = {
18
18
  */
19
19
  description:
20
20
  'Lists web features used on the page and their Baseline status as of {date}. ' +
21
- '[Learn more about Baseline](https://webstatus.dev/).',
21
+ '[Learn more about Baseline](https://developer.chrome.com/docs/lighthouse/best-practices/baseline-features).',
22
22
  /** Label for the column displaying the feature ID. */
23
23
  columnFeature: 'Web-features',
24
24
  /** Label for the column displaying the feature\'s baseline status. */
@@ -6,6 +6,7 @@
6
6
 
7
7
  import {NO_NAVIGATION} from '@paulirish/trace_engine/models/trace/types/TraceEvents.js';
8
8
 
9
+ import {Helpers} from '../../lib/trace-engine.js';
9
10
  import {ProcessedTrace} from '../../computed/processed-trace.js';
10
11
  import {TraceEngineResult} from '../../computed/trace-engine-result.js';
11
12
  import {Audit} from '../audit.js';
@@ -28,8 +29,8 @@ async function getInsightSet(artifacts, context) {
28
29
 
29
30
  const navigationId = processedTrace.timeOriginEvt.args.data?.navigationId;
30
31
  const insights = navigationId ?
31
- [...traceEngineResult.insights.values()]
32
- .find(insightSet => insightSet.navigation?.args.data?.navigationId === navigationId) :
32
+ [...traceEngineResult.insights.values()].find(insightSet =>
33
+ Helpers.Trace.navigationIDForEvent(insightSet.navigation) === navigationId) :
33
34
  traceEngineResult.insights.get(NO_NAVIGATION);
34
35
 
35
36
  return {insights, data: traceEngineResult.data};
@@ -176,12 +176,23 @@ class ScriptTreemapDataAudit extends Audit {
176
176
  const nodes = [];
177
177
  /** @type {Map<string, LH.Treemap.Node>} */
178
178
  const htmlNodesByFrameId = new Map();
179
+ /** @type {Set<LH.Artifacts.NetworkRequest>} */
180
+ const seenNetworkRecords = new Set();
179
181
  const bundles = await JSBundles.request(artifacts, context);
180
182
  const duplicationByPath = await ModuleDuplication.request(artifacts, context);
181
183
 
182
184
  for (const script of artifacts.Scripts) {
183
185
  if (script.scriptLanguage !== 'JavaScript') continue;
184
186
 
187
+ const isInlineScript = isInline(script);
188
+ const networkRecord = isInlineScript ?
189
+ undefined :
190
+ getRequestForScript(networkRecords, script);
191
+ if (networkRecord) {
192
+ if (seenNetworkRecords.has(networkRecord)) continue;
193
+ seenNetworkRecords.add(networkRecord);
194
+ }
195
+
185
196
  const name = script.url;
186
197
  const bundle = bundles.find(bundle => script.scriptId === bundle.script.scriptId) ?? null;
187
198
  const scriptCoverage = /** @type {LH.Artifacts['JsUsage'][string] | undefined} */
@@ -246,7 +257,7 @@ class ScriptTreemapDataAudit extends Audit {
246
257
 
247
258
  // If this is an inline script, place the node inside a top-level (aka depth-one) node.
248
259
  // Also separate each iframe / the main page's inline scripts into their own top-level nodes.
249
- if (isInline(script)) {
260
+ if (isInlineScript) {
250
261
  let htmlNode = htmlNodesByFrameId.get(script.executionContextAuxData.frameId);
251
262
  if (!htmlNode) {
252
263
  htmlNode = {
@@ -269,7 +280,6 @@ class ScriptTreemapDataAudit extends Audit {
269
280
  // Non-inline scripts each have their own top-level node.
270
281
  nodes.push(node);
271
282
 
272
- const networkRecord = getRequestForScript(networkRecords, script);
273
283
  if (networkRecord) {
274
284
  const bodyTransferSize =
275
285
  networkRecord.transferSize - networkRecord.responseHeadersTransferSize;
@@ -6,6 +6,7 @@
6
6
 
7
7
  import {calculateDocFirstByteTs} from '@paulirish/trace_engine/models/trace/insights/Common.js';
8
8
 
9
+ import {Helpers} from '../../lib/trace-engine.js';
9
10
  import {makeComputedArtifact} from '../computed-artifact.js';
10
11
  import {NavigationMetric} from './navigation-metric.js';
11
12
  import {MainResource} from '../main-resource.js';
@@ -52,15 +53,16 @@ class TimeToFirstByte extends NavigationMetric {
52
53
  await NavigationInsights.request({trace, settings, SourceMaps, HostDPR}, context);
53
54
  const lcpBreakdown = navInsights.model.LCPBreakdown;
54
55
 
56
+ const navigationId = Helpers.Trace.navigationIDForEvent(navInsights.navigation);
57
+
55
58
  // Defer to LCP breakdown, but if there's no LCP fallback to manual calculation.
56
59
  if (lcpBreakdown && !(lcpBreakdown instanceof Error) && lcpBreakdown.subparts) {
57
60
  return {
58
61
  timing: lcpBreakdown.subparts.ttfb.range / 1000,
59
62
  timestamp: lcpBreakdown.subparts.ttfb.max,
60
63
  };
61
- } else if (navInsights.navigation?.args.data?.navigationId) {
62
- const request = traceEngineResult.data.NetworkRequests.byId.get(
63
- navInsights.navigation.args.data.navigationId);
64
+ } else if (navInsights.navigation && navigationId) {
65
+ const request = traceEngineResult.data.NetworkRequests.byId.get(navigationId);
64
66
  if (!request) {
65
67
  throw new Error();
66
68
  }
@@ -4,6 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
+ import {Helpers} from '../lib/trace-engine.js';
7
8
  import {makeComputedArtifact} from './computed-artifact.js';
8
9
  import {ProcessedTrace} from './processed-trace.js';
9
10
  import {TraceEngineResult} from './trace-engine-result.js';
@@ -26,8 +27,8 @@ class NavigationInsights {
26
27
  const navigationId = processedTrace.timeOriginEvt.args.data?.navigationId;
27
28
  if (!navigationId) throw new Error('No navigationId found');
28
29
 
29
- const navInsights = [...traceEngineResult.insights.values()]
30
- .find(insightSet => insightSet.navigation?.args.data?.navigationId === navigationId);
30
+ const navInsights = [...traceEngineResult.insights.values()].find(insightSet =>
31
+ Helpers.Trace.navigationIDForEvent(insightSet.navigation) === navigationId);
31
32
  if (!navInsights) throw new Error('No navigations insights found');
32
33
 
33
34
  return navInsights;
@@ -7,6 +7,7 @@
7
7
  import log from 'lighthouse-logger';
8
8
 
9
9
  import * as i18n from '../lib/i18n/i18n.js';
10
+ import * as Lantern from '../lib/lantern/lantern.js';
10
11
  import * as TraceEngine from '../lib/trace-engine.js';
11
12
  import {makeComputedArtifact} from './computed-artifact.js';
12
13
  import {CumulativeLayoutShift} from './metrics/cumulative-layout-shift.js';
@@ -68,8 +69,20 @@ class TraceEngineResult {
68
69
  });
69
70
  if (!processor.data) throw new Error('No data');
70
71
  if (!processor.insights) throw new Error('No insights');
71
- this.localizeInsights(processor.insights);
72
- return {data: processor.data, insights: processor.insights};
72
+ const data = processor.data;
73
+ const insights = processor.insights;
74
+ this.localizeInsights(insights);
75
+
76
+ // Release intermediate handler state retained in module-level TraceHandlers singletons
77
+ // and static Lantern simulation node timings after trace processing completes.
78
+ for (const handler of Object.values(TraceEngine.TraceHandlers)) {
79
+ handler.reset();
80
+ }
81
+ if (!process.env.LANTERN_DEBUG) {
82
+ Lantern.Simulation.Simulator.allNodeTimings.clear();
83
+ }
84
+
85
+ return {data, insights};
73
86
  }
74
87
 
75
88
  /**
@@ -238,8 +251,9 @@ class TraceEngineResult {
238
251
  const layoutShiftEvents = new Set(
239
252
  CumulativeLayoutShift.getLayoutShiftEvents(processedTrace).map(e => e.event));
240
253
 
241
- // Avoid modifying the input array.
242
- const traceEvents = [...data.trace.traceEvents];
254
+ // Avoid modifying the input array, copying only if an event is modified.
255
+ let traceEvents = data.trace.traceEvents;
256
+ let copied = false;
243
257
  for (let i = 0; i < traceEvents.length; i++) {
244
258
  let event = traceEvents[i];
245
259
  if (event.name !== 'LayoutShift') continue;
@@ -247,6 +261,10 @@ class TraceEngineResult {
247
261
 
248
262
  const isConsidered = layoutShiftEvents.has(event);
249
263
  if (event.args.data.had_recent_input && isConsidered) {
264
+ if (!copied) {
265
+ traceEvents = [...traceEvents];
266
+ copied = true;
267
+ }
250
268
  event = JSON.parse(JSON.stringify(event));
251
269
  // @ts-expect-error impossible for data to be missing.
252
270
  event.args.data.had_recent_input = false;
@@ -13,7 +13,6 @@ import ConfigPlugin from './config-plugin.js';
13
13
  import {Runner} from '../runner.js';
14
14
  import * as i18n from '../lib/i18n/i18n.js';
15
15
  import * as validation from './validation.js';
16
- import {getModuleDirectory} from '../../shared/esm-utils.js';
17
16
  import {isEqual} from '../lib/arbitrary-equality-map.js';
18
17
 
19
18
  const require = createRequire(import.meta.url);
@@ -292,7 +291,7 @@ function requireAudit(auditPath, coreAuditList, configDir) {
292
291
  const absolutePath = resolveModulePath(auditPath, configDir, 'audit');
293
292
  if (isBundledEnvironment()) {
294
293
  // Use a relative path so bundler can easily expose it.
295
- requirePath = path.relative(getModuleDirectory(import.meta), absolutePath);
294
+ requirePath = path.relative(import.meta.dirname, absolutePath);
296
295
  } else {
297
296
  requirePath = absolutePath;
298
297
  }
@@ -512,7 +511,7 @@ function resolveModulePath(moduleIdentifier, configDir, category) {
512
511
  const errorString = 'Unable to locate ' + (category ? `${category}: ` : '') +
513
512
  `\`${moduleIdentifier}\`.
514
513
  Tried to resolve the module from these locations:
515
- ${getModuleDirectory(import.meta)}
514
+ ${import.meta.dirname}
516
515
  ${cwdPath}`;
517
516
 
518
517
  if (!configDir) {
@@ -28,11 +28,10 @@ import {
28
28
  mergeConfigFragment,
29
29
  mergeConfigFragmentArrayByKey,
30
30
  } from './config-helpers.js';
31
- import {getModuleDirectory} from '../../shared/esm-utils.js';
32
31
  import * as format from '../../shared/localization/format.js';
33
32
 
34
33
  const defaultConfigPath = path.join(
35
- getModuleDirectory(import.meta),
34
+ import.meta.dirname,
36
35
  '../../config/default-config.js'
37
36
  );
38
37
 
@@ -11,6 +11,7 @@ import {
11
11
  getDevicePixelRatio,
12
12
  } from './driver/environment.js';
13
13
  import {isEqual} from '../lib/arbitrary-equality-map.js';
14
+ import {Sentry} from '../lib/sentry.js';
14
15
 
15
16
  /**
16
17
  * @param {LH.Config.ResolvedConfig} resolvedConfig
@@ -23,6 +24,11 @@ async function getBaseArtifacts(resolvedConfig, driver, context) {
23
24
  const {userAgent, product} = await getBrowserVersion(driver.defaultSession);
24
25
  const HostDPR = await getDevicePixelRatio(driver.executionContext);
25
26
 
27
+ const [name, version] = product.split('/');
28
+ if (name && version) {
29
+ Sentry.setContext('browser', {name, version});
30
+ }
31
+
26
32
  return {
27
33
  // Meta artifacts.
28
34
  fetchTime: new Date().toJSON(),
@@ -95,7 +95,7 @@ class FullPageScreenshot extends BaseGatherer {
95
95
  mobile: deviceMetrics.mobile,
96
96
  deviceScaleFactor: 1,
97
97
  height,
98
- width: 0, // Leave width unchanged
98
+ width: deviceMetrics.width,
99
99
  });
100
100
 
101
101
  // Now that the viewport is taller, give the page some time to fetch new resources that
@@ -235,7 +235,7 @@ class FullPageScreenshot extends BaseGatherer {
235
235
  mobile: deviceMetrics.mobile,
236
236
  deviceScaleFactor: deviceMetrics.deviceScaleFactor,
237
237
  height: deviceMetrics.height,
238
- width: 0, // Leave width unchanged
238
+ width: deviceMetrics.width,
239
239
  });
240
240
  }
241
241
  }
@@ -96,6 +96,8 @@ class InspectorIssues extends BaseGatherer {
96
96
  }
97
97
  }
98
98
 
99
+ this._issues = [];
100
+
99
101
  return artifact;
100
102
  }
101
103
  }
@@ -67,6 +67,8 @@ class JsUsage extends BaseGatherer {
67
67
  usageByScriptId[scriptUsage.scriptId] = scriptUsage;
68
68
  }
69
69
 
70
+ this._scriptUsages = [];
71
+
70
72
  return usageByScriptId;
71
73
  }
72
74
  }
@@ -1,13 +1,22 @@
1
1
  export default Scripts;
2
+ export type TraceScript = {
3
+ scriptId: string;
4
+ sourceText?: string | undefined;
5
+ chunks?: string[] | undefined;
6
+ url?: string | undefined;
7
+ sourceUrl?: string | undefined;
8
+ executionContextId?: number | undefined;
9
+ frame?: string | undefined;
10
+ };
2
11
  /**
3
12
  * @fileoverview Gets JavaScript file contents.
4
13
  */
5
14
  declare class Scripts extends BaseGatherer {
6
15
  static symbol: symbol;
16
+ /** @type {LH.Gatherer.GathererMeta<'Trace'>} */
17
+ meta: LH.Gatherer.GathererMeta<"Trace">;
7
18
  /** @type {LH.Crdp.Debugger.ScriptParsedEvent[]} */
8
19
  _scriptParsedEvents: LH.Crdp.Debugger.ScriptParsedEvent[];
9
- /** @type {Array<string | undefined>} */
10
- _scriptContents: Array<string | undefined>;
11
20
  /**
12
21
  * @param {LH.Crdp.Debugger.ScriptParsedEvent} params
13
22
  */
@@ -20,7 +29,11 @@ declare class Scripts extends BaseGatherer {
20
29
  * @param {LH.Gatherer.Context} context
21
30
  */
22
31
  stopInstrumentation(context: LH.Gatherer.Context): Promise<void>;
23
- getArtifact(): Promise<import("../../index.js").Artifacts.Script[]>;
32
+ /**
33
+ * @param {LH.Gatherer.Context<'Trace'>} context
34
+ * @return {Promise<LH.Artifacts['Scripts']>}
35
+ */
36
+ getArtifact(context: LH.Gatherer.Context<"Trace">): Promise<LH.Artifacts["Scripts"]>;
24
37
  }
25
38
  import BaseGatherer from '../base-gatherer.js';
26
39
  //# sourceMappingURL=scripts.d.ts.map