lighthouse 11.1.0-dev.20231002 → 11.1.0-dev.20231004

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 (69) hide show
  1. package/cli/test/smokehouse/__snapshots__/report-assert-test.js.snap +8 -0
  2. package/core/audits/audit.js +21 -11
  3. package/core/audits/bf-cache.js +1 -0
  4. package/core/audits/bootup-time.js +4 -1
  5. package/core/audits/byte-efficiency/byte-efficiency-audit.js +1 -1
  6. package/core/audits/byte-efficiency/duplicated-javascript.js +1 -1
  7. package/core/audits/byte-efficiency/efficient-animated-content.js +1 -1
  8. package/core/audits/byte-efficiency/legacy-javascript.js +1 -1
  9. package/core/audits/byte-efficiency/modern-image-formats.js +1 -1
  10. package/core/audits/byte-efficiency/offscreen-images.js +1 -1
  11. package/core/audits/byte-efficiency/render-blocking-resources.js +2 -3
  12. package/core/audits/byte-efficiency/total-byte-weight.js +3 -1
  13. package/core/audits/byte-efficiency/unminified-css.js +1 -1
  14. package/core/audits/byte-efficiency/unminified-javascript.js +1 -1
  15. package/core/audits/byte-efficiency/unused-css-rules.js +1 -1
  16. package/core/audits/byte-efficiency/unused-javascript.js +1 -1
  17. package/core/audits/byte-efficiency/uses-long-cache-ttl.js +3 -8
  18. package/core/audits/byte-efficiency/uses-optimized-images.js +1 -1
  19. package/core/audits/byte-efficiency/uses-responsive-images-snapshot.js +1 -0
  20. package/core/audits/byte-efficiency/uses-responsive-images.js +1 -1
  21. package/core/audits/byte-efficiency/uses-text-compression.js +1 -1
  22. package/core/audits/csp-xss.js +1 -1
  23. package/core/audits/dobetterweb/dom-size.js +3 -1
  24. package/core/audits/dobetterweb/no-document-write.js +1 -0
  25. package/core/audits/dobetterweb/uses-http2.js +2 -3
  26. package/core/audits/dobetterweb/uses-passive-event-listeners.js +1 -0
  27. package/core/audits/font-display.js +1 -0
  28. package/core/audits/installable-manifest.js +2 -2
  29. package/core/audits/largest-contentful-paint-element.js +3 -2
  30. package/core/audits/layout-shift-elements.js +8 -4
  31. package/core/audits/lcp-lazy-loaded.js +1 -0
  32. package/core/audits/long-tasks.js +8 -1
  33. package/core/audits/mainthread-work-breakdown.js +3 -1
  34. package/core/audits/metrics/cumulative-layout-shift.js +4 -1
  35. package/core/audits/metrics/first-contentful-paint.js +1 -0
  36. package/core/audits/metrics/largest-contentful-paint.js +1 -0
  37. package/core/audits/metrics/speed-index.js +1 -0
  38. package/core/audits/metrics/total-blocking-time.js +1 -0
  39. package/core/audits/prioritize-lcp-image.js +2 -3
  40. package/core/audits/redirects.js +2 -3
  41. package/core/audits/server-response-time.js +2 -0
  42. package/core/audits/third-party-facades.js +1 -0
  43. package/core/audits/third-party-summary.js +5 -1
  44. package/core/audits/unsized-images.js +1 -1
  45. package/core/audits/uses-rel-preconnect.js +2 -3
  46. package/core/audits/uses-rel-preload.js +2 -3
  47. package/core/audits/viewport.js +1 -0
  48. package/core/audits/work-during-interaction.js +6 -2
  49. package/core/gather/session.js +2 -0
  50. package/core/lib/csp-evaluator.js +13 -13
  51. package/dist/report/bundle.esm.js +12 -89
  52. package/dist/report/flow.js +17 -94
  53. package/dist/report/standalone.js +13 -90
  54. package/package.json +4 -4
  55. package/report/assets/styles.css +1 -78
  56. package/report/assets/templates.html +0 -35
  57. package/report/renderer/components.d.ts +2 -2
  58. package/report/renderer/components.js +2 -51
  59. package/report/renderer/performance-category-renderer.d.ts +16 -18
  60. package/report/renderer/performance-category-renderer.js +90 -102
  61. package/shared/localization/locales/en-US.json +14 -14
  62. package/shared/localization/locales/en-XL.json +14 -14
  63. package/shared/util.d.ts +22 -0
  64. package/shared/util.js +31 -0
  65. package/types/audit.d.ts +5 -1
  66. package/types/internal/rxjs.d.ts +3 -0
  67. package/types/lhr/audit-result.d.ts +16 -0
  68. /package/{core/lib → shared}/statistics.d.ts +0 -0
  69. /package/{core/lib → shared}/statistics.js +0 -0
@@ -77,6 +77,7 @@ class SpeedIndex extends Audit {
77
77
  options.scoring,
78
78
  metricResult.timing
79
79
  ),
80
+ scoringOptions: options.scoring,
80
81
  numericValue: metricResult.timing,
81
82
  numericUnit: 'millisecond',
82
83
  displayValue: str_(i18n.UIStrings.seconds, {timeInMs: metricResult.timing}),
@@ -107,6 +107,7 @@ class TotalBlockingTime extends Audit {
107
107
  options.scoring,
108
108
  metricResult.timing
109
109
  ),
110
+ scoringOptions: options.scoring,
110
111
  numericValue: metricResult.timing,
111
112
  numericUnit: 'millisecond',
112
113
  displayValue: str_(i18n.UIStrings.ms, {timeInMs: metricResult.timing}),
@@ -10,7 +10,6 @@ import {NetworkRequest} from '../lib/network-request.js';
10
10
  import {MainResource} from '../computed/main-resource.js';
11
11
  import {LanternLargestContentfulPaint} from '../computed/metrics/lantern-largest-contentful-paint.js';
12
12
  import {LoadSimulator} from '../computed/load-simulator.js';
13
- import {ByteEfficiencyAudit} from './byte-efficiency/byte-efficiency-audit.js';
14
13
  import {LCPImageRecord} from '../computed/lcp-image-record.js';
15
14
 
16
15
  const UIStrings = {
@@ -40,7 +39,7 @@ class PrioritizeLcpImage extends Audit {
40
39
  supportedModes: ['navigation'],
41
40
  guidanceLevel: 3,
42
41
  requiredArtifacts: ['traces', 'devtoolsLogs', 'GatherContext', 'URL', 'TraceElements'],
43
- scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
42
+ scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
44
43
  };
45
44
  }
46
45
 
@@ -282,7 +281,7 @@ class PrioritizeLcpImage extends Audit {
282
281
  }
283
282
 
284
283
  return {
285
- score: ByteEfficiencyAudit.scoreForWastedMs(wastedMs),
284
+ score: results.length ? 0 : 1,
286
285
  numericValue: wastedMs,
287
286
  numericUnit: 'millisecond',
288
287
  displayValue: wastedMs ? str_(i18n.UIStrings.displayValueMsSavings, {wastedMs}) : '',
@@ -5,7 +5,6 @@
5
5
  */
6
6
 
7
7
  import {Audit} from './audit.js';
8
- import {ByteEfficiencyAudit} from './byte-efficiency/byte-efficiency-audit.js';
9
8
  import * as i18n from '../lib/i18n/i18n.js';
10
9
  import {ProcessedTrace} from '../computed/processed-trace.js';
11
10
  import {NetworkRecords} from '../computed/network-records.js';
@@ -29,7 +28,7 @@ class Redirects extends Audit {
29
28
  id: 'redirects',
30
29
  title: str_(UIStrings.title),
31
30
  description: str_(UIStrings.description),
32
- scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
31
+ scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
33
32
  supportedModes: ['navigation'],
34
33
  guidanceLevel: 2,
35
34
  requiredArtifacts: ['URL', 'GatherContext', 'devtoolsLogs', 'traces'],
@@ -145,7 +144,7 @@ class Redirects extends Audit {
145
144
  {overallSavingsMs: totalWastedMs});
146
145
 
147
146
  return {
148
- score: ByteEfficiencyAudit.scoreForWastedMs(totalWastedMs),
147
+ score: tableRows.length ? 0 : 1,
149
148
  numericValue: totalWastedMs,
150
149
  numericUnit: 'millisecond',
151
150
  displayValue: totalWastedMs ?
@@ -39,6 +39,7 @@ class ServerResponseTime extends Audit {
39
39
  supportedModes: ['navigation'],
40
40
  guidanceLevel: 1,
41
41
  requiredArtifacts: ['devtoolsLogs', 'URL', 'GatherContext'],
42
+ scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
42
43
  };
43
44
  }
44
45
 
@@ -91,6 +92,7 @@ class ServerResponseTime extends Audit {
91
92
  numericValue: responseTime,
92
93
  numericUnit: 'millisecond',
93
94
  score: Number(passed),
95
+ scoreDisplayMode: passed ? Audit.SCORING_MODES.INFORMATIVE : undefined,
94
96
  displayValue,
95
97
  details,
96
98
  metricSavings: {
@@ -88,6 +88,7 @@ class ThirdPartyFacades extends Audit {
88
88
  supportedModes: ['navigation'],
89
89
  guidanceLevel: 3,
90
90
  requiredArtifacts: ['traces', 'devtoolsLogs', 'URL', 'GatherContext'],
91
+ scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
91
92
  };
92
93
  }
93
94
 
@@ -75,6 +75,7 @@ class ThirdPartySummary extends Audit {
75
75
  failureTitle: str_(UIStrings.failureTitle),
76
76
  description: str_(UIStrings.description),
77
77
  guidanceLevel: 1,
78
+ scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
78
79
  requiredArtifacts: ['traces', 'devtoolsLogs', 'URL', 'GatherContext'],
79
80
  };
80
81
  }
@@ -257,8 +258,11 @@ class ThirdPartySummary extends Audit {
257
258
  const details = Audit.makeTableDetails(headings, results,
258
259
  {...overallSummary, isEntityGrouped: true});
259
260
 
261
+ const passed = overallSummary.wastedMs <= PASS_THRESHOLD_IN_MS;
262
+
260
263
  return {
261
- score: Number(overallSummary.wastedMs <= PASS_THRESHOLD_IN_MS),
264
+ score: Number(passed),
265
+ scoreDisplayMode: passed ? Audit.SCORING_MODES.INFORMATIVE : undefined,
262
266
  displayValue: str_(UIStrings.displayValue, {
263
267
  timeInMs: overallSummary.wastedMs,
264
268
  }),
@@ -36,6 +36,7 @@ class UnsizedImages extends Audit {
36
36
  description: str_(UIStrings.description),
37
37
  guidanceLevel: 3,
38
38
  requiredArtifacts: ['ImageElements'],
39
+ scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
39
40
  };
40
41
  }
41
42
 
@@ -153,7 +154,6 @@ class UnsizedImages extends Audit {
153
154
 
154
155
  return {
155
156
  score: unsizedImages.length > 0 ? 0 : 1,
156
- notApplicable: images.length === 0,
157
157
  details: Audit.makeTableDetails(headings, unsizedImages),
158
158
  metricSavings: {
159
159
  CLS: 0,
@@ -5,7 +5,6 @@
5
5
  */
6
6
 
7
7
  import {Audit} from './audit.js';
8
- import {ByteEfficiencyAudit} from './byte-efficiency/byte-efficiency-audit.js';
9
8
  import UrlUtils from '../lib/url-utils.js';
10
9
  import * as i18n from '../lib/i18n/i18n.js';
11
10
  import {NetworkRecords} from '../computed/network-records.js';
@@ -64,7 +63,7 @@ class UsesRelPreconnectAudit extends Audit {
64
63
  supportedModes: ['navigation'],
65
64
  guidanceLevel: 3,
66
65
  requiredArtifacts: ['traces', 'devtoolsLogs', 'URL', 'LinkElements'],
67
- scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
66
+ scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
68
67
  };
69
68
  }
70
69
 
@@ -268,7 +267,7 @@ class UsesRelPreconnectAudit extends Audit {
268
267
  {overallSavingsMs: maxWastedLcp, sortedBy: ['wastedMs']});
269
268
 
270
269
  return {
271
- score: ByteEfficiencyAudit.scoreForWastedMs(maxWastedLcp),
270
+ score: results.length ? 0 : 1,
272
271
  numericValue: maxWastedLcp,
273
272
  numericUnit: 'millisecond',
274
273
  displayValue: maxWastedLcp ?
@@ -7,7 +7,6 @@
7
7
  import UrlUtils from '../lib/url-utils.js';
8
8
  import {NetworkRequest} from '../lib/network-request.js';
9
9
  import {Audit} from './audit.js';
10
- import {ByteEfficiencyAudit} from './byte-efficiency/byte-efficiency-audit.js';
11
10
  import {CriticalRequestChains} from '../computed/critical-request-chains.js';
12
11
  import * as i18n from '../lib/i18n/i18n.js';
13
12
  import {MainResource} from '../computed/main-resource.js';
@@ -45,7 +44,7 @@ class UsesRelPreloadAudit extends Audit {
45
44
  supportedModes: ['navigation'],
46
45
  guidanceLevel: 3,
47
46
  requiredArtifacts: ['devtoolsLogs', 'traces', 'URL'],
48
- scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
47
+ scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
49
48
  };
50
49
  }
51
50
 
@@ -244,7 +243,7 @@ class UsesRelPreloadAudit extends Audit {
244
243
  {overallSavingsMs: wastedMs, sortedBy: ['wastedMs']});
245
244
 
246
245
  return {
247
- score: ByteEfficiencyAudit.scoreForWastedMs(wastedMs),
246
+ score: results.length ? 0 : 1,
248
247
  numericValue: wastedMs,
249
248
  numericUnit: 'millisecond',
250
249
  displayValue: wastedMs ?
@@ -36,6 +36,7 @@ class Viewport extends Audit {
36
36
  description: str_(UIStrings.description),
37
37
  guidanceLevel: 3,
38
38
  requiredArtifacts: ['MetaElements'],
39
+ scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
39
40
  };
40
41
  }
41
42
 
@@ -58,7 +58,7 @@ class WorkDuringInteraction extends Audit {
58
58
  title: str_(UIStrings.title),
59
59
  failureTitle: str_(UIStrings.failureTitle),
60
60
  description: str_(UIStrings.description),
61
- scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
61
+ scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
62
62
  supportedModes: ['timespan'],
63
63
  guidanceLevel: 1,
64
64
  requiredArtifacts: ['traces', 'devtoolsLogs', 'TraceElements'],
@@ -273,8 +273,12 @@ class WorkDuringInteraction extends Audit {
273
273
 
274
274
  const duration = interactionEvent.args.data.duration;
275
275
  const displayValue = str_(UIStrings.displayValue, {timeInMs: duration, interactionType});
276
+
277
+ const passed = duration < InteractionToNextPaint.defaultOptions.p10;
278
+
276
279
  return {
277
- score: duration < InteractionToNextPaint.defaultOptions.p10 ? 1 : 0,
280
+ score: passed ? 1 : 0,
281
+ scoreDisplayMode: passed ? Audit.SCORING_MODES.INFORMATIVE : undefined,
278
282
  displayValue,
279
283
  details: {
280
284
  type: 'list',
@@ -29,6 +29,7 @@ class ProtocolSession extends CrdpEventEmitter {
29
29
  this._nextProtocolTimeout = undefined;
30
30
 
31
31
  this._handleProtocolEvent = this._handleProtocolEvent.bind(this);
32
+ // @ts-expect-error Puppeteer expects the handler params to be type `unknown`
32
33
  this._cdpSession.on('*', this._handleProtocolEvent);
33
34
  }
34
35
 
@@ -106,6 +107,7 @@ class ProtocolSession extends CrdpEventEmitter {
106
107
  * @return {Promise<void>}
107
108
  */
108
109
  async dispose() {
110
+ // @ts-expect-error Puppeteer expects the handler params to be type `unknown`
109
111
  this._cdpSession.off('*', this._handleProtocolEvent);
110
112
  await this._cdpSession.detach();
111
113
  }
@@ -19,31 +19,31 @@ import {isIcuMessage} from '../../shared/localization/format.js';
19
19
 
20
20
  const UIStrings = {
21
21
  /** Message shown when a CSP does not have a base-uri directive. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "base-uri", "'none'", and "'self'" do not need to be translated. */
22
- missingBaseUri: 'Missing base-uri allows injected <base> tags to set the base URL for all ' +
22
+ missingBaseUri: 'Missing `base-uri` allows injected `<base>` tags to set the base URL for all ' +
23
23
  'relative URLs (e.g. scripts) to an attacker controlled domain. ' +
24
- 'Consider setting base-uri to \'none\' or \'self\'.',
24
+ 'Consider setting `base-uri` to `\'none\'` or `\'self\'`.',
25
25
  /** Message shown when a CSP does not have a script-src directive. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "script-src" does not need to be translated. */
26
- missingScriptSrc: 'script-src directive is missing. ' +
26
+ missingScriptSrc: '`script-src` directive is missing. ' +
27
27
  'This can allow the execution of unsafe scripts.',
28
28
  /** Message shown when a CSP does not have a script-src directive. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "object-src" and "'none'" do not need to be translated. */
29
- missingObjectSrc: 'Missing object-src allows the injection of plugins ' +
30
- 'that execute unsafe scripts. Consider setting object-src to \'none\' if you can.',
29
+ missingObjectSrc: 'Missing `object-src` allows the injection of plugins ' +
30
+ 'that execute unsafe scripts. Consider setting `object-src` to `\'none\'` if you can.',
31
31
  /** Message shown when a CSP uses a domain allowlist to filter out malicious scripts. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "CSP", "'strict-dynamic'", "nonces", and "hashes" do not need to be translated. "allowlists" can be interpreted as "whitelist". */
32
32
  strictDynamic: 'Host allowlists can frequently be bypassed. Consider using ' +
33
- 'CSP nonces or hashes instead, along with \'strict-dynamic\' if necessary.',
33
+ 'CSP nonces or hashes instead, along with `\'strict-dynamic\'` if necessary.',
34
34
  /** Message shown when a CSP allows inline scripts to be run in the page. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "CSP", "'unsafe-inline'", "nonces", and "hashes" do not need to be translated. */
35
- unsafeInline: '\'unsafe-inline\' allows the execution of unsafe in-page scripts ' +
35
+ unsafeInline: '`\'unsafe-inline\'` allows the execution of unsafe in-page scripts ' +
36
36
  'and event handlers. Consider using CSP nonces or hashes to allow scripts individually.',
37
37
  /** Message shown when a CSP is not backwards compatible with browsers that do not support CSP nonces/hashes. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "'unsafe-inline'", "nonces", and "hashes" do not need to be translated. */
38
- unsafeInlineFallback: 'Consider adding \'unsafe-inline\' (ignored by browsers supporting ' +
38
+ unsafeInlineFallback: 'Consider adding `\'unsafe-inline\'` (ignored by browsers supporting ' +
39
39
  'nonces/hashes) to be backward compatible with older browsers.',
40
40
  /** Message shown when a CSP is not backwards compatible with browsers that do not support the 'strict-dynamic' keyword. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "http:", "https:", and "'strict-dynamic'" do not need to be translated. */
41
41
  allowlistFallback: 'Consider adding https: and http: URL schemes (ignored by browsers ' +
42
- 'supporting \'strict-dynamic\') to be backward compatible with older browsers.',
42
+ 'supporting `\'strict-dynamic\'`) to be backward compatible with older browsers.',
43
43
  /** Message shown when a CSP only provides a reporting destination through the report-to directive. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "report-to", "report-uri", and "Chromium" do not need to be translated. */
44
44
  reportToOnly: 'The reporting destination is only configured via the report-to directive. ' +
45
45
  'This directive is only supported in Chromium-based browsers so it is ' +
46
- 'recommended to also use a report-uri directive.',
46
+ 'recommended to also use a `report-uri` directive.',
47
47
  /** Message shown when a CSP does not provide a reporting destination. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "CSP" does not need to be translated. */
48
48
  reportingDestinationMissing: 'No CSP configures a reporting destination. ' +
49
49
  'This makes it difficult to maintain the CSP over time and monitor for any breakages.',
@@ -65,13 +65,13 @@ const UIStrings = {
65
65
  */
66
66
  unknownKeyword: '{keyword} seems to be an invalid keyword.',
67
67
  /** Message shown when a CSP uses the deprecated reflected-xss directive. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "reflected-xss", "CSP2" and "X-XSS-Protection" do not need to be translated. */
68
- deprecatedReflectedXSS: 'reflected-xss is deprecated since CSP2. ' +
68
+ deprecatedReflectedXSS: '`reflected-xss` is deprecated since CSP2. ' +
69
69
  'Please, use the X-XSS-Protection header instead.',
70
70
  /** Message shown when a CSP uses the deprecated referrer directive. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "referrer", "CSP2" and "Referrer-Policy" do not need to be translated. */
71
- deprecatedReferrer: 'referrer is deprecated since CSP2. ' +
71
+ deprecatedReferrer: '`referrer` is deprecated since CSP2. ' +
72
72
  'Please, use the Referrer-Policy header instead.',
73
73
  /** Message shown when a CSP uses the deprecated disown-opener directive. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy". "disown-opener", "CSP3" and "Cross-Origin-Opener-Policy" do not need to be translated. */
74
- deprecatedDisownOpener: 'disown-opener is deprecated since CSP3. ' +
74
+ deprecatedDisownOpener: '`disown-opener` is deprecated since CSP3. ' +
75
75
  'Please, use the Cross-Origin-Opener-Policy header instead.',
76
76
  /**
77
77
  * @description Message shown when a CSP wildcard allows unsafe scripts to be run in the page. Shown in a table with a list of other CSP vulnerabilities and suggestions. "CSP" stands for "Content Security Policy".