lighthouse 11.7.1 → 12.0.0
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.
- package/CONTRIBUTING.md +2 -2
- package/cli/bin.js +0 -7
- package/cli/cli-flags.d.ts +1 -5
- package/cli/cli-flags.js +4 -8
- package/cli/test/smokehouse/__snapshots__/report-assert-test.js.snap +14 -14
- package/cli/test/smokehouse/config/exclusions.js +3 -0
- package/cli/test/smokehouse/core-tests.js +6 -20
- package/cli/test/smokehouse/frontends/smokehouse-bin.js +2 -2
- package/core/audits/accessibility/aria-conditional-attr.d.ts +10 -0
- package/core/audits/accessibility/aria-conditional-attr.js +43 -0
- package/core/audits/accessibility/{duplicate-id-active.d.ts → aria-deprecated-role.d.ts} +3 -3
- package/core/audits/accessibility/aria-deprecated-role.js +43 -0
- package/core/audits/accessibility/aria-prohibited-attr.d.ts +10 -0
- package/core/audits/accessibility/aria-prohibited-attr.js +44 -0
- package/core/audits/accessibility/target-size.js +0 -1
- package/core/audits/byte-efficiency/byte-efficiency-audit.d.ts +0 -16
- package/core/audits/byte-efficiency/byte-efficiency-audit.js +1 -38
- package/core/audits/byte-efficiency/offscreen-images.d.ts +0 -11
- package/core/audits/byte-efficiency/offscreen-images.js +0 -15
- package/core/audits/byte-efficiency/render-blocking-resources.js +27 -26
- package/core/audits/byte-efficiency/unminified-css.js +2 -2
- package/core/audits/byte-efficiency/unused-css-rules.js +3 -1
- package/core/audits/dobetterweb/uses-http2.d.ts +0 -13
- package/core/audits/dobetterweb/uses-http2.js +4 -38
- package/core/audits/font-display.js +2 -2
- package/core/audits/layout-shifts.js +1 -1
- package/core/audits/preload-fonts.d.ts +1 -5
- package/core/audits/preload-fonts.js +1 -10
- package/core/audits/prioritize-lcp-image.js +2 -2
- package/core/audits/redirects-http.d.ts +19 -0
- package/core/audits/redirects-http.js +75 -0
- package/core/audits/resource-summary.d.ts +2 -0
- package/core/audits/resource-summary.js +5 -4
- package/core/audits/seo/is-crawlable.d.ts +2 -1
- package/core/audits/seo/link-text.js +12 -0
- package/core/audits/uses-rel-preload.d.ts +1 -5
- package/core/audits/uses-rel-preload.js +5 -15
- package/core/audits/work-during-interaction.d.ts +2 -2
- package/core/audits/work-during-interaction.js +2 -2
- package/core/computed/js-bundles.d.ts +1 -1
- package/core/computed/metrics/lantern-first-contentful-paint.d.ts +13 -82
- package/core/computed/metrics/lantern-first-contentful-paint.js +16 -178
- package/core/computed/metrics/lantern-first-meaningful-paint.d.ts +13 -12
- package/core/computed/metrics/lantern-first-meaningful-paint.js +11 -49
- package/core/computed/metrics/lantern-interactive.d.ts +13 -21
- package/core/computed/metrics/lantern-interactive.js +12 -84
- package/core/computed/metrics/lantern-largest-contentful-paint.d.ts +13 -25
- package/core/computed/metrics/lantern-largest-contentful-paint.js +13 -80
- package/core/computed/metrics/lantern-max-potential-fid.d.ts +13 -24
- package/core/computed/metrics/lantern-max-potential-fid.js +12 -64
- package/core/computed/metrics/lantern-metric.d.ts +14 -18
- package/core/computed/metrics/lantern-metric.js +34 -30
- package/core/computed/metrics/lantern-speed-index.d.ts +13 -32
- package/core/computed/metrics/lantern-speed-index.js +13 -116
- package/core/computed/metrics/lantern-total-blocking-time.d.ts +13 -25
- package/core/computed/metrics/lantern-total-blocking-time.js +10 -94
- package/core/computed/metrics/metric.js +1 -3
- package/core/computed/module-duplication.d.ts +1 -1
- package/core/computed/navigation-insights.d.ts +36 -0
- package/core/computed/navigation-insights.js +35 -0
- package/core/computed/page-dependency-graph.js +3 -7
- package/core/computed/resource-summary.d.ts +10 -12
- package/core/computed/resource-summary.js +12 -19
- package/core/computed/trace-engine-result.d.ts +16 -3
- package/core/computed/trace-engine-result.js +19 -14
- package/core/computed/unused-css.d.ts +3 -1
- package/core/computed/unused-css.js +6 -5
- package/core/config/config-helpers.js +0 -4
- package/core/config/constants.js +0 -1
- package/core/config/default-config.js +63 -142
- package/core/config/experimental-config.js +11 -0
- package/core/config/filters.js +0 -1
- package/core/gather/driver/navigation.js +4 -1
- package/core/gather/driver/prepare.js +1 -1
- package/core/gather/driver/target-manager.js +4 -3
- package/core/gather/driver/wait-for-condition.js +2 -3
- package/core/gather/driver.d.ts +12 -0
- package/core/gather/driver.js +27 -0
- package/core/gather/gatherers/accessibility.js +4 -6
- package/core/gather/gatherers/css-usage.d.ts +0 -21
- package/core/gather/gatherers/css-usage.js +9 -119
- package/core/gather/gatherers/root-causes.d.ts +2 -2
- package/core/gather/gatherers/root-causes.js +6 -5
- package/core/gather/gatherers/stylesheets.d.ts +26 -0
- package/core/gather/gatherers/stylesheets.js +138 -0
- package/core/gather/gatherers/trace-elements.d.ts +2 -12
- package/core/gather/gatherers/trace-elements.js +2 -21
- package/core/gather/navigation-runner.js +3 -1
- package/core/gather/session.d.ts +8 -0
- package/core/gather/session.js +14 -1
- package/core/lib/emulation.js +2 -2
- package/core/lib/i18n/i18n.d.ts +0 -1
- package/core/lib/i18n/i18n.js +0 -2
- package/core/lib/lantern/cpu-node.d.ts +7 -1
- package/core/lib/lantern/cpu-node.js +12 -2
- package/core/lib/lantern/lantern-error.d.ts +8 -0
- package/core/lib/lantern/lantern-error.js +9 -0
- package/core/lib/lantern/metric.js +2 -6
- package/core/lib/lantern/metrics/first-contentful-paint.d.ts +79 -0
- package/core/lib/lantern/metrics/first-contentful-paint.js +200 -0
- package/core/lib/lantern/metrics/first-meaningful-paint.d.ts +6 -0
- package/core/lib/lantern/metrics/first-meaningful-paint.js +64 -0
- package/core/lib/lantern/metrics/interactive.d.ts +26 -0
- package/core/lib/lantern/metrics/interactive.js +112 -0
- package/core/lib/lantern/metrics/largest-contentful-paint.d.ts +19 -0
- package/core/lib/lantern/metrics/largest-contentful-paint.js +108 -0
- package/core/lib/lantern/metrics/max-potential-fid.d.ts +30 -0
- package/core/lib/lantern/metrics/max-potential-fid.js +92 -0
- package/core/lib/lantern/metrics/speed-index.d.ts +38 -0
- package/core/lib/lantern/metrics/speed-index.js +144 -0
- package/core/lib/lantern/metrics/total-blocking-time.d.ts +31 -0
- package/core/lib/lantern/metrics/total-blocking-time.js +128 -0
- package/core/lib/lantern/network-node.js +28 -4
- package/core/lib/lantern/page-dependency-graph.d.ts +4 -4
- package/core/lib/lantern/page-dependency-graph.js +19 -7
- package/core/lib/lantern/simulator/connection-pool.d.ts +2 -12
- package/core/lib/lantern/simulator/connection-pool.js +3 -22
- package/core/lib/lantern/simulator/network-analyzer.js +1 -12
- package/core/lib/lantern/simulator/simulator.d.ts +2 -4
- package/core/lib/lantern/simulator/simulator.js +7 -14
- package/core/lib/lantern/types/lantern.d.ts +5 -3
- package/core/lib/lantern-trace-saver.js +0 -1
- package/core/lib/lh-error.d.ts +9 -0
- package/core/lib/lh-error.js +13 -3
- package/core/lib/lighthouse-compatibility.js +53 -10
- package/core/lib/navigation-error.js +3 -0
- package/core/lib/network-request.d.ts +1 -0
- package/core/lib/network-request.js +28 -0
- package/core/runner.js +18 -25
- package/dist/report/bundle.esm.js +11 -112
- package/dist/report/flow.js +16 -117
- package/dist/report/standalone.js +12 -113
- package/flow-report/src/help-dialog.tsx +0 -1
- package/flow-report/src/i18n/i18n.d.ts +0 -4
- package/flow-report/src/i18n/ui-strings.d.ts +0 -1
- package/flow-report/src/i18n/ui-strings.js +0 -2
- package/flow-report/src/summary/category.tsx +10 -12
- package/package.json +5 -5
- package/readme.md +4 -4
- package/report/assets/styles.css +1 -60
- package/report/assets/templates.html +0 -95
- package/report/renderer/category-renderer.js +1 -1
- package/report/renderer/components.d.ts +2 -2
- package/report/renderer/components.js +2 -103
- package/report/renderer/dom.d.ts +1 -1
- package/report/renderer/dom.js +1 -1
- package/report/renderer/performance-category-renderer.d.ts +0 -7
- package/report/renderer/performance-category-renderer.js +1 -32
- package/report/renderer/report-renderer.js +3 -13
- package/report/renderer/report-ui-features.js +1 -1
- package/report/renderer/report-utils.d.ts +0 -1
- package/report/renderer/report-utils.js +13 -13
- package/shared/localization/locales/ar-XB.json +62 -329
- package/shared/localization/locales/ar.json +62 -329
- package/shared/localization/locales/bg.json +62 -329
- package/shared/localization/locales/ca.json +62 -329
- package/shared/localization/locales/cs.json +62 -329
- package/shared/localization/locales/da.json +62 -329
- package/shared/localization/locales/de.json +62 -329
- package/shared/localization/locales/el.json +62 -329
- package/shared/localization/locales/en-GB.json +62 -329
- package/shared/localization/locales/en-US.json +41 -272
- package/shared/localization/locales/en-XA.json +62 -329
- package/shared/localization/locales/en-XL.json +41 -272
- package/shared/localization/locales/es-419.json +62 -329
- package/shared/localization/locales/es.json +62 -329
- package/shared/localization/locales/fi.json +62 -329
- package/shared/localization/locales/fil.json +61 -328
- package/shared/localization/locales/fr.json +62 -329
- package/shared/localization/locales/he.json +62 -329
- package/shared/localization/locales/hi.json +62 -329
- package/shared/localization/locales/hr.json +63 -330
- package/shared/localization/locales/hu.json +62 -329
- package/shared/localization/locales/id.json +62 -329
- package/shared/localization/locales/it.json +62 -329
- package/shared/localization/locales/ja.json +62 -329
- package/shared/localization/locales/ko.json +62 -329
- package/shared/localization/locales/lt.json +62 -329
- package/shared/localization/locales/lv.json +62 -329
- package/shared/localization/locales/nl.json +62 -329
- package/shared/localization/locales/no.json +62 -329
- package/shared/localization/locales/pl.json +61 -328
- package/shared/localization/locales/pt-PT.json +62 -329
- package/shared/localization/locales/pt.json +64 -331
- package/shared/localization/locales/ro.json +62 -329
- package/shared/localization/locales/ru.json +62 -329
- package/shared/localization/locales/sk.json +62 -329
- package/shared/localization/locales/sl.json +62 -329
- package/shared/localization/locales/sr-Latn.json +62 -329
- package/shared/localization/locales/sr.json +62 -329
- package/shared/localization/locales/sv.json +62 -329
- package/shared/localization/locales/ta.json +61 -328
- package/shared/localization/locales/te.json +62 -329
- package/shared/localization/locales/th.json +62 -329
- package/shared/localization/locales/tr.json +62 -329
- package/shared/localization/locales/uk.json +62 -329
- package/shared/localization/locales/vi.json +61 -328
- package/shared/localization/locales/zh-HK.json +62 -329
- package/shared/localization/locales/zh-TW.json +61 -328
- package/shared/localization/locales/zh.json +62 -329
- package/tsconfig.json +1 -3
- package/types/artifacts.d.ts +21 -110
- package/types/audit.d.ts +0 -10
- package/types/config.d.ts +0 -1
- package/types/externs.d.ts +0 -2
- package/types/gatherer.d.ts +3 -0
- package/types/internal/smokehouse.d.ts +1 -1
- package/types/lh.d.ts +0 -2
- package/types/lhr/audit-details.d.ts +9 -4
- package/types/lhr/lhr.d.ts +0 -4
- package/types/lhr/settings.d.ts +0 -4
- package/core/audits/accessibility/duplicate-id-active.js +0 -42
- package/core/audits/content-width.d.ts +0 -17
- package/core/audits/content-width.js +0 -76
- package/core/audits/installable-manifest.d.ts +0 -111
- package/core/audits/installable-manifest.js +0 -248
- package/core/audits/layout-shift-elements.d.ts +0 -16
- package/core/audits/layout-shift-elements.js +0 -101
- package/core/audits/manual/pwa-cross-browser.d.ts +0 -12
- package/core/audits/manual/pwa-cross-browser.js +0 -40
- package/core/audits/manual/pwa-each-page-has-url.d.ts +0 -12
- package/core/audits/manual/pwa-each-page-has-url.js +0 -38
- package/core/audits/manual/pwa-page-transitions.d.ts +0 -12
- package/core/audits/manual/pwa-page-transitions.js +0 -38
- package/core/audits/maskable-icon.d.ts +0 -25
- package/core/audits/maskable-icon.js +0 -70
- package/core/audits/multi-check-audit.d.ts +0 -28
- package/core/audits/multi-check-audit.js +0 -82
- package/core/audits/no-unload-listeners.d.ts +0 -16
- package/core/audits/no-unload-listeners.js +0 -86
- package/core/audits/performance-budget.d.ts +0 -39
- package/core/audits/performance-budget.js +0 -154
- package/core/audits/script-elements-test-audit.d.ts +0 -14
- package/core/audits/script-elements-test-audit.js +0 -29
- package/core/audits/seo/plugins.d.ts +0 -15
- package/core/audits/seo/plugins.js +0 -150
- package/core/audits/seo/tap-targets.d.ts +0 -50
- package/core/audits/seo/tap-targets.js +0 -352
- package/core/audits/splash-screen.d.ts +0 -37
- package/core/audits/splash-screen.js +0 -98
- package/core/audits/themed-omnibox.d.ts +0 -42
- package/core/audits/themed-omnibox.js +0 -102
- package/core/audits/timing-budget.d.ts +0 -43
- package/core/audits/timing-budget.js +0 -175
- package/core/computed/manifest-values.d.ts +0 -24
- package/core/computed/manifest-values.js +0 -136
- package/core/config/budget.d.ts +0 -74
- package/core/config/budget.js +0 -340
- package/core/config/metrics-to-audits.d.ts +0 -19
- package/core/config/metrics-to-audits.js +0 -62
- package/core/gather/driver/service-workers.d.ts +0 -16
- package/core/gather/driver/service-workers.js +0 -52
- package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.d.ts +0 -47
- package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.js +0 -233
- package/core/gather/gatherers/global-listeners.d.ts +0 -27
- package/core/gather/gatherers/global-listeners.js +0 -108
- package/core/gather/gatherers/installability-errors.d.ts +0 -17
- package/core/gather/gatherers/installability-errors.js +0 -56
- package/core/gather/gatherers/script-elements.d.ts +0 -21
- package/core/gather/gatherers/script-elements.js +0 -100
- package/core/gather/gatherers/seo/embedded-content.d.ts +0 -10
- package/core/gather/gatherers/seo/embedded-content.js +0 -63
- package/core/gather/gatherers/seo/tap-targets.d.ts +0 -21
- package/core/gather/gatherers/seo/tap-targets.js +0 -389
- package/core/gather/gatherers/service-worker.d.ts +0 -10
- package/core/gather/gatherers/service-worker.js +0 -32
- package/core/gather/gatherers/web-app-manifest.d.ts +0 -32
- package/core/gather/gatherers/web-app-manifest.js +0 -106
- package/report/renderer/pwa-category-renderer.d.ts +0 -55
- package/report/renderer/pwa-category-renderer.js +0 -184
- package/third-party/chromium-synchronization/installability-errors-test.js +0 -79
- package/types/lhr/budget.d.ts +0 -60
|
@@ -140,15 +140,6 @@ class NetworkAnalyzer {
|
|
|
140
140
|
const {timing, connectionReused, record} = info;
|
|
141
141
|
if (connectionReused) return;
|
|
142
142
|
|
|
143
|
-
// In LR, network records are missing connection timing, but we've smuggled it in via headers.
|
|
144
|
-
if (global.isLightrider && record.lrStatistics) {
|
|
145
|
-
if (record.protocol.startsWith('h3')) {
|
|
146
|
-
return record.lrStatistics.TCPMs;
|
|
147
|
-
} else {
|
|
148
|
-
return [record.lrStatistics.TCPMs / 2, record.lrStatistics.TCPMs / 2];
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
143
|
const {connectStart, sslStart, sslEnd, connectEnd} = timing;
|
|
153
144
|
if (connectEnd >= 0 && connectStart >= 0 && record.protocol.startsWith('h3')) {
|
|
154
145
|
// These values are equal to sslStart and sslEnd for h3.
|
|
@@ -256,9 +247,7 @@ class NetworkAnalyzer {
|
|
|
256
247
|
*/
|
|
257
248
|
static _estimateResponseTimeByOrigin(records, rttByOrigin) {
|
|
258
249
|
return NetworkAnalyzer._estimateValueByOrigin(records, ({record, timing}) => {
|
|
259
|
-
|
|
260
|
-
// close to the response time.
|
|
261
|
-
if (global.isLightrider && record.lrStatistics) return record.lrStatistics.requestMs;
|
|
250
|
+
if (record.serverResponseTime !== undefined) return record.serverResponseTime;
|
|
262
251
|
|
|
263
252
|
if (!Number.isFinite(timing.receiveHeadersEnd) || timing.receiveHeadersEnd < 0) return;
|
|
264
253
|
if (!Number.isFinite(timing.sendEnd) || timing.sendEnd < 0) return;
|
|
@@ -29,7 +29,6 @@ export class Simulator<T = any> {
|
|
|
29
29
|
_layoutTaskMultiplier: number;
|
|
30
30
|
/** @type {Array<Node>} */
|
|
31
31
|
_cachedNodeListByStartPosition: Array<Node>;
|
|
32
|
-
_flexibleOrdering: boolean;
|
|
33
32
|
_nodeTimings: SimulatorTimingMap;
|
|
34
33
|
/** @type {Map<string, number>} */
|
|
35
34
|
_numberInProgressByType: Map<string, number>;
|
|
@@ -131,17 +130,16 @@ export class Simulator<T = any> {
|
|
|
131
130
|
* Estimates the time taken to process all of the graph's nodes, returns the overall time along with
|
|
132
131
|
* each node annotated by start/end times.
|
|
133
132
|
*
|
|
134
|
-
*
|
|
133
|
+
* Simulator/connection pool are allowed to deviate from what was
|
|
135
134
|
* observed in the trace/devtoolsLog and start requests as soon as they are queued (i.e. do not
|
|
136
135
|
* wait around for a warm connection to be available if the original record was fetched on a warm
|
|
137
136
|
* connection).
|
|
138
137
|
*
|
|
139
138
|
* @param {Node} graph
|
|
140
|
-
* @param {{
|
|
139
|
+
* @param {{label?: string}=} options
|
|
141
140
|
* @return {Lantern.Simulation.Result<T>}
|
|
142
141
|
*/
|
|
143
142
|
simulate(graph: Node, options?: {
|
|
144
|
-
flexibleOrdering?: boolean;
|
|
145
143
|
label?: string;
|
|
146
144
|
} | undefined): Lantern.Simulation.Result<T>;
|
|
147
145
|
/**
|
|
@@ -80,7 +80,6 @@ class Simulator {
|
|
|
80
80
|
this._cachedNodeListByStartPosition = [];
|
|
81
81
|
|
|
82
82
|
// Properties reset on every `.simulate` call but duplicated here for type checking
|
|
83
|
-
this._flexibleOrdering = false;
|
|
84
83
|
this._nodeTimings = new SimulatorTimingMap();
|
|
85
84
|
/** @type {Map<string, number>} */
|
|
86
85
|
this._numberInProgressByType = new Map();
|
|
@@ -197,9 +196,7 @@ class Simulator {
|
|
|
197
196
|
* @return {?TcpConnection}
|
|
198
197
|
*/
|
|
199
198
|
_acquireConnection(record) {
|
|
200
|
-
return this._connectionPool.acquire(record
|
|
201
|
-
ignoreConnectionReused: this._flexibleOrdering,
|
|
202
|
-
});
|
|
199
|
+
return this._connectionPool.acquire(record);
|
|
203
200
|
}
|
|
204
201
|
|
|
205
202
|
/**
|
|
@@ -276,7 +273,7 @@ class Simulator {
|
|
|
276
273
|
? this._layoutTaskMultiplier
|
|
277
274
|
: this._cpuSlowdownMultiplier;
|
|
278
275
|
const totalDuration = Math.min(
|
|
279
|
-
Math.round(cpuNode.
|
|
276
|
+
Math.round(cpuNode.duration / 1000 * multiplier),
|
|
280
277
|
DEFAULT_MAXIMUM_CPU_TASK_DURATION
|
|
281
278
|
);
|
|
282
279
|
const estimatedTimeElapsed = totalDuration - timingData.timeElapsed;
|
|
@@ -425,13 +422,13 @@ class Simulator {
|
|
|
425
422
|
* Estimates the time taken to process all of the graph's nodes, returns the overall time along with
|
|
426
423
|
* each node annotated by start/end times.
|
|
427
424
|
*
|
|
428
|
-
*
|
|
425
|
+
* Simulator/connection pool are allowed to deviate from what was
|
|
429
426
|
* observed in the trace/devtoolsLog and start requests as soon as they are queued (i.e. do not
|
|
430
427
|
* wait around for a warm connection to be available if the original record was fetched on a warm
|
|
431
428
|
* connection).
|
|
432
429
|
*
|
|
433
430
|
* @param {Node} graph
|
|
434
|
-
* @param {{
|
|
431
|
+
* @param {{label?: string}=} options
|
|
435
432
|
* @return {Lantern.Simulation.Result<T>}
|
|
436
433
|
*/
|
|
437
434
|
simulate(graph, options) {
|
|
@@ -441,11 +438,9 @@ class Simulator {
|
|
|
441
438
|
|
|
442
439
|
options = Object.assign({
|
|
443
440
|
label: undefined,
|
|
444
|
-
flexibleOrdering: false,
|
|
445
441
|
}, options);
|
|
446
442
|
|
|
447
443
|
// initialize the necessary data containers
|
|
448
|
-
this._flexibleOrdering = !!options.flexibleOrdering;
|
|
449
444
|
this._dns = new DNSCache({rtt: this._rtt});
|
|
450
445
|
this._initializeConnectionPool(graph);
|
|
451
446
|
this._initializeAuxiliaryData();
|
|
@@ -470,11 +465,9 @@ class Simulator {
|
|
|
470
465
|
}
|
|
471
466
|
|
|
472
467
|
if (!nodesInProgress.size) {
|
|
473
|
-
//
|
|
474
|
-
//
|
|
475
|
-
|
|
476
|
-
this._flexibleOrdering = true;
|
|
477
|
-
continue;
|
|
468
|
+
// Interplay between fromDiskCache and connectionReused can be incorrect,
|
|
469
|
+
// have to give up.
|
|
470
|
+
throw new Error('Failed to start a node');
|
|
478
471
|
}
|
|
479
472
|
|
|
480
473
|
// set the available throughput for all connections based on # inflight
|
|
@@ -67,9 +67,6 @@ export class NetworkRequest<T = any> {
|
|
|
67
67
|
resourceSize: number;
|
|
68
68
|
fromDiskCache: boolean;
|
|
69
69
|
fromMemoryCache: boolean;
|
|
70
|
-
// TODO(15841): remove from lantern.
|
|
71
|
-
/** Extra timing information available only when run in Lightrider. */
|
|
72
|
-
lrStatistics: LightriderStatistics | undefined;
|
|
73
70
|
finished: boolean;
|
|
74
71
|
statusCode: number;
|
|
75
72
|
/** The network request that this one redirected to */
|
|
@@ -80,6 +77,11 @@ export class NetworkRequest<T = any> {
|
|
|
80
77
|
/** The chain of network requests that redirected to this one */
|
|
81
78
|
redirects: NetworkRequest[] | undefined;
|
|
82
79
|
timing: LH.Crdp.Network.ResourceTiming | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Optional value for how long the server took to respond to this request.
|
|
82
|
+
* When not provided, the server response time is derived from the timing object.
|
|
83
|
+
*/
|
|
84
|
+
serverResponseTime: number | undefined;
|
|
83
85
|
resourceType: LH.Crdp.Network.ResourceType | undefined;
|
|
84
86
|
mimeType: string;
|
|
85
87
|
priority: LH.Crdp.Network.ResourcePriority;
|
package/core/lib/lh-error.d.ts
CHANGED
|
@@ -105,6 +105,7 @@ export namespace UIStrings {
|
|
|
105
105
|
const missingRequiredArtifact: string;
|
|
106
106
|
const erroredRequiredArtifact: string;
|
|
107
107
|
const oldChromeDoesNotSupportFeature: string;
|
|
108
|
+
const targetCrashed: string;
|
|
108
109
|
}
|
|
109
110
|
declare namespace ERRORS {
|
|
110
111
|
namespace NO_SPEEDLINE_FRAMES {
|
|
@@ -340,6 +341,14 @@ declare namespace ERRORS {
|
|
|
340
341
|
import message_30 = UIStrings.erroredRequiredArtifact;
|
|
341
342
|
export { message_30 as message };
|
|
342
343
|
}
|
|
344
|
+
namespace TARGET_CRASHED {
|
|
345
|
+
const code_31: string;
|
|
346
|
+
export { code_31 as code };
|
|
347
|
+
import message_31 = UIStrings.targetCrashed;
|
|
348
|
+
export { message_31 as message };
|
|
349
|
+
const lhrRuntimeError_22: boolean;
|
|
350
|
+
export { lhrRuntimeError_22 as lhrRuntimeError };
|
|
351
|
+
}
|
|
343
352
|
}
|
|
344
353
|
export {};
|
|
345
354
|
//# sourceMappingURL=lh-error.d.ts.map
|
package/core/lib/lh-error.js
CHANGED
|
@@ -76,13 +76,13 @@ const UIStrings = {
|
|
|
76
76
|
criTimeout: 'Timeout waiting for initial Debugger Protocol connection.',
|
|
77
77
|
/**
|
|
78
78
|
* @description Error message explaining that a resource that was required for testing was never collected. "artifactName" will be replaced with the name of the resource that wasn't collected.
|
|
79
|
-
* @example {
|
|
79
|
+
* @example {MainDocumentContent} artifactName
|
|
80
80
|
* */
|
|
81
81
|
missingRequiredArtifact: 'Required {artifactName} gatherer did not run.',
|
|
82
82
|
/**
|
|
83
83
|
* @description Error message explaining that there was an error while trying to collect a resource that was required for testing. "artifactName" will be replaced with the name of the resource that wasn't collected; "errorMessage" will be replaced with a string description of the error that occurred.
|
|
84
|
-
* @example {
|
|
85
|
-
* @example {
|
|
84
|
+
* @example {MainDocumentContent} artifactName
|
|
85
|
+
* @example {Could not find main document} errorMessage
|
|
86
86
|
* */
|
|
87
87
|
erroredRequiredArtifact: 'Required {artifactName} gatherer encountered an error: {errorMessage}',
|
|
88
88
|
|
|
@@ -91,6 +91,9 @@ const UIStrings = {
|
|
|
91
91
|
* @example {Largest Contentful Paint} featureName
|
|
92
92
|
* */
|
|
93
93
|
oldChromeDoesNotSupportFeature: 'This version of Chrome is too old to support \'{featureName}\'. Use a newer version to see full results.',
|
|
94
|
+
|
|
95
|
+
/** Error message explaining that the browser tab that Lighthouse is inspecting has crashed. */
|
|
96
|
+
targetCrashed: 'Browser tab has unexpectedly crashed.',
|
|
94
97
|
};
|
|
95
98
|
|
|
96
99
|
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
@@ -423,6 +426,13 @@ const ERRORS = {
|
|
|
423
426
|
message: UIStrings.erroredRequiredArtifact,
|
|
424
427
|
},
|
|
425
428
|
|
|
429
|
+
/** The page has crashed and will no longer respond to 99% of CDP commmands. */
|
|
430
|
+
TARGET_CRASHED: {
|
|
431
|
+
code: 'TARGET_CRASHED',
|
|
432
|
+
message: UIStrings.targetCrashed,
|
|
433
|
+
lhrRuntimeError: true,
|
|
434
|
+
},
|
|
435
|
+
|
|
426
436
|
// Hey! When adding a new error type, update lighthouse-result.proto too.
|
|
427
437
|
// Only necessary for runtime errors, which come from artifacts or pageLoadErrors.
|
|
428
438
|
};
|
|
@@ -108,19 +108,62 @@ function upgradeLhrForCompatibility(lhr) {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
// This backcompat converts old LHRs
|
|
112
|
-
//
|
|
113
|
-
//
|
|
111
|
+
// This backcompat converts old LHRs to use the "hidden" and "diagnostics" groups.
|
|
112
|
+
// <9.0.0 LHRs used "no group" to identify audits that should be hidden in performance instead of the "hidden" group.
|
|
113
|
+
// <9.0.0 LHRs used "load-opportunities" for opportunity audits that are now grouped under "diagnostics".
|
|
114
|
+
// >=9.0.0 && <12.0.0 LHRs use "no group" to identify opportunities and diagnostics whose groups are assigned by details type.
|
|
115
|
+
// >=12.0.0 LHRs use the "hidden" group to identify hidden audits and "diagnostics" to identify diagnostics. "no group" is meaningless.
|
|
114
116
|
const [majorVersion] = lhr.lighthouseVersion.split('.').map(Number);
|
|
115
117
|
const perfCategory = lhr.categories['performance'];
|
|
116
|
-
if (
|
|
117
|
-
if (
|
|
118
|
-
|
|
118
|
+
if (perfCategory) {
|
|
119
|
+
if (majorVersion < 9) {
|
|
120
|
+
if (!lhr.categoryGroups) lhr.categoryGroups = {};
|
|
121
|
+
lhr.categoryGroups['hidden'] = {title: ''};
|
|
122
|
+
for (const auditRef of perfCategory.auditRefs) {
|
|
123
|
+
if (!auditRef.group) {
|
|
124
|
+
auditRef.group = 'hidden';
|
|
125
|
+
} else if (auditRef.group === 'load-opportunities') {
|
|
126
|
+
auditRef.group = 'diagnostics';
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
} else if (majorVersion < 12) {
|
|
130
|
+
for (const auditRef of perfCategory.auditRefs) {
|
|
131
|
+
if (!auditRef.group) {
|
|
132
|
+
auditRef.group = 'diagnostics';
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (majorVersion < 12 && perfCategory) {
|
|
139
|
+
/** @type {Map<string, string[]>} */
|
|
140
|
+
const metricRelevanceMap = new Map();
|
|
141
|
+
|
|
119
142
|
for (const auditRef of perfCategory.auditRefs) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
143
|
+
/** @type {string[]|undefined} */
|
|
144
|
+
// @ts-expect-error Removed in v12
|
|
145
|
+
const relevantAudits = auditRef.relevantAudits;
|
|
146
|
+
if (!relevantAudits || !auditRef.acronym) continue;
|
|
147
|
+
|
|
148
|
+
for (const auditId of relevantAudits) {
|
|
149
|
+
const acronyms = metricRelevanceMap.get(auditId) || [];
|
|
150
|
+
acronyms.push(auditRef.acronym);
|
|
151
|
+
metricRelevanceMap.set(auditId, acronyms);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
for (const [auditId, acronyms] of metricRelevanceMap) {
|
|
156
|
+
if (!acronyms.length) continue;
|
|
157
|
+
|
|
158
|
+
const audit = lhr.audits[auditId];
|
|
159
|
+
if (!audit) continue;
|
|
160
|
+
|
|
161
|
+
// Old versions can still define metric savings, let's not mess with it.
|
|
162
|
+
if (audit.metricSavings) continue;
|
|
163
|
+
|
|
164
|
+
audit.metricSavings = {};
|
|
165
|
+
for (const acronym of acronyms) {
|
|
166
|
+
audit.metricSavings[acronym] = 0;
|
|
124
167
|
}
|
|
125
168
|
}
|
|
126
169
|
}
|
|
@@ -150,6 +150,9 @@ function getPageLoadError(navigationError, context) {
|
|
|
150
150
|
let finalRecord;
|
|
151
151
|
if (mainRecord) {
|
|
152
152
|
finalRecord = NetworkAnalyzer.resolveRedirects(mainRecord);
|
|
153
|
+
} else {
|
|
154
|
+
// We have no network requests to process, use the navError
|
|
155
|
+
return navigationError;
|
|
153
156
|
}
|
|
154
157
|
|
|
155
158
|
if (finalRecord?.mimeType === XHTML_MIME_TYPE) {
|
|
@@ -247,6 +247,7 @@ export class NetworkRequest {
|
|
|
247
247
|
* is passed in via X-Headers similar to 'X-TotalFetchedSize'.
|
|
248
248
|
*/
|
|
249
249
|
_updateTimingsForLightrider(): void;
|
|
250
|
+
serverResponseTime: number | undefined;
|
|
250
251
|
}
|
|
251
252
|
export namespace NetworkRequest {
|
|
252
253
|
export { HEADER_TCP };
|
|
@@ -536,6 +536,7 @@ class NetworkRequest {
|
|
|
536
536
|
requestMs: requestMs,
|
|
537
537
|
responseMs: responseMs,
|
|
538
538
|
};
|
|
539
|
+
this.serverResponseTime = responseMs;
|
|
539
540
|
}
|
|
540
541
|
|
|
541
542
|
/**
|
|
@@ -574,8 +575,35 @@ class NetworkRequest {
|
|
|
574
575
|
* @return {Lantern.NetworkRequest<NetworkRequest>}
|
|
575
576
|
*/
|
|
576
577
|
static asLanternNetworkRequest(record) {
|
|
578
|
+
// In LR, network records are missing connection timing, but we've smuggled it in via headers.
|
|
579
|
+
let timing = record.timing;
|
|
580
|
+
let serverResponseTime;
|
|
581
|
+
if (global.isLightrider && record.lrStatistics) {
|
|
582
|
+
if (record.protocol.startsWith('h3')) {
|
|
583
|
+
// @ts-expect-error We don't need all the properties set.
|
|
584
|
+
timing = {
|
|
585
|
+
connectStart: 0,
|
|
586
|
+
connectEnd: record.lrStatistics.TCPMs,
|
|
587
|
+
};
|
|
588
|
+
} else {
|
|
589
|
+
// @ts-expect-error We don't need all the properties set.
|
|
590
|
+
timing = {
|
|
591
|
+
connectStart: 0,
|
|
592
|
+
sslStart: record.lrStatistics.TCPMs / 2,
|
|
593
|
+
connectEnd: record.lrStatistics.TCPMs,
|
|
594
|
+
sslEnd: record.lrStatistics.TCPMs,
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
// Lightrider does not have timings for sendEnd, but we do have this timing which should be
|
|
598
|
+
// close to the response time.
|
|
599
|
+
serverResponseTime = record.lrStatistics.requestMs;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
577
603
|
return {
|
|
578
604
|
...record,
|
|
605
|
+
timing,
|
|
606
|
+
serverResponseTime,
|
|
579
607
|
record,
|
|
580
608
|
};
|
|
581
609
|
}
|
package/core/runner.js
CHANGED
|
@@ -106,7 +106,6 @@ class Runner {
|
|
|
106
106
|
networkUserAgent: artifacts.NetworkUserAgent,
|
|
107
107
|
hostUserAgent: artifacts.HostUserAgent,
|
|
108
108
|
benchmarkIndex: artifacts.BenchmarkIndex,
|
|
109
|
-
benchmarkIndexes: artifacts.BenchmarkIndexes,
|
|
110
109
|
credits,
|
|
111
110
|
},
|
|
112
111
|
audits: auditResultsById,
|
|
@@ -199,32 +198,27 @@ class Runner {
|
|
|
199
198
|
data: sentryContext,
|
|
200
199
|
});
|
|
201
200
|
|
|
202
|
-
/** @type {LH.Artifacts} */
|
|
203
|
-
let artifacts;
|
|
204
201
|
if (settings.auditMode && !settings.gatherMode) {
|
|
205
202
|
// No browser required, just load the artifacts from disk.
|
|
206
203
|
const path = this._getDataSavePath(settings);
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const path = this._getDataSavePath(settings);
|
|
226
|
-
await assetSaver.saveArtifacts(artifacts, path);
|
|
227
|
-
}
|
|
204
|
+
return assetSaver.loadArtifacts(path);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const runnerStatus = {msg: 'Gather phase', id: 'lh:runner:gather'};
|
|
208
|
+
log.time(runnerStatus, 'verbose');
|
|
209
|
+
|
|
210
|
+
const artifacts = await gatherFn({resolvedConfig: options.resolvedConfig});
|
|
211
|
+
log.timeEnd(runnerStatus);
|
|
212
|
+
|
|
213
|
+
// If `gather` is run multiple times before `audit`, the timing entries for each `gather` can pollute one another.
|
|
214
|
+
// We need to clear the timing entries at the end of gathering.
|
|
215
|
+
// Set artifacts.Timing again to ensure lh:runner:gather is included.
|
|
216
|
+
artifacts.Timing = log.takeTimeEntries();
|
|
217
|
+
|
|
218
|
+
// -G means save these to disk (e.g. ./latest-run).
|
|
219
|
+
if (settings.gatherMode) {
|
|
220
|
+
const path = this._getDataSavePath(settings);
|
|
221
|
+
await assetSaver.saveArtifacts(artifacts, path);
|
|
228
222
|
}
|
|
229
223
|
|
|
230
224
|
return artifacts;
|
|
@@ -304,7 +298,6 @@ class Runner {
|
|
|
304
298
|
auditMode: undefined,
|
|
305
299
|
output: undefined,
|
|
306
300
|
channel: undefined,
|
|
307
|
-
budgets: undefined,
|
|
308
301
|
};
|
|
309
302
|
const normalizedGatherSettings = Object.assign({}, artifacts.settings, overrides);
|
|
310
303
|
const normalizedAuditSettings = Object.assign({}, settings, overrides);
|