lighthouse 11.7.0-dev.20240408 → 11.7.1

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 (141) hide show
  1. package/CONTRIBUTING.md +2 -2
  2. package/cli/test/smokehouse/core-tests.js +2 -0
  3. package/core/audits/accessibility/duplicate-id-active.d.ts +10 -0
  4. package/core/audits/accessibility/duplicate-id-active.js +42 -0
  5. package/core/audits/accessibility/target-size.js +1 -0
  6. package/core/audits/byte-efficiency/byte-efficiency-audit.d.ts +16 -0
  7. package/core/audits/byte-efficiency/byte-efficiency-audit.js +38 -1
  8. package/core/audits/byte-efficiency/offscreen-images.d.ts +11 -0
  9. package/core/audits/byte-efficiency/offscreen-images.js +15 -0
  10. package/core/audits/dobetterweb/uses-http2.d.ts +13 -0
  11. package/core/audits/dobetterweb/uses-http2.js +34 -2
  12. package/core/audits/layout-shift-elements.d.ts +16 -0
  13. package/core/audits/layout-shift-elements.js +101 -0
  14. package/core/audits/no-unload-listeners.d.ts +16 -0
  15. package/core/audits/no-unload-listeners.js +86 -0
  16. package/core/audits/preload-fonts.d.ts +5 -1
  17. package/core/audits/preload-fonts.js +10 -1
  18. package/core/audits/script-elements-test-audit.d.ts +14 -0
  19. package/core/audits/script-elements-test-audit.js +29 -0
  20. package/core/audits/seo/is-crawlable.d.ts +1 -2
  21. package/core/audits/seo/plugins.d.ts +15 -0
  22. package/core/audits/seo/plugins.js +150 -0
  23. package/core/audits/seo/tap-targets.d.ts +50 -0
  24. package/core/audits/seo/tap-targets.js +352 -0
  25. package/core/audits/uses-rel-preload.d.ts +5 -1
  26. package/core/audits/uses-rel-preload.js +11 -1
  27. package/core/audits/work-during-interaction.d.ts +2 -2
  28. package/core/audits/work-during-interaction.js +2 -2
  29. package/core/computed/js-bundles.d.ts +1 -1
  30. package/core/computed/metrics/lantern-first-contentful-paint.d.ts +82 -13
  31. package/core/computed/metrics/lantern-first-contentful-paint.js +178 -15
  32. package/core/computed/metrics/lantern-first-meaningful-paint.d.ts +12 -13
  33. package/core/computed/metrics/lantern-first-meaningful-paint.js +49 -10
  34. package/core/computed/metrics/lantern-interactive.d.ts +21 -13
  35. package/core/computed/metrics/lantern-interactive.js +84 -11
  36. package/core/computed/metrics/lantern-largest-contentful-paint.d.ts +25 -13
  37. package/core/computed/metrics/lantern-largest-contentful-paint.js +80 -12
  38. package/core/computed/metrics/lantern-max-potential-fid.d.ts +24 -13
  39. package/core/computed/metrics/lantern-max-potential-fid.js +64 -11
  40. package/core/computed/metrics/lantern-metric.d.ts +18 -9
  41. package/core/computed/metrics/lantern-metric.js +31 -13
  42. package/core/computed/metrics/lantern-speed-index.d.ts +32 -13
  43. package/core/computed/metrics/lantern-speed-index.js +116 -12
  44. package/core/computed/metrics/lantern-total-blocking-time.d.ts +25 -13
  45. package/core/computed/metrics/lantern-total-blocking-time.js +94 -10
  46. package/core/computed/metrics/metric.js +3 -1
  47. package/core/computed/module-duplication.d.ts +1 -1
  48. package/core/computed/page-dependency-graph.js +1 -2
  49. package/core/config/default-config.js +74 -46
  50. package/core/config/experimental-config.js +0 -11
  51. package/core/config/metrics-to-audits.d.ts +19 -0
  52. package/core/config/metrics-to-audits.js +62 -0
  53. package/core/gather/gatherers/accessibility.js +3 -1
  54. package/core/gather/gatherers/global-listeners.d.ts +27 -0
  55. package/core/gather/gatherers/global-listeners.js +108 -0
  56. package/core/gather/gatherers/script-elements.d.ts +21 -0
  57. package/core/gather/gatherers/script-elements.js +100 -0
  58. package/core/gather/gatherers/seo/embedded-content.d.ts +10 -0
  59. package/core/gather/gatherers/seo/embedded-content.js +63 -0
  60. package/core/gather/gatherers/seo/tap-targets.d.ts +21 -0
  61. package/core/gather/gatherers/seo/tap-targets.js +389 -0
  62. package/core/gather/gatherers/trace-elements.d.ts +10 -0
  63. package/core/gather/gatherers/trace-elements.js +19 -0
  64. package/core/lib/lantern/page-dependency-graph.d.ts +4 -4
  65. package/core/lib/lantern/page-dependency-graph.js +5 -5
  66. package/core/lib/lighthouse-compatibility.js +10 -53
  67. package/dist/report/bundle.esm.js +1 -1
  68. package/dist/report/flow.js +14 -14
  69. package/dist/report/standalone.js +1 -1
  70. package/flow-report/src/summary/category.tsx +12 -10
  71. package/package.json +1 -1
  72. package/report/renderer/performance-category-renderer.d.ts +7 -0
  73. package/report/renderer/performance-category-renderer.js +11 -1
  74. package/report/renderer/report-utils.js +10 -13
  75. package/shared/localization/locales/ar-XB.json +64 -1
  76. package/shared/localization/locales/ar.json +64 -1
  77. package/shared/localization/locales/bg.json +64 -1
  78. package/shared/localization/locales/ca.json +64 -1
  79. package/shared/localization/locales/cs.json +64 -1
  80. package/shared/localization/locales/da.json +64 -1
  81. package/shared/localization/locales/de.json +64 -1
  82. package/shared/localization/locales/el.json +64 -1
  83. package/shared/localization/locales/en-GB.json +64 -1
  84. package/shared/localization/locales/en-US.json +65 -2
  85. package/shared/localization/locales/en-XA.json +64 -1
  86. package/shared/localization/locales/en-XL.json +65 -2
  87. package/shared/localization/locales/es-419.json +64 -1
  88. package/shared/localization/locales/es.json +64 -1
  89. package/shared/localization/locales/fi.json +64 -1
  90. package/shared/localization/locales/fil.json +64 -1
  91. package/shared/localization/locales/fr.json +64 -1
  92. package/shared/localization/locales/he.json +64 -1
  93. package/shared/localization/locales/hi.json +64 -1
  94. package/shared/localization/locales/hr.json +64 -1
  95. package/shared/localization/locales/hu.json +64 -1
  96. package/shared/localization/locales/id.json +64 -1
  97. package/shared/localization/locales/it.json +64 -1
  98. package/shared/localization/locales/ja.json +64 -1
  99. package/shared/localization/locales/ko.json +64 -1
  100. package/shared/localization/locales/lt.json +64 -1
  101. package/shared/localization/locales/lv.json +64 -1
  102. package/shared/localization/locales/nl.json +64 -1
  103. package/shared/localization/locales/no.json +64 -1
  104. package/shared/localization/locales/pl.json +64 -1
  105. package/shared/localization/locales/pt-PT.json +64 -1
  106. package/shared/localization/locales/pt.json +64 -1
  107. package/shared/localization/locales/ro.json +64 -1
  108. package/shared/localization/locales/ru.json +64 -1
  109. package/shared/localization/locales/sk.json +64 -1
  110. package/shared/localization/locales/sl.json +64 -1
  111. package/shared/localization/locales/sr-Latn.json +64 -1
  112. package/shared/localization/locales/sr.json +64 -1
  113. package/shared/localization/locales/sv.json +64 -1
  114. package/shared/localization/locales/ta.json +64 -1
  115. package/shared/localization/locales/te.json +64 -1
  116. package/shared/localization/locales/th.json +64 -1
  117. package/shared/localization/locales/tr.json +64 -1
  118. package/shared/localization/locales/uk.json +64 -1
  119. package/shared/localization/locales/vi.json +64 -1
  120. package/shared/localization/locales/zh-HK.json +64 -1
  121. package/shared/localization/locales/zh-TW.json +64 -1
  122. package/shared/localization/locales/zh.json +64 -1
  123. package/tsconfig.json +0 -1
  124. package/types/artifacts.d.ts +17 -3
  125. package/types/config.d.ts +1 -0
  126. package/types/lhr/audit-details.d.ts +4 -9
  127. package/types/lhr/lhr.d.ts +2 -0
  128. package/core/lib/lantern/metrics/first-contentful-paint.d.ts +0 -79
  129. package/core/lib/lantern/metrics/first-contentful-paint.js +0 -200
  130. package/core/lib/lantern/metrics/first-meaningful-paint.d.ts +0 -6
  131. package/core/lib/lantern/metrics/first-meaningful-paint.js +0 -66
  132. package/core/lib/lantern/metrics/interactive.d.ts +0 -26
  133. package/core/lib/lantern/metrics/interactive.js +0 -112
  134. package/core/lib/lantern/metrics/largest-contentful-paint.d.ts +0 -19
  135. package/core/lib/lantern/metrics/largest-contentful-paint.js +0 -108
  136. package/core/lib/lantern/metrics/max-potential-fid.d.ts +0 -30
  137. package/core/lib/lantern/metrics/max-potential-fid.js +0 -92
  138. package/core/lib/lantern/metrics/speed-index.d.ts +0 -38
  139. package/core/lib/lantern/metrics/speed-index.js +0 -145
  140. package/core/lib/lantern/metrics/total-blocking-time.d.ts +0 -31
  141. package/core/lib/lantern/metrics/total-blocking-time.js +0 -128
@@ -4,23 +4,83 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
- import {TotalBlockingTime} from '../../lib/lantern/metrics/total-blocking-time.js';
8
7
  import {makeComputedArtifact} from '../computed-artifact.js';
8
+ import {LanternMetric} from './lantern-metric.js';
9
+ import {BaseNode} from '../../lib/lantern/base-node.js';
9
10
  import {LanternFirstContentfulPaint} from './lantern-first-contentful-paint.js';
10
11
  import {LanternInteractive} from './lantern-interactive.js';
11
- import {getComputationDataParams} from './lantern-metric.js';
12
+ import {BLOCKING_TIME_THRESHOLD, calculateSumOfBlockingTime} from './tbt-utils.js';
12
13
 
13
- /** @typedef {import('../../lib/lantern/metric.js').Extras} Extras */
14
+ /** @typedef {import('../../lib/lantern/base-node.js').Node<LH.Artifacts.NetworkRequest>} Node */
14
15
 
15
- class LanternTotalBlockingTime extends TotalBlockingTime {
16
+ class LanternTotalBlockingTime extends LanternMetric {
16
17
  /**
17
- * @param {LH.Artifacts.MetricComputationDataInput} data
18
- * @param {LH.Artifacts.ComputedContext} context
19
- * @param {Omit<Extras, 'optimistic'>=} extras
20
- * @return {Promise<LH.Artifacts.LanternMetric>}
18
+ * @return {LH.Gatherer.Simulation.MetricCoefficients}
19
+ */
20
+ static get COEFFICIENTS() {
21
+ return {
22
+ intercept: 0,
23
+ optimistic: 0.5,
24
+ pessimistic: 0.5,
25
+ };
26
+ }
27
+
28
+ /**
29
+ * @param {Node} dependencyGraph
30
+ * @return {Node}
21
31
  */
22
- static async computeMetricWithGraphs(data, context, extras) {
23
- return this.compute(await getComputationDataParams(data, context), extras);
32
+ static getOptimisticGraph(dependencyGraph) {
33
+ return dependencyGraph;
34
+ }
35
+
36
+ /**
37
+ * @param {Node} dependencyGraph
38
+ * @return {Node}
39
+ */
40
+ static getPessimisticGraph(dependencyGraph) {
41
+ return dependencyGraph;
42
+ }
43
+
44
+ /**
45
+ * @param {LH.Gatherer.Simulation.Result} simulation
46
+ * @param {import('../../lib/lantern/metric.js').Extras} extras
47
+ * @return {LH.Gatherer.Simulation.Result}
48
+ */
49
+ static getEstimateFromSimulation(simulation, extras) {
50
+ if (!extras.fcpResult) throw new Error('missing fcpResult');
51
+ if (!extras.interactiveResult) throw new Error('missing interactiveResult');
52
+
53
+ // Intentionally use the opposite FCP estimate. A pessimistic FCP is higher than equal to an
54
+ // optimistic FCP, which means potentially more tasks are excluded from the Total Blocking Time
55
+ // computation. So a more pessimistic FCP gives a more optimistic Total Blocking Time for the
56
+ // same work.
57
+ const fcpTimeInMs = extras.optimistic
58
+ ? extras.fcpResult.pessimisticEstimate.timeInMs
59
+ : extras.fcpResult.optimisticEstimate.timeInMs;
60
+
61
+ // Similarly, we always have pessimistic TTI >= optimistic TTI. Therefore, picking optimistic
62
+ // TTI means our window of interest is smaller and thus potentially more tasks are excluded from
63
+ // Total Blocking Time computation, yielding a lower (more optimistic) Total Blocking Time value
64
+ // for the same work.
65
+ const interactiveTimeMs = extras.optimistic
66
+ ? extras.interactiveResult.optimisticEstimate.timeInMs
67
+ : extras.interactiveResult.pessimisticEstimate.timeInMs;
68
+
69
+ const minDurationMs = BLOCKING_TIME_THRESHOLD;
70
+
71
+ const events = LanternTotalBlockingTime.getTopLevelEvents(
72
+ simulation.nodeTimings,
73
+ minDurationMs
74
+ );
75
+
76
+ return {
77
+ timeInMs: calculateSumOfBlockingTime(
78
+ events,
79
+ fcpTimeInMs,
80
+ interactiveTimeMs
81
+ ),
82
+ nodeTimings: simulation.nodeTimings,
83
+ };
24
84
  }
25
85
 
26
86
  /**
@@ -33,6 +93,30 @@ class LanternTotalBlockingTime extends TotalBlockingTime {
33
93
  const interactiveResult = await LanternInteractive.request(data, context);
34
94
  return this.computeMetricWithGraphs(data, context, {fcpResult, interactiveResult});
35
95
  }
96
+
97
+ /**
98
+ * @param {LH.Gatherer.Simulation.Result['nodeTimings']} nodeTimings
99
+ * @param {number} minDurationMs
100
+ */
101
+ static getTopLevelEvents(nodeTimings, minDurationMs) {
102
+ /** @type {Array<{start: number, end: number, duration: number}>}
103
+ */
104
+ const events = [];
105
+
106
+ for (const [node, timing] of nodeTimings.entries()) {
107
+ if (node.type !== BaseNode.TYPES.CPU) continue;
108
+ // Filtering out events below minimum duration.
109
+ if (timing.duration < minDurationMs) continue;
110
+
111
+ events.push({
112
+ start: timing.startTime,
113
+ end: timing.endTime,
114
+ duration: timing.duration,
115
+ });
116
+ }
117
+
118
+ return events;
119
+ }
36
120
  }
37
121
 
38
122
  const LanternTotalBlockingTimeComputed = makeComputedArtifact(
@@ -61,7 +61,9 @@ class Metric {
61
61
  * @return {Promise<LH.Artifacts.LanternMetric|LH.Artifacts.Metric>}
62
62
  */
63
63
  static async compute_(data, context) {
64
- const {trace, devtoolsLog, settings, gatherContext} = data;
64
+ // TODO: remove this fallback when lighthouse-pub-ads plugin can update.
65
+ const gatherContext = data.gatherContext || {gatherMode: 'navigation'};
66
+ const {trace, devtoolsLog, settings} = data;
65
67
  if (!trace || !devtoolsLog || !settings) {
66
68
  throw new Error('Did not provide necessary metric computation data');
67
69
  }
@@ -1,6 +1,6 @@
1
1
  export { ModuleDuplicationComputed as ModuleDuplication };
2
2
  declare const ModuleDuplicationComputed: typeof ModuleDuplication & {
3
- request: (dependencies: Pick<import("../index.js").Artifacts, "SourceMaps" | "Scripts">, context: import("../../types/utility-types.js").default.ImmutableObject<{
3
+ request: (dependencies: Pick<import("../index.js").Artifacts, "Scripts" | "SourceMaps">, context: import("../../types/utility-types.js").default.ImmutableObject<{
4
4
  computedCache: Map<string, import("../lib/arbitrary-equality-map.js").ArbitraryEqualityMap>;
5
5
  }>) => Promise<Map<string, {
6
6
  scriptId: string;
@@ -30,9 +30,8 @@ class PageDependencyGraph {
30
30
  // Calculates the URL artifact from the processed trace and DT log.
31
31
  const URL = data.URL || await DocumentUrls.request(data, context);
32
32
 
33
- const mainThreadEvents = processedTrace.mainThreadEvents;
34
33
  const lanternRequests = networkRecords.map(NetworkRequest.asLanternNetworkRequest);
35
- return LanternPageDependencyGraph.createGraph(mainThreadEvents, lanternRequests, URL);
34
+ return LanternPageDependencyGraph.createGraph(processedTrace, lanternRequests, URL);
36
35
  }
37
36
  }
38
37
 
@@ -9,6 +9,7 @@
9
9
  import * as LH from '../../types/lh.js';
10
10
  import * as constants from './constants.js';
11
11
  import * as i18n from '../lib/i18n/i18n.js';
12
+ import {metricsToAudits} from './metrics-to-audits.js';
12
13
 
13
14
  const UIStrings = {
14
15
  /** Title of the Performance category of audits. Equivalent to 'Web performance', this term is inclusive of all web page speed and loading optimization topics. Also used as a label of a score gauge; try to limit to 20 characters. */
@@ -19,6 +20,10 @@ const UIStrings = {
19
20
  budgetsGroupDescription: 'Performance budgets set standards for the performance of your site.',
20
21
  /** Title of the speed metrics section of the Performance category. Within this section are various speed metrics which quantify the pageload performance into values presented in seconds and milliseconds. */
21
22
  metricGroupTitle: 'Metrics',
23
+ /** Title of the opportunity section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the loading performance of their web page. 'Suggestion'/'Optimization'/'Recommendation' are reasonable synonyms for 'opportunity' in this case. */
24
+ loadOpportunitiesGroupTitle: 'Opportunities',
25
+ /** Description of the opportunity section of the Performance category. 'Suggestions' could also be 'recommendations'. Within this section are audits with imperative titles that suggest actions the user can take to improve the loading performance of their web page. */
26
+ loadOpportunitiesGroupDescription: 'These suggestions can help your page load faster. They don\'t [directly affect](https://developer.chrome.com/docs/lighthouse/performance/performance-scoring/) the Performance score.',
22
27
  /** Title of an opportunity sub-section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the time of the first initial render of the webpage. */
23
28
  firstPaintImprovementsGroupTitle: 'First Paint Improvements',
24
29
  /** Description of an opportunity sub-section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the time of the first initial render of the webpage. */
@@ -133,8 +138,10 @@ const defaultConfig = {
133
138
  {id: 'CSSUsage', gatherer: 'css-usage'},
134
139
  {id: 'Doctype', gatherer: 'dobetterweb/doctype'},
135
140
  {id: 'DOMStats', gatherer: 'dobetterweb/domstats'},
141
+ {id: 'EmbeddedContent', gatherer: 'seo/embedded-content'},
136
142
  {id: 'FontSize', gatherer: 'seo/font-size'},
137
143
  {id: 'Inputs', gatherer: 'inputs'},
144
+ {id: 'GlobalListeners', gatherer: 'global-listeners'},
138
145
  {id: 'IFrameElements', gatherer: 'iframe-elements'},
139
146
  {id: 'ImageElements', gatherer: 'image-elements'},
140
147
  {id: 'InstallabilityErrors', gatherer: 'installability-errors'},
@@ -148,10 +155,12 @@ const defaultConfig = {
148
155
  {id: 'ResponseCompression', gatherer: 'dobetterweb/response-compression'},
149
156
  {id: 'RobotsTxt', gatherer: 'seo/robots-txt'},
150
157
  {id: 'ServiceWorker', gatherer: 'service-worker'},
158
+ {id: 'ScriptElements', gatherer: 'script-elements'},
151
159
  {id: 'Scripts', gatherer: 'scripts'},
152
160
  {id: 'SourceMaps', gatherer: 'source-maps'},
153
161
  {id: 'Stacks', gatherer: 'stacks'},
154
162
  {id: 'TagsBlockingFirstPaint', gatherer: 'dobetterweb/tags-blocking-first-paint'},
163
+ {id: 'TapTargets', gatherer: 'seo/tap-targets'},
155
164
  {id: 'TraceElements', gatherer: 'trace-elements'},
156
165
  {id: 'ViewportDimensions', gatherer: 'viewport-dimensions'},
157
166
  {id: 'WebAppManifest', gatherer: 'web-app-manifest'},
@@ -192,10 +201,12 @@ const defaultConfig = {
192
201
  'content-width',
193
202
  'image-aspect-ratio',
194
203
  'image-size-responsive',
204
+ 'preload-fonts',
195
205
  'deprecations',
196
206
  'third-party-cookies',
197
207
  'mainthread-work-breakdown',
198
208
  'bootup-time',
209
+ 'uses-rel-preload',
199
210
  'uses-rel-preconnect',
200
211
  'font-display',
201
212
  'diagnostics',
@@ -211,8 +222,10 @@ const defaultConfig = {
211
222
  'third-party-facades',
212
223
  'largest-contentful-paint-element',
213
224
  'lcp-lazy-loaded',
225
+ 'layout-shift-elements',
214
226
  'layout-shifts',
215
227
  'long-tasks',
228
+ 'no-unload-listeners',
216
229
  'non-composited-animations',
217
230
  'unsized-images',
218
231
  'valid-source-maps',
@@ -248,6 +261,7 @@ const defaultConfig = {
248
261
  'accessibility/definition-list',
249
262
  'accessibility/dlitem',
250
263
  'accessibility/document-title',
264
+ 'accessibility/duplicate-id-active',
251
265
  'accessibility/duplicate-id-aria',
252
266
  'accessibility/empty-heading',
253
267
  'accessibility/form-field-multiple-labels',
@@ -326,7 +340,9 @@ const defaultConfig = {
326
340
  'seo/crawlable-anchors',
327
341
  'seo/is-crawlable',
328
342
  'seo/robots-txt',
343
+ 'seo/tap-targets',
329
344
  'seo/hreflang',
345
+ 'seo/plugins',
330
346
  'seo/canonical',
331
347
  'seo/manual/structured-data',
332
348
  'work-during-interaction',
@@ -336,6 +352,10 @@ const defaultConfig = {
336
352
  'metrics': {
337
353
  title: str_(UIStrings.metricGroupTitle),
338
354
  },
355
+ 'load-opportunities': {
356
+ title: str_(UIStrings.loadOpportunitiesGroupTitle),
357
+ description: str_(UIStrings.loadOpportunitiesGroupDescription),
358
+ },
339
359
  'budgets': {
340
360
  title: str_(UIStrings.budgetsGroupTitle),
341
361
  description: str_(UIStrings.budgetsGroupDescription),
@@ -414,58 +434,60 @@ const defaultConfig = {
414
434
  title: str_(UIStrings.performanceCategoryTitle),
415
435
  supportedModes: ['navigation', 'timespan', 'snapshot'],
416
436
  auditRefs: [
417
- {id: 'first-contentful-paint', weight: 10, group: 'metrics', acronym: 'FCP'},
418
- {id: 'largest-contentful-paint', weight: 25, group: 'metrics', acronym: 'LCP'},
419
- {id: 'total-blocking-time', weight: 30, group: 'metrics', acronym: 'TBT'},
420
- {id: 'cumulative-layout-shift', weight: 25, group: 'metrics', acronym: 'CLS'},
437
+ {id: 'first-contentful-paint', weight: 10, group: 'metrics', acronym: 'FCP', relevantAudits: metricsToAudits.fcpRelevantAudits},
438
+ {id: 'largest-contentful-paint', weight: 25, group: 'metrics', acronym: 'LCP', relevantAudits: metricsToAudits.lcpRelevantAudits},
439
+ {id: 'total-blocking-time', weight: 30, group: 'metrics', acronym: 'TBT', relevantAudits: metricsToAudits.tbtRelevantAudits},
440
+ {id: 'cumulative-layout-shift', weight: 25, group: 'metrics', acronym: 'CLS', relevantAudits: metricsToAudits.clsRelevantAudits},
421
441
  {id: 'speed-index', weight: 10, group: 'metrics', acronym: 'SI'},
422
- {id: 'interaction-to-next-paint', weight: 0, group: 'metrics', acronym: 'INP'},
442
+ {id: 'interaction-to-next-paint', weight: 0, group: 'metrics', acronym: 'INP', relevantAudits: metricsToAudits.inpRelevantAudits},
423
443
 
424
444
  // These are our "invisible" metrics. Not displayed, but still in the LHR.
425
445
  {id: 'interactive', weight: 0, group: 'hidden', acronym: 'TTI'},
426
446
  {id: 'max-potential-fid', weight: 0, group: 'hidden'},
427
447
  {id: 'first-meaningful-paint', weight: 0, acronym: 'FMP', group: 'hidden'},
428
448
 
429
- {id: 'render-blocking-resources', weight: 0, group: 'diagnostics'},
430
- {id: 'uses-responsive-images', weight: 0, group: 'diagnostics'},
431
- {id: 'offscreen-images', weight: 0, group: 'diagnostics'},
432
- {id: 'unminified-css', weight: 0, group: 'diagnostics'},
433
- {id: 'unminified-javascript', weight: 0, group: 'diagnostics'},
434
- {id: 'unused-css-rules', weight: 0, group: 'diagnostics'},
435
- {id: 'unused-javascript', weight: 0, group: 'diagnostics'},
436
- {id: 'uses-optimized-images', weight: 0, group: 'diagnostics'},
437
- {id: 'modern-image-formats', weight: 0, group: 'diagnostics'},
438
- {id: 'uses-text-compression', weight: 0, group: 'diagnostics'},
439
- {id: 'uses-rel-preconnect', weight: 0, group: 'diagnostics'},
440
- {id: 'server-response-time', weight: 0, group: 'diagnostics'},
441
- {id: 'redirects', weight: 0, group: 'diagnostics'},
442
- {id: 'uses-http2', weight: 0, group: 'diagnostics'},
443
- {id: 'efficient-animated-content', weight: 0, group: 'diagnostics'},
444
- {id: 'duplicated-javascript', weight: 0, group: 'diagnostics'},
445
- {id: 'legacy-javascript', weight: 0, group: 'diagnostics'},
446
- {id: 'prioritize-lcp-image', weight: 0, group: 'diagnostics'},
447
- {id: 'total-byte-weight', weight: 0, group: 'diagnostics'},
448
- {id: 'uses-long-cache-ttl', weight: 0, group: 'diagnostics'},
449
- {id: 'dom-size', weight: 0, group: 'diagnostics'},
450
- {id: 'critical-request-chains', weight: 0, group: 'diagnostics'},
451
- {id: 'user-timings', weight: 0, group: 'diagnostics'},
452
- {id: 'bootup-time', weight: 0, group: 'diagnostics'},
453
- {id: 'mainthread-work-breakdown', weight: 0, group: 'diagnostics'},
454
- {id: 'font-display', weight: 0, group: 'diagnostics'},
455
- {id: 'third-party-summary', weight: 0, group: 'diagnostics'},
456
- {id: 'third-party-facades', weight: 0, group: 'diagnostics'},
457
- {id: 'largest-contentful-paint-element', weight: 0, group: 'diagnostics'},
458
- {id: 'lcp-lazy-loaded', weight: 0, group: 'diagnostics'},
459
- {id: 'layout-shifts', weight: 0, group: 'diagnostics'},
460
- {id: 'uses-passive-event-listeners', weight: 0, group: 'diagnostics'},
461
- {id: 'no-document-write', weight: 0, group: 'diagnostics'},
462
- {id: 'long-tasks', weight: 0, group: 'diagnostics'},
463
- {id: 'non-composited-animations', weight: 0, group: 'diagnostics'},
464
- {id: 'unsized-images', weight: 0, group: 'diagnostics'},
465
- {id: 'viewport', weight: 0, group: 'diagnostics'},
466
- {id: 'uses-responsive-images-snapshot', weight: 0, group: 'diagnostics'},
467
- {id: 'work-during-interaction', weight: 0, group: 'diagnostics'},
468
- {id: 'bf-cache', weight: 0, group: 'diagnostics'},
449
+ // These audits will be put in "load-opportunities" or "diagnostics" based on their details type.
450
+ {id: 'render-blocking-resources', weight: 0},
451
+ {id: 'uses-responsive-images', weight: 0},
452
+ {id: 'offscreen-images', weight: 0},
453
+ {id: 'unminified-css', weight: 0},
454
+ {id: 'unminified-javascript', weight: 0},
455
+ {id: 'unused-css-rules', weight: 0},
456
+ {id: 'unused-javascript', weight: 0},
457
+ {id: 'uses-optimized-images', weight: 0},
458
+ {id: 'modern-image-formats', weight: 0},
459
+ {id: 'uses-text-compression', weight: 0},
460
+ {id: 'uses-rel-preconnect', weight: 0},
461
+ {id: 'server-response-time', weight: 0},
462
+ {id: 'redirects', weight: 0},
463
+ {id: 'uses-rel-preload', weight: 0},
464
+ {id: 'uses-http2', weight: 0},
465
+ {id: 'efficient-animated-content', weight: 0},
466
+ {id: 'duplicated-javascript', weight: 0},
467
+ {id: 'legacy-javascript', weight: 0},
468
+ {id: 'prioritize-lcp-image', weight: 0},
469
+ {id: 'total-byte-weight', weight: 0},
470
+ {id: 'uses-long-cache-ttl', weight: 0},
471
+ {id: 'dom-size', weight: 0},
472
+ {id: 'critical-request-chains', weight: 0},
473
+ {id: 'user-timings', weight: 0},
474
+ {id: 'bootup-time', weight: 0},
475
+ {id: 'mainthread-work-breakdown', weight: 0},
476
+ {id: 'font-display', weight: 0},
477
+ {id: 'third-party-summary', weight: 0},
478
+ {id: 'third-party-facades', weight: 0},
479
+ {id: 'largest-contentful-paint-element', weight: 0},
480
+ {id: 'lcp-lazy-loaded', weight: 0},
481
+ {id: 'layout-shifts', weight: 0},
482
+ {id: 'uses-passive-event-listeners', weight: 0},
483
+ {id: 'no-document-write', weight: 0},
484
+ {id: 'long-tasks', weight: 0},
485
+ {id: 'non-composited-animations', weight: 0},
486
+ {id: 'unsized-images', weight: 0},
487
+ {id: 'viewport', weight: 0},
488
+ {id: 'uses-responsive-images-snapshot', weight: 0},
489
+ {id: 'work-during-interaction', weight: 0},
490
+ {id: 'bf-cache', weight: 0},
469
491
 
470
492
  // Budget audits.
471
493
  {id: 'performance-budget', weight: 0, group: 'budgets'},
@@ -482,6 +504,7 @@ const defaultConfig = {
482
504
  {id: 'final-screenshot', weight: 0, group: 'hidden'},
483
505
  {id: 'script-treemap-data', weight: 0, group: 'hidden'},
484
506
  {id: 'resource-summary', weight: 0, group: 'hidden'},
507
+ {id: 'layout-shift-elements', weight: 0, group: 'hidden'},
485
508
  ],
486
509
  },
487
510
  'accessibility': {
@@ -520,6 +543,7 @@ const defaultConfig = {
520
543
  {id: 'definition-list', weight: 7, group: 'a11y-tables-lists'},
521
544
  {id: 'dlitem', weight: 7, group: 'a11y-tables-lists'},
522
545
  {id: 'document-title', weight: 7, group: 'a11y-names-labels'},
546
+ {id: 'duplicate-id-active', weight: 7, group: 'a11y-navigation'},
523
547
  {id: 'duplicate-id-aria', weight: 10, group: 'a11y-aria'},
524
548
  {id: 'form-field-multiple-labels', weight: 3, group: 'a11y-names-labels'},
525
549
  {id: 'frame-title', weight: 7, group: 'a11y-names-labels'},
@@ -543,7 +567,6 @@ const defaultConfig = {
543
567
  {id: 'skip-link', weight: 3, group: 'a11y-names-labels'},
544
568
  {id: 'tabindex', weight: 7, group: 'a11y-navigation'},
545
569
  {id: 'table-duplicate-name', weight: 1, group: 'a11y-tables-lists'},
546
- {id: 'target-size', weight: 7, group: 'a11y-best-practices'},
547
570
  {id: 'td-headers-attr', weight: 7, group: 'a11y-tables-lists'},
548
571
  {id: 'th-has-data-cells', weight: 7, group: 'a11y-tables-lists'},
549
572
  {id: 'valid-lang', weight: 7, group: 'a11y-language'},
@@ -563,6 +586,7 @@ const defaultConfig = {
563
586
  {id: 'empty-heading', weight: 0, group: 'hidden'},
564
587
  {id: 'identical-links-same-purpose', weight: 0, group: 'hidden'},
565
588
  {id: 'landmark-one-main', weight: 0, group: 'hidden'},
589
+ {id: 'target-size', weight: 0, group: 'hidden'},
566
590
  {id: 'label-content-name-mismatch', weight: 0, group: 'hidden'},
567
591
  {id: 'table-fake-caption', weight: 0, group: 'hidden'},
568
592
  {id: 'td-has-header', weight: 0, group: 'hidden'},
@@ -581,10 +605,12 @@ const defaultConfig = {
581
605
  {id: 'paste-preventing-inputs', weight: 3, group: 'best-practices-ux'},
582
606
  {id: 'image-aspect-ratio', weight: 1, group: 'best-practices-ux'},
583
607
  {id: 'image-size-responsive', weight: 1, group: 'best-practices-ux'},
608
+ {id: 'preload-fonts', weight: 1, group: 'best-practices-ux'},
584
609
  // Browser Compatibility
585
610
  {id: 'doctype', weight: 1, group: 'best-practices-browser-compat'},
586
611
  {id: 'charset', weight: 1, group: 'best-practices-browser-compat'},
587
612
  // General Group
613
+ {id: 'no-unload-listeners', weight: 1, group: 'best-practices-general'},
588
614
  {id: 'js-libraries', weight: 0, group: 'best-practices-general'},
589
615
  {id: 'deprecations', weight: 5, group: 'best-practices-general'},
590
616
  {id: 'third-party-cookies', weight: 5, group: 'best-practices-general'},
@@ -611,6 +637,8 @@ const defaultConfig = {
611
637
  {id: 'hreflang', weight: 1, group: 'seo-content'},
612
638
  {id: 'canonical', weight: 1, group: 'seo-content'},
613
639
  {id: 'font-size', weight: 1, group: 'seo-mobile'},
640
+ {id: 'plugins', weight: 1, group: 'seo-content'},
641
+ {id: 'tap-targets', weight: 1, group: 'seo-mobile'},
614
642
  // Manual audits
615
643
  {id: 'structured-data', weight: 0},
616
644
  ],
@@ -14,24 +14,13 @@ const config = {
14
14
  extends: 'lighthouse:default',
15
15
  audits: [
16
16
  'autocomplete',
17
- // Preload advice is on hold until https://github.com/GoogleChrome/lighthouse/issues/11960
18
- 'preload-fonts',
19
- 'uses-rel-preload',
20
17
  ],
21
18
  categories: {
22
- // @ts-ignore: `title` is required in CategoryJson. setting to the same value as the default
23
- // config is awkward - easier to omit the property here. Will defer to default config.
24
- 'performance': {
25
- auditRefs: [
26
- {id: 'uses-rel-preload', weight: 0, group: 'diagnostics'},
27
- ],
28
- },
29
19
  // @ts-ignore: `title` is required in CategoryJson. setting to the same value as the default
30
20
  // config is awkward - easier to omit the property here. Will defer to default config.
31
21
  'best-practices': {
32
22
  auditRefs: [
33
23
  {id: 'autocomplete', weight: 0, group: 'best-practices-ux'},
34
- {id: 'preload-fonts', weight: 0, group: 'best-practices-ux'},
35
24
  ],
36
25
  },
37
26
  },
@@ -0,0 +1,19 @@
1
+ export namespace metricsToAudits {
2
+ export { fcpRelevantAudits };
3
+ export { lcpRelevantAudits };
4
+ export { tbtRelevantAudits };
5
+ export { clsRelevantAudits };
6
+ export { inpRelevantAudits };
7
+ }
8
+ /**
9
+ * @license
10
+ * Copyright 2021 Google LLC
11
+ * SPDX-License-Identifier: Apache-2.0
12
+ */
13
+ declare const fcpRelevantAudits: string[];
14
+ declare const lcpRelevantAudits: string[];
15
+ declare const tbtRelevantAudits: string[];
16
+ declare const clsRelevantAudits: string[];
17
+ declare const inpRelevantAudits: string[];
18
+ export {};
19
+ //# sourceMappingURL=metrics-to-audits.d.ts.map
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2021 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ // go/lh-audit-metric-mapping
8
+ const fcpRelevantAudits = [
9
+ 'server-response-time',
10
+ 'render-blocking-resources',
11
+ 'redirects',
12
+ 'critical-request-chains',
13
+ 'uses-text-compression',
14
+ 'uses-rel-preconnect',
15
+ 'uses-rel-preload',
16
+ 'font-display',
17
+ 'unminified-javascript',
18
+ 'unminified-css',
19
+ 'unused-css-rules',
20
+ ];
21
+
22
+ const lcpRelevantAudits = [
23
+ ...fcpRelevantAudits,
24
+ 'largest-contentful-paint-element',
25
+ 'prioritize-lcp-image',
26
+ 'unused-javascript',
27
+ 'efficient-animated-content',
28
+ 'total-byte-weight',
29
+ 'lcp-lazy-loaded',
30
+ ];
31
+
32
+ const tbtRelevantAudits = [
33
+ 'long-tasks',
34
+ 'third-party-summary',
35
+ 'third-party-facades',
36
+ 'bootup-time',
37
+ 'mainthread-work-breakdown',
38
+ 'dom-size',
39
+ 'duplicated-javascript',
40
+ 'legacy-javascript',
41
+ 'viewport',
42
+ ];
43
+
44
+ const clsRelevantAudits = [
45
+ 'layout-shift-elements',
46
+ 'layout-shifts',
47
+ 'non-composited-animations',
48
+ 'unsized-images',
49
+ // 'preload-fonts', // actually in BP, rather than perf
50
+ ];
51
+
52
+ const inpRelevantAudits = [
53
+ 'work-during-interaction',
54
+ ];
55
+
56
+ export const metricsToAudits = {
57
+ fcpRelevantAudits,
58
+ lcpRelevantAudits,
59
+ tbtRelevantAudits,
60
+ clsRelevantAudits,
61
+ inpRelevantAudits,
62
+ };
@@ -52,6 +52,7 @@ async function runA11yChecks() {
52
52
  'aria-text': {enabled: true},
53
53
  'audio-caption': {enabled: false},
54
54
  'blink': {enabled: false},
55
+ 'duplicate-id-active': {enabled: true},
55
56
  'duplicate-id': {enabled: false},
56
57
  'empty-heading': {enabled: true},
57
58
  'frame-focusable-content': {enabled: false},
@@ -78,7 +79,8 @@ async function runA11yChecks() {
78
79
  'tabindex': {enabled: true},
79
80
  'table-duplicate-name': {enabled: true},
80
81
  'table-fake-caption': {enabled: true},
81
- 'target-size': {enabled: true},
82
+ // TODO: https://github.com/GoogleChrome/lighthouse/issues/15824
83
+ // 'target-size': {enabled: true},
82
84
  'td-has-header': {enabled: true},
83
85
  },
84
86
  });
@@ -0,0 +1,27 @@
1
+ export default GlobalListeners;
2
+ declare class GlobalListeners extends BaseGatherer {
3
+ /**
4
+ * @param {LH.Crdp.DOMDebugger.EventListener} listener
5
+ * @return {listener is {type: 'pagehide'|'unload'|'visibilitychange'} & LH.Crdp.DOMDebugger.EventListener}
6
+ */
7
+ static _filterForAllowlistedTypes(listener: LH.Crdp.DOMDebugger.EventListener): listener is {
8
+ type: 'pagehide' | 'unload' | 'visibilitychange';
9
+ } & import("devtools-protocol").Protocol.DOMDebugger.EventListener;
10
+ /**
11
+ * @param { LH.Artifacts.GlobalListener } listener
12
+ * @return { string }
13
+ */
14
+ getListenerIndentifier(listener: LH.Artifacts.GlobalListener): string;
15
+ /**
16
+ * @param { LH.Artifacts['GlobalListeners'] } listeners
17
+ * @return { LH.Artifacts['GlobalListeners'] }
18
+ */
19
+ dedupeListeners(listeners: LH.Artifacts['GlobalListeners']): LH.Artifacts['GlobalListeners'];
20
+ /**
21
+ * @param {LH.Gatherer.Context} passContext
22
+ * @return {Promise<LH.Artifacts['GlobalListeners']>}
23
+ */
24
+ getArtifact(passContext: LH.Gatherer.Context): Promise<LH.Artifacts['GlobalListeners']>;
25
+ }
26
+ import BaseGatherer from '../base-gatherer.js';
27
+ //# sourceMappingURL=global-listeners.d.ts.map