lighthouse 12.8.2 → 13.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.
Files changed (270) hide show
  1. package/cli/cli-flags.js +1 -1
  2. package/cli/test/smokehouse/config/exclusions.js +0 -2
  3. package/cli/test/smokehouse/version-check.d.ts +1 -1
  4. package/core/audits/accessibility/accesskeys.js +3 -3
  5. package/core/audits/accessibility/aria-allowed-attr.js +3 -3
  6. package/core/audits/accessibility/aria-allowed-role.js +2 -1
  7. package/core/audits/accessibility/aria-command-name.js +1 -1
  8. package/core/audits/accessibility/aria-conditional-attr.js +1 -1
  9. package/core/audits/accessibility/aria-deprecated-role.js +1 -1
  10. package/core/audits/accessibility/aria-dialog-name.js +1 -1
  11. package/core/audits/accessibility/aria-hidden-body.js +3 -3
  12. package/core/audits/accessibility/aria-hidden-focus.js +3 -3
  13. package/core/audits/accessibility/aria-input-field-name.js +3 -3
  14. package/core/audits/accessibility/aria-meter-name.js +1 -1
  15. package/core/audits/accessibility/aria-progressbar-name.js +1 -1
  16. package/core/audits/accessibility/aria-prohibited-attr.js +1 -1
  17. package/core/audits/accessibility/aria-required-attr.js +3 -3
  18. package/core/audits/accessibility/aria-required-children.js +3 -3
  19. package/core/audits/accessibility/aria-required-parent.js +3 -3
  20. package/core/audits/accessibility/aria-roles.js +3 -3
  21. package/core/audits/accessibility/aria-text.js +3 -3
  22. package/core/audits/accessibility/aria-toggle-field-name.js +3 -3
  23. package/core/audits/accessibility/aria-tooltip-name.js +1 -1
  24. package/core/audits/accessibility/aria-treeitem-name.js +1 -1
  25. package/core/audits/accessibility/aria-valid-attr-value.js +3 -3
  26. package/core/audits/accessibility/aria-valid-attr.js +3 -3
  27. package/core/audits/accessibility/button-name.js +3 -3
  28. package/core/audits/accessibility/bypass.js +3 -3
  29. package/core/audits/accessibility/color-contrast.js +3 -3
  30. package/core/audits/accessibility/definition-list.js +3 -3
  31. package/core/audits/accessibility/dlitem.js +3 -3
  32. package/core/audits/accessibility/document-title.js +3 -3
  33. package/core/audits/accessibility/duplicate-id-aria.js +3 -3
  34. package/core/audits/accessibility/empty-heading.js +3 -3
  35. package/core/audits/accessibility/form-field-multiple-labels.js +3 -3
  36. package/core/audits/accessibility/frame-title.js +3 -3
  37. package/core/audits/accessibility/heading-order.js +3 -3
  38. package/core/audits/accessibility/html-has-lang.js +3 -3
  39. package/core/audits/accessibility/html-lang-valid.js +3 -3
  40. package/core/audits/accessibility/html-xml-lang-mismatch.js +3 -3
  41. package/core/audits/accessibility/identical-links-same-purpose.js +3 -3
  42. package/core/audits/accessibility/image-alt.js +3 -3
  43. package/core/audits/accessibility/image-redundant-alt.js +4 -3
  44. package/core/audits/accessibility/input-button-name.js +3 -3
  45. package/core/audits/accessibility/input-image-alt.js +3 -3
  46. package/core/audits/accessibility/label-content-name-mismatch.js +3 -3
  47. package/core/audits/accessibility/label.js +3 -3
  48. package/core/audits/accessibility/landmark-one-main.js +3 -4
  49. package/core/audits/accessibility/link-in-text-block.js +3 -3
  50. package/core/audits/accessibility/link-name.js +3 -3
  51. package/core/audits/accessibility/list.js +3 -3
  52. package/core/audits/accessibility/listitem.js +3 -3
  53. package/core/audits/accessibility/meta-refresh.js +3 -3
  54. package/core/audits/accessibility/meta-viewport.js +3 -3
  55. package/core/audits/accessibility/object-alt.js +3 -3
  56. package/core/audits/accessibility/select-name.js +3 -3
  57. package/core/audits/accessibility/skip-link.js +3 -3
  58. package/core/audits/accessibility/tabindex.js +3 -3
  59. package/core/audits/accessibility/table-duplicate-name.js +4 -3
  60. package/core/audits/accessibility/table-fake-caption.js +3 -3
  61. package/core/audits/accessibility/target-size.js +3 -3
  62. package/core/audits/accessibility/td-has-header.js +3 -3
  63. package/core/audits/accessibility/td-headers-attr.js +3 -3
  64. package/core/audits/accessibility/th-has-data-cells.js +3 -3
  65. package/core/audits/accessibility/valid-lang.js +3 -3
  66. package/core/audits/accessibility/video-caption.js +3 -3
  67. package/core/audits/audit.d.ts +0 -4
  68. package/core/audits/audit.js +2 -13
  69. package/core/audits/insights/cls-culprits-insight.js +1 -1
  70. package/core/audits/insights/dom-size-insight.js +11 -7
  71. package/core/audits/insights/font-display-insight.js +3 -1
  72. package/core/audits/insights/image-delivery-insight.js +4 -1
  73. package/core/audits/insights/insight-audit.d.ts +6 -4
  74. package/core/audits/insights/insight-audit.js +27 -8
  75. package/core/audits/insights/third-parties-insight.js +1 -1
  76. package/core/audits/layout-shifts.js +1 -1
  77. package/core/audits/predictive-perf.js +2 -2
  78. package/core/audits/seo/crawlable-anchors.js +2 -3
  79. package/core/audits/seo/manual/structured-data.js +1 -1
  80. package/core/audits/server-response-time.d.ts +0 -5
  81. package/core/audits/server-response-time.js +12 -26
  82. package/core/computed/metrics/cumulative-layout-shift.js +2 -2
  83. package/core/computed/metrics/lantern-metric.js +3 -3
  84. package/core/computed/metrics/lcp-breakdown.d.ts +10 -5
  85. package/core/computed/metrics/lcp-breakdown.js +50 -22
  86. package/core/computed/metrics/time-to-first-byte.js +33 -10
  87. package/core/computed/metrics/timing-summary.js +3 -2
  88. package/core/computed/page-dependency-graph.js +1 -1
  89. package/core/computed/trace-engine-result.js +2 -2
  90. package/core/config/default-config.js +110 -152
  91. package/core/config/experimental-config.js +1 -32
  92. package/core/config/filters.js +6 -9
  93. package/core/config/lr-desktop-config.js +0 -1
  94. package/core/config/lr-mobile-config.js +0 -1
  95. package/core/gather/driver/target-manager.d.ts +1 -1
  96. package/core/gather/driver.d.ts +1 -1
  97. package/core/gather/gatherers/anchor-elements.js +8 -24
  98. package/core/gather/gatherers/image-elements.js +32 -6
  99. package/core/gather/gatherers/inspector-issues.js +1 -28
  100. package/core/gather/gatherers/trace-elements.d.ts +2 -11
  101. package/core/gather/gatherers/trace-elements.js +9 -39
  102. package/core/gather/navigation-runner.js +0 -3
  103. package/core/gather/session.d.ts +1 -1
  104. package/core/lib/asset-saver.d.ts +2 -2
  105. package/core/lib/asset-saver.js +33 -43
  106. package/core/lib/bf-cache-strings.js +10 -9
  107. package/core/lib/deprecations-strings.js +5 -5
  108. package/core/lib/emulation.d.ts +10 -0
  109. package/core/lib/emulation.js +21 -6
  110. package/core/lib/legacy-javascript/legacy-javascript.js +4 -11
  111. package/core/lib/network-request.d.ts +0 -7
  112. package/core/lib/network-request.js +0 -16
  113. package/core/lib/proto-preprocessor.js +10 -25
  114. package/core/runner.js +1 -8
  115. package/core/scoring.js +1 -1
  116. package/dist/report/bundle.esm.js +10 -49
  117. package/dist/report/flow.js +12 -51
  118. package/dist/report/standalone.js +11 -50
  119. package/flow-report/src/i18n/i18n.d.ts +4 -6
  120. package/package.json +16 -19
  121. package/readme.md +2 -2
  122. package/report/assets/styles.css +0 -39
  123. package/report/renderer/api.js +0 -1
  124. package/report/renderer/category-renderer.js +6 -0
  125. package/report/renderer/components.js +1 -1
  126. package/report/renderer/details-renderer.d.ts +1 -2
  127. package/report/renderer/details-renderer.js +0 -1
  128. package/report/renderer/dom.d.ts +0 -13
  129. package/report/renderer/dom.js +0 -38
  130. package/report/renderer/performance-category-renderer.d.ts +0 -26
  131. package/report/renderer/performance-category-renderer.js +10 -142
  132. package/report/renderer/report-ui-features.d.ts +0 -1
  133. package/report/renderer/report-ui-features.js +2 -13
  134. package/report/renderer/report-utils.d.ts +2 -3
  135. package/report/renderer/report-utils.js +4 -6
  136. package/report/types/report-renderer.d.ts +0 -6
  137. package/shared/localization/locales/ar-XB.json +107 -455
  138. package/shared/localization/locales/ar.json +107 -455
  139. package/shared/localization/locales/bg.json +96 -444
  140. package/shared/localization/locales/ca.json +96 -444
  141. package/shared/localization/locales/cs.json +96 -444
  142. package/shared/localization/locales/da.json +96 -444
  143. package/shared/localization/locales/de.json +96 -444
  144. package/shared/localization/locales/el.json +96 -444
  145. package/shared/localization/locales/en-GB.json +96 -444
  146. package/shared/localization/locales/en-US.json +116 -467
  147. package/shared/localization/locales/en-XA.json +93 -441
  148. package/shared/localization/locales/en-XL.json +116 -467
  149. package/shared/localization/locales/es-419.json +96 -444
  150. package/shared/localization/locales/es.json +96 -444
  151. package/shared/localization/locales/fi.json +96 -444
  152. package/shared/localization/locales/fil.json +96 -444
  153. package/shared/localization/locales/fr.json +96 -444
  154. package/shared/localization/locales/he.json +118 -466
  155. package/shared/localization/locales/hi.json +96 -444
  156. package/shared/localization/locales/hr.json +100 -448
  157. package/shared/localization/locales/hu.json +96 -444
  158. package/shared/localization/locales/id.json +96 -444
  159. package/shared/localization/locales/it.json +96 -444
  160. package/shared/localization/locales/ja.json +96 -444
  161. package/shared/localization/locales/ko.json +97 -445
  162. package/shared/localization/locales/lt.json +96 -444
  163. package/shared/localization/locales/lv.json +97 -445
  164. package/shared/localization/locales/nl.json +96 -444
  165. package/shared/localization/locales/no.json +96 -444
  166. package/shared/localization/locales/pl.json +96 -444
  167. package/shared/localization/locales/pt-PT.json +96 -444
  168. package/shared/localization/locales/pt.json +97 -445
  169. package/shared/localization/locales/ro.json +97 -445
  170. package/shared/localization/locales/ru.json +96 -444
  171. package/shared/localization/locales/sk.json +96 -444
  172. package/shared/localization/locales/sl.json +96 -444
  173. package/shared/localization/locales/sr-Latn.json +96 -444
  174. package/shared/localization/locales/sr.json +96 -444
  175. package/shared/localization/locales/sv.json +96 -444
  176. package/shared/localization/locales/ta.json +96 -444
  177. package/shared/localization/locales/te.json +97 -445
  178. package/shared/localization/locales/th.json +96 -444
  179. package/shared/localization/locales/tr.json +96 -444
  180. package/shared/localization/locales/uk.json +96 -444
  181. package/shared/localization/locales/vi.json +96 -444
  182. package/shared/localization/locales/zh-HK.json +96 -444
  183. package/shared/localization/locales/zh-TW.json +97 -445
  184. package/shared/localization/locales/zh.json +96 -444
  185. package/shared/localization/locales.d.ts +2 -0
  186. package/shared/localization/locales.js +130 -139
  187. package/shared/tsconfig.json +2 -0
  188. package/tsconfig-base.json +2 -2
  189. package/tsconfig.json +1 -4
  190. package/types/artifacts.d.ts +6 -81
  191. package/types/audit.d.ts +1 -1
  192. package/types/lhr/settings.d.ts +1 -1
  193. package/core/audits/byte-efficiency/duplicated-javascript.d.ts +0 -45
  194. package/core/audits/byte-efficiency/duplicated-javascript.js +0 -223
  195. package/core/audits/byte-efficiency/efficient-animated-content.d.ts +0 -22
  196. package/core/audits/byte-efficiency/efficient-animated-content.js +0 -93
  197. package/core/audits/byte-efficiency/legacy-javascript.d.ts +0 -28
  198. package/core/audits/byte-efficiency/legacy-javascript.js +0 -144
  199. package/core/audits/byte-efficiency/modern-image-formats.d.ts +0 -38
  200. package/core/audits/byte-efficiency/modern-image-formats.js +0 -187
  201. package/core/audits/byte-efficiency/offscreen-images.d.ts +0 -63
  202. package/core/audits/byte-efficiency/offscreen-images.js +0 -240
  203. package/core/audits/byte-efficiency/render-blocking-resources.d.ts +0 -53
  204. package/core/audits/byte-efficiency/render-blocking-resources.js +0 -312
  205. package/core/audits/byte-efficiency/uses-long-cache-ttl.d.ts +0 -59
  206. package/core/audits/byte-efficiency/uses-long-cache-ttl.js +0 -293
  207. package/core/audits/byte-efficiency/uses-optimized-images.d.ts +0 -33
  208. package/core/audits/byte-efficiency/uses-optimized-images.js +0 -146
  209. package/core/audits/byte-efficiency/uses-responsive-images-snapshot.d.ts +0 -16
  210. package/core/audits/byte-efficiency/uses-responsive-images-snapshot.js +0 -106
  211. package/core/audits/byte-efficiency/uses-responsive-images.d.ts +0 -44
  212. package/core/audits/byte-efficiency/uses-responsive-images.js +0 -202
  213. package/core/audits/byte-efficiency/uses-text-compression.d.ts +0 -14
  214. package/core/audits/byte-efficiency/uses-text-compression.js +0 -108
  215. package/core/audits/critical-request-chains.d.ts +0 -44
  216. package/core/audits/critical-request-chains.js +0 -221
  217. package/core/audits/dobetterweb/dom-size.d.ts +0 -32
  218. package/core/audits/dobetterweb/dom-size.js +0 -182
  219. package/core/audits/dobetterweb/no-document-write.d.ts +0 -16
  220. package/core/audits/dobetterweb/no-document-write.js +0 -86
  221. package/core/audits/dobetterweb/uses-http2.d.ts +0 -72
  222. package/core/audits/dobetterweb/uses-http2.js +0 -276
  223. package/core/audits/dobetterweb/uses-passive-event-listeners.d.ts +0 -16
  224. package/core/audits/dobetterweb/uses-passive-event-listeners.js +0 -69
  225. package/core/audits/font-display.d.ts +0 -32
  226. package/core/audits/font-display.js +0 -195
  227. package/core/audits/largest-contentful-paint-element.d.ts +0 -34
  228. package/core/audits/largest-contentful-paint-element.js +0 -181
  229. package/core/audits/lcp-lazy-loaded.d.ts +0 -22
  230. package/core/audits/lcp-lazy-loaded.js +0 -115
  231. package/core/audits/metrics/first-meaningful-paint.d.ts +0 -12
  232. package/core/audits/metrics/first-meaningful-paint.js +0 -47
  233. package/core/audits/preload-fonts.d.ts +0 -25
  234. package/core/audits/preload-fonts.js +0 -97
  235. package/core/audits/prioritize-lcp-image.d.ts +0 -74
  236. package/core/audits/prioritize-lcp-image.js +0 -297
  237. package/core/audits/seo/font-size.d.ts +0 -24
  238. package/core/audits/seo/font-size.js +0 -344
  239. package/core/audits/third-party-facades.d.ts +0 -41
  240. package/core/audits/third-party-facades.js +0 -234
  241. package/core/audits/third-party-summary.d.ts +0 -78
  242. package/core/audits/third-party-summary.js +0 -236
  243. package/core/audits/uses-rel-preconnect.d.ts +0 -37
  244. package/core/audits/uses-rel-preconnect.js +0 -286
  245. package/core/audits/uses-rel-preload.d.ts +0 -57
  246. package/core/audits/uses-rel-preload.js +0 -263
  247. package/core/audits/viewport.d.ts +0 -17
  248. package/core/audits/viewport.js +0 -87
  249. package/core/audits/work-during-interaction.d.ts +0 -81
  250. package/core/audits/work-during-interaction.js +0 -287
  251. package/core/computed/critical-request-chains.d.ts +0 -42
  252. package/core/computed/critical-request-chains.js +0 -143
  253. package/core/computed/viewport-meta.d.ts +0 -37
  254. package/core/computed/viewport-meta.js +0 -71
  255. package/core/gather/gatherers/cache-contents.d.ts +0 -11
  256. package/core/gather/gatherers/cache-contents.js +0 -56
  257. package/core/gather/gatherers/devtools-log-compat.d.ts +0 -13
  258. package/core/gather/gatherers/devtools-log-compat.js +0 -35
  259. package/core/gather/gatherers/dobetterweb/domstats.d.ts +0 -10
  260. package/core/gather/gatherers/dobetterweb/domstats.js +0 -102
  261. package/core/gather/gatherers/dobetterweb/optimized-images.d.ts +0 -48
  262. package/core/gather/gatherers/dobetterweb/optimized-images.js +0 -169
  263. package/core/gather/gatherers/dobetterweb/response-compression.d.ts +0 -23
  264. package/core/gather/gatherers/dobetterweb/response-compression.js +0 -136
  265. package/core/gather/gatherers/seo/font-size.d.ts +0 -131
  266. package/core/gather/gatherers/seo/font-size.js +0 -347
  267. package/core/gather/gatherers/trace-compat.d.ts +0 -13
  268. package/core/gather/gatherers/trace-compat.js +0 -35
  269. package/types/internal/metaviewport-parser.d.ts +0 -13
  270. package/types/internal/parse-cache-control.d.ts +0 -20
@@ -1,276 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2016 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- /**
8
- * @fileoverview Audit a page to ensure that resource loaded over its own
9
- * origin are over the http/2 protocol.
10
- */
11
-
12
- import {Audit} from '../audit.js';
13
- import {EntityClassification} from '../../computed/entity-classification.js';
14
- import UrlUtils from '../../lib/url-utils.js';
15
- import {NetworkRequest} from '../../lib/network-request.js';
16
- import {NetworkRecords} from '../../computed/network-records.js';
17
- import {LoadSimulator} from '../../computed/load-simulator.js';
18
- import {LanternLargestContentfulPaint} from '../../computed/metrics/lantern-largest-contentful-paint.js';
19
- import {LanternFirstContentfulPaint} from '../../computed/metrics/lantern-first-contentful-paint.js';
20
- import * as i18n from '../../lib/i18n/i18n.js';
21
-
22
- const UIStrings = {
23
- /** Imperative title of a Lighthouse audit that tells the user to enable HTTP/2. This is displayed in a list of audit titles that Lighthouse generates. */
24
- title: 'Use HTTP/2',
25
- /** Description of a Lighthouse audit that tells the user why they should use HTTP/2. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
26
- description: 'HTTP/2 offers many benefits over HTTP/1.1, including binary headers and ' +
27
- 'multiplexing. [Learn more about HTTP/2](https://developer.chrome.com/docs/lighthouse/best-practices/uses-http2/).',
28
- /** [ICU Syntax] Label identifying the number of network requests that were not served with HTTP/2. */
29
- displayValue: `{itemCount, plural,
30
- =1 {1 request not served via HTTP/2}
31
- other {# requests not served via HTTP/2}
32
- }`,
33
- /** Label for a column in a data table; entries in the column will be the HTTP Protocol used to make a network request. */
34
- columnProtocol: 'Protocol',
35
- };
36
-
37
- const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
38
-
39
- /** @type {Set<LH.Artifacts.NetworkRequest['resourceType']>} */
40
- const STATIC_RESOURCE_TYPES = new Set([
41
- NetworkRequest.TYPES.Document,
42
- NetworkRequest.TYPES.Font,
43
- NetworkRequest.TYPES.Image,
44
- NetworkRequest.TYPES.Stylesheet,
45
- NetworkRequest.TYPES.Script,
46
- NetworkRequest.TYPES.Media,
47
- ]);
48
-
49
- class UsesHTTP2Audit extends Audit {
50
- /**
51
- * @return {LH.Audit.Meta}
52
- */
53
- static get meta() {
54
- return {
55
- id: 'uses-http2',
56
- title: str_(UIStrings.title),
57
- description: str_(UIStrings.description),
58
- scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
59
- guidanceLevel: 3,
60
- supportedModes: ['timespan', 'navigation'],
61
- requiredArtifacts: ['URL', 'DevtoolsLog', 'Trace', 'GatherContext', 'SourceMaps'],
62
- };
63
- }
64
-
65
- /**
66
- * Computes the estimated effect of all results being converted to http/2 on the provided graph.
67
- *
68
- * @param {Array<{url: string}>} results
69
- * @param {LH.Gatherer.Simulation.GraphNode} graph
70
- * @param {LH.Gatherer.Simulation.Simulator} simulator
71
- * @param {{label?: string}=} options
72
- * @return {{savings: number, simulationBefore: LH.Gatherer.Simulation.Result, simulationAfter: LH.Gatherer.Simulation.Result}}
73
- */
74
- static computeWasteWithGraph(results, graph, simulator, options) {
75
- options = Object.assign({label: ''}, options);
76
- const beforeLabel = `${this.meta.id}-${options.label}-before`;
77
- const afterLabel = `${this.meta.id}-${options.label}-after`;
78
-
79
- const urlsToChange = new Set(results.map(result => result.url));
80
- const simulationBefore = simulator.simulate(graph, {label: beforeLabel});
81
-
82
- // Update all the protocols to reflect implementing our recommendations
83
- /** @type {Map<string, string>} */
84
- const originalProtocols = new Map();
85
- graph.traverse(node => {
86
- if (node.type !== 'network') return;
87
- if (!urlsToChange.has(node.request.url)) return;
88
-
89
- originalProtocols.set(node.request.requestId, node.request.protocol);
90
- node.request.protocol = 'h2';
91
- });
92
-
93
- const simulationAfter = simulator.simulate(graph, {label: afterLabel});
94
-
95
- // Restore the original protocol after we've done our simulation
96
- graph.traverse(node => {
97
- if (node.type !== 'network') return;
98
- const originalProtocol = originalProtocols.get(node.request.requestId);
99
- if (originalProtocol === undefined) return;
100
- node.request.protocol = originalProtocol;
101
- });
102
-
103
- const savings = simulationBefore.timeInMs - simulationAfter.timeInMs;
104
-
105
- return {
106
- // Round waste to nearest 10ms
107
- savings: Math.round(Math.max(savings, 0) / 10) * 10,
108
- simulationBefore,
109
- simulationAfter,
110
- };
111
- }
112
-
113
- /**
114
- * Determines whether a network request is a "static resource" that would benefit from H2 multiplexing.
115
- * XHRs, tracking pixels, etc generally don't benefit as much because they aren't requested en-masse
116
- * for the same origin at the exact same time.
117
- *
118
- * @param {LH.Artifacts.NetworkRequest} networkRequest
119
- * @param {LH.Artifacts.EntityClassification} classifiedEntities
120
- * @return {boolean}
121
- */
122
- static isMultiplexableStaticAsset(networkRequest, classifiedEntities) {
123
- if (!STATIC_RESOURCE_TYPES.has(networkRequest.resourceType)) return false;
124
-
125
- // Resources from third-parties that are less than 100 bytes are usually tracking pixels, not actual resources.
126
- // They can masquerade as static types though (gifs, documents, etc)
127
- if (networkRequest.resourceSize < 100) {
128
- const entity = classifiedEntities.entityByUrl.get(networkRequest.url);
129
- if (entity) {
130
- // Third-party assets are multiplexable in their first-party context.
131
- if (classifiedEntities.firstParty?.name === entity.name) return true;
132
- // Skip recognizable third-parties' requests.
133
- if (!entity.isUnrecognized) return false;
134
- }
135
- }
136
-
137
- return true;
138
- }
139
-
140
- /**
141
- * Determine the set of resources that aren't HTTP/2 but should be.
142
- * We're a little conservative about what we surface for a few reasons:
143
- *
144
- * - The simulator approximation of HTTP/2 is a little more generous than reality.
145
- * - There's a bit of debate surrounding HTTP/2 due to its worse performance in environments with high packet loss.**
146
- * - It's something that you'd have absolutely zero control over with a third-party (can't defer to fix it for example).
147
- *
148
- * Therefore, we only surface requests that were...
149
- *
150
- * - Served over HTTP/1.1 or earlier
151
- * - Served over an origin that serves at least 6 static asset requests
152
- * (if there aren't more requests than browser's max/host, multiplexing isn't as big a deal)
153
- * - Not served on localhost (h2 is a pain to deal with locally & and CI)
154
- *
155
- * ** = https://news.ycombinator.com/item?id=19086639
156
- * https://www.twilio.com/blog/2017/10/http2-issues.html
157
- * https://www.cachefly.com/http-2-is-not-a-magic-bullet/
158
- *
159
- * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
160
- * @param {LH.Artifacts.EntityClassification} classifiedEntities
161
- * @return {Array<{url: string, protocol: string}>}
162
- */
163
- static determineNonHttp2Resources(networkRecords, classifiedEntities) {
164
- /** @type {Array<{url: string, protocol: string}>} */
165
- const nonHttp2Resources = [];
166
-
167
- /** @type {Set<string>} */
168
- const seenURLs = new Set();
169
- /** @type {Map<string, Array<LH.Artifacts.NetworkRequest>>} */
170
- const groupedByOrigin = new Map();
171
- for (const record of networkRecords) {
172
- if (!UsesHTTP2Audit.isMultiplexableStaticAsset(record, classifiedEntities)) continue;
173
- if (UrlUtils.isLikeLocalhost(record.parsedURL.host)) continue;
174
- const existing = groupedByOrigin.get(record.parsedURL.securityOrigin) || [];
175
- existing.push(record);
176
- groupedByOrigin.set(record.parsedURL.securityOrigin, existing);
177
- }
178
-
179
- for (const record of networkRecords) {
180
- // Skip duplicates.
181
- if (seenURLs.has(record.url)) continue;
182
- // Check if record is not served through the service worker, servicer worker uses http/1.1 as a protocol.
183
- // These can generate false positives (bug: https://github.com/GoogleChrome/lighthouse/issues/7158).
184
- if (record.fetchedViaServiceWorker) continue;
185
- // Test the protocol to see if it was http/1.1.
186
- const isOldHttp = /HTTP\/[01][.\d]?/i.test(record.protocol);
187
- if (!isOldHttp) continue;
188
- // Check if the origin has enough requests to bother flagging.
189
- const group = groupedByOrigin.get(record.parsedURL.securityOrigin) || [];
190
- if (group.length < 6) continue;
191
-
192
- seenURLs.add(record.url);
193
- nonHttp2Resources.push({protocol: record.protocol, url: record.url});
194
- }
195
-
196
- return nonHttp2Resources;
197
- }
198
-
199
- /**
200
- * @param {LH.Artifacts} artifacts
201
- * @param {LH.Audit.Context} context
202
- * @return {Promise<LH.Audit.Product>}
203
- */
204
- static async audit(artifacts, context) {
205
- const devtoolsLog = artifacts.DevtoolsLog;
206
- const URL = artifacts.URL;
207
- const networkRecords = await NetworkRecords.request(devtoolsLog, context);
208
- const classifiedEntities = await EntityClassification.request({URL, devtoolsLog}, context);
209
- const resources = UsesHTTP2Audit.determineNonHttp2Resources(networkRecords, classifiedEntities);
210
-
211
- let displayValue;
212
- if (resources.length > 0) {
213
- displayValue = str_(UIStrings.displayValue, {itemCount: resources.length});
214
- }
215
-
216
- // TODO: Compute actual savings for timespan mode.
217
- if (artifacts.GatherContext.gatherMode === 'timespan') {
218
- /** @type {LH.Audit.Details.Table['headings']} */
219
- const headings = [
220
- {key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL)},
221
- {key: 'protocol', valueType: 'text', label: str_(UIStrings.columnProtocol)},
222
- ];
223
-
224
- const details = Audit.makeTableDetails(headings, resources);
225
-
226
- return {
227
- displayValue,
228
- score: resources.length ? 0 : 1,
229
- details,
230
- };
231
- }
232
-
233
- const settings = context?.settings || {};
234
- const simulatorOptions = {
235
- devtoolsLog,
236
- settings,
237
- };
238
- const simulator = await LoadSimulator.request(simulatorOptions, context);
239
- const metricComputationInput = Audit.makeMetricComputationDataInput(artifacts, context);
240
-
241
- const {
242
- pessimisticGraph: fcpGraph,
243
- } = await LanternFirstContentfulPaint.request(metricComputationInput, context);
244
- const {
245
- pessimisticGraph: lcpGraph,
246
- } = await LanternLargestContentfulPaint.request(metricComputationInput, context);
247
-
248
- const wasteFcp =
249
- UsesHTTP2Audit.computeWasteWithGraph(resources,
250
- fcpGraph, simulator, {label: 'fcp'});
251
- const wasteLcp =
252
- UsesHTTP2Audit.computeWasteWithGraph(resources,
253
- lcpGraph, simulator, {label: 'lcp'});
254
-
255
- /** @type {LH.Audit.Details.Opportunity['headings']} */
256
- const headings = [
257
- {key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL)},
258
- {key: 'protocol', valueType: 'text', label: str_(UIStrings.columnProtocol)},
259
- ];
260
-
261
- const details = Audit.makeOpportunityDetails(headings, resources,
262
- {overallSavingsMs: wasteLcp.savings});
263
-
264
- return {
265
- displayValue,
266
- numericValue: wasteLcp.savings,
267
- numericUnit: 'millisecond',
268
- score: resources.length ? 0 : 1,
269
- details,
270
- metricSavings: {LCP: wasteLcp.savings, FCP: wasteFcp.savings},
271
- };
272
- }
273
- }
274
-
275
- export default UsesHTTP2Audit;
276
- export {UIStrings};
@@ -1,16 +0,0 @@
1
- export default PassiveEventsAudit;
2
- declare class PassiveEventsAudit extends ViolationAudit {
3
- /**
4
- * @param {LH.Artifacts} artifacts
5
- * @param {LH.Audit.Context} context
6
- * @return {Promise<LH.Audit.Product>}
7
- */
8
- static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
9
- }
10
- export namespace UIStrings {
11
- let title: string;
12
- let failureTitle: string;
13
- let description: string;
14
- }
15
- import ViolationAudit from '../violation-audit.js';
16
- //# sourceMappingURL=uses-passive-event-listeners.d.ts.map
@@ -1,69 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2016 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- /**
8
- * @fileoverview Audit a page to see if it is using passive event listeners on
9
- * scroll-blocking touch and wheel event listeners.
10
- */
11
-
12
-
13
- import ViolationAudit from '../violation-audit.js';
14
- import * as i18n from '../../lib/i18n/i18n.js';
15
-
16
- const UIStrings = {
17
- /** Title of a Lighthouse audit that provides detail on the page's use of passive event listeners used to improve the scrolling performance of the page. This descriptive title is shown to users when the page does use passive listeners. */
18
- title: 'Uses passive listeners to improve scrolling performance',
19
- /** Title of a Lighthouse audit that provides detail on the page's use of passive event listeners used to improve the scrolling performance of the page. This descriptive title is shown to users when the page does not use passive listeners. */
20
- failureTitle: 'Does not use passive listeners to improve scrolling performance',
21
- /** Description of a Lighthouse audit that tells the user why they should use passive event listeners on the page. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
22
- description: 'Consider marking your touch and wheel event listeners as `passive` ' +
23
- 'to improve your page\'s scroll performance. ' +
24
- '[Learn more about adopting passive event listeners](https://developer.chrome.com/docs/lighthouse/best-practices/uses-passive-event-listeners/).',
25
- };
26
-
27
- const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
28
-
29
- class PassiveEventsAudit extends ViolationAudit {
30
- /**
31
- * @return {LH.Audit.Meta}
32
- */
33
- static get meta() {
34
- return {
35
- id: 'uses-passive-event-listeners',
36
- title: str_(UIStrings.title),
37
- failureTitle: str_(UIStrings.failureTitle),
38
- description: str_(UIStrings.description),
39
- guidanceLevel: 3,
40
- requiredArtifacts: ['ConsoleMessages', 'SourceMaps', 'Scripts'],
41
- scoreDisplayMode: ViolationAudit.SCORING_MODES.METRIC_SAVINGS,
42
- };
43
- }
44
-
45
- /**
46
- * @param {LH.Artifacts} artifacts
47
- * @param {LH.Audit.Context} context
48
- * @return {Promise<LH.Audit.Product>}
49
- */
50
- static async audit(artifacts, context) {
51
- const results =
52
- await ViolationAudit.getViolationResults(artifacts, context, /passive event listener/);
53
-
54
- /** @type {LH.Audit.Details.Table['headings']} */
55
- const headings = [
56
- {key: 'source', valueType: 'source-location', label: str_(i18n.UIStrings.columnSource)},
57
- ];
58
- // TODO(bckenny): see TODO in geolocation-on-start
59
- const details = ViolationAudit.makeTableDetails(headings, results);
60
-
61
- return {
62
- score: Number(results.length === 0),
63
- details,
64
- };
65
- }
66
- }
67
-
68
- export default PassiveEventsAudit;
69
- export {UIStrings};
@@ -1,32 +0,0 @@
1
- export default FontDisplay;
2
- declare class FontDisplay extends Audit {
3
- /**
4
- * @param {LH.Artifacts} artifacts
5
- * @param {RegExp} passingFontDisplayRegex
6
- * @return {{passingURLs: Set<string>, failingURLs: Set<string>}}
7
- */
8
- static findFontDisplayDeclarations(artifacts: LH.Artifacts, passingFontDisplayRegex: RegExp): {
9
- passingURLs: Set<string>;
10
- failingURLs: Set<string>;
11
- };
12
- /**
13
- * Some pages load many fonts we can't check, so dedupe on origin.
14
- * @param {Array<string>} warningUrls
15
- * @return {Array<LH.IcuMessage>}
16
- */
17
- static getWarningsForFontUrls(warningUrls: Array<string>): Array<LH.IcuMessage>;
18
- /**
19
- * @param {LH.Artifacts} artifacts
20
- * @param {LH.Audit.Context} context
21
- * @return {Promise<LH.Audit.Product>}
22
- */
23
- static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
24
- }
25
- export namespace UIStrings {
26
- let title: string;
27
- let failureTitle: string;
28
- let description: string;
29
- let undeclaredFontOriginWarning: string;
30
- }
31
- import { Audit } from './audit.js';
32
- //# sourceMappingURL=font-display.d.ts.map
@@ -1,195 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2017 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- import {Audit} from './audit.js';
8
- import UrlUtils from '../lib/url-utils.js';
9
- import * as i18n from '../lib/i18n/i18n.js';
10
- import {Sentry} from '../lib/sentry.js';
11
- import {NetworkRecords} from '../computed/network-records.js';
12
-
13
- const PASSING_FONT_DISPLAY_REGEX = /^(block|fallback|optional|swap)$/;
14
- const CSS_URL_REGEX = /url\((.*?)\)/;
15
- const CSS_URL_GLOBAL_REGEX = new RegExp(CSS_URL_REGEX, 'g');
16
-
17
- const UIStrings = {
18
- /** Title of a diagnostic audit that provides detail on if all the text on a webpage was visible while the page was loading its webfonts. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
19
- title: 'All text remains visible during webfont loads',
20
- /** Title of a diagnostic audit that provides detail on the load of the page's webfonts. Often the text is invisible for seconds before the webfont resource is loaded. This imperative title is shown to users when there is a significant amount of execution time that could be reduced. */
21
- failureTitle: 'Ensure text remains visible during webfont load',
22
- /** Description of a Lighthouse audit that tells the user *why* they should use the font-display CSS feature. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
23
- description:
24
- 'Leverage the `font-display` CSS feature to ensure text is user-visible while ' +
25
- 'webfonts are loading. ' +
26
- '[Learn more about `font-display`](https://developer.chrome.com/docs/lighthouse/performance/font-display/).',
27
- /**
28
- * @description [ICU Syntax] A warning message that is shown when Lighthouse couldn't automatically check some of the page's fonts, telling the user that they will need to manually check the fonts coming from a certain URL origin.
29
- * @example {https://font.cdn.com/} fontOrigin
30
- */
31
- undeclaredFontOriginWarning:
32
- '{fontCountForOrigin, plural, ' +
33
- // eslint-disable-next-line max-len
34
- '=1 {Lighthouse was unable to automatically check the `font-display` value for the origin {fontOrigin}.} ' +
35
- // eslint-disable-next-line max-len
36
- 'other {Lighthouse was unable to automatically check the `font-display` values for the origin {fontOrigin}.}}',
37
- };
38
-
39
- const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
40
-
41
- class FontDisplay extends Audit {
42
- /**
43
- * @return {LH.Audit.Meta}
44
- */
45
- static get meta() {
46
- return {
47
- id: 'font-display',
48
- title: str_(UIStrings.title),
49
- failureTitle: str_(UIStrings.failureTitle),
50
- description: str_(UIStrings.description),
51
- supportedModes: ['navigation'],
52
- guidanceLevel: 3,
53
- requiredArtifacts: ['DevtoolsLog', 'Stylesheets', 'URL'],
54
- scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
55
- };
56
- }
57
-
58
- /**
59
- * @param {LH.Artifacts} artifacts
60
- * @param {RegExp} passingFontDisplayRegex
61
- * @return {{passingURLs: Set<string>, failingURLs: Set<string>}}
62
- */
63
- static findFontDisplayDeclarations(artifacts, passingFontDisplayRegex) {
64
- /** @type {Set<string>} */
65
- const passingURLs = new Set();
66
- /** @type {Set<string>} */
67
- const failingURLs = new Set();
68
-
69
- // Go through all the stylesheets to find all @font-face declarations
70
- for (const stylesheet of artifacts.Stylesheets) {
71
- // Eliminate newlines so we can more easily scan through with a regex
72
- const newlinesStripped = stylesheet.content.replace(/(\r|\n)+/g, ' ');
73
- // Find the @font-faces
74
- const fontFaceDeclarations = newlinesStripped.match(/@font-face\s*{(.*?)}/g) || [];
75
- // Go through all the @font-face declarations to find a declared `font-display: ` property
76
- for (const declaration of fontFaceDeclarations) {
77
- // We'll try to find the URL it's referencing.
78
- const rawFontURLs = declaration.match(CSS_URL_GLOBAL_REGEX);
79
- // If no URLs, we can't really do anything; bail
80
- if (!rawFontURLs) continue;
81
- // Find the font-display value by matching a single token, optionally surrounded by whitespace,
82
- // followed either by a semicolon or the end of a block.
83
- const fontDisplayMatch = declaration.match(/font-display\s*:\s*(\w+)\s*(;|\})/);
84
- const rawFontDisplay = fontDisplayMatch?.[1] || '';
85
- const hasPassingFontDisplay = passingFontDisplayRegex.test(rawFontDisplay);
86
- const targetURLSet = hasPassingFontDisplay ? passingURLs : failingURLs;
87
-
88
- // Finally convert the raw font URLs to the absolute URLs and add them to the set.
89
- const relativeURLs = rawFontURLs
90
- // @ts-expect-error - guaranteed to match from previous regex, pull URL group out
91
- .map(s => s.match(CSS_URL_REGEX)[1].trim())
92
- .map(s => {
93
- // remove any quotes surrounding the URL
94
- if (/^('|").*\1$/.test(s)) {
95
- return s.substr(1, s.length - 2);
96
- }
97
-
98
- return s;
99
- });
100
-
101
- // Convert the relative CSS URL to an absolute URL and add it to the target set.
102
- for (const relativeURL of relativeURLs) {
103
- try {
104
- const relativeRoot = UrlUtils.isValid(stylesheet.header.sourceURL) ?
105
- stylesheet.header.sourceURL : artifacts.URL.finalDisplayedUrl;
106
- const absoluteURL = new URL(relativeURL, relativeRoot);
107
- targetURLSet.add(absoluteURL.href);
108
- } catch (err) {
109
- Sentry.captureException(err, {tags: {audit: this.meta.id}});
110
- }
111
- }
112
- }
113
- }
114
-
115
- return {passingURLs, failingURLs};
116
- }
117
-
118
- /**
119
- * Some pages load many fonts we can't check, so dedupe on origin.
120
- * @param {Array<string>} warningUrls
121
- * @return {Array<LH.IcuMessage>}
122
- */
123
- static getWarningsForFontUrls(warningUrls) {
124
- /** @type {Map<string, number>} */
125
- const warningCountByOrigin = new Map();
126
- for (const warningUrl of warningUrls) {
127
- const origin = UrlUtils.getOrigin(warningUrl);
128
- if (!origin) continue;
129
-
130
- const count = warningCountByOrigin.get(origin) || 0;
131
- warningCountByOrigin.set(origin, count + 1);
132
- }
133
-
134
- const warnings = [...warningCountByOrigin].map(([fontOrigin, fontCountForOrigin]) => {
135
- return str_(UIStrings.undeclaredFontOriginWarning, {fontCountForOrigin, fontOrigin});
136
- });
137
- return warnings;
138
- }
139
-
140
- /**
141
- * @param {LH.Artifacts} artifacts
142
- * @param {LH.Audit.Context} context
143
- * @return {Promise<LH.Audit.Product>}
144
- */
145
- static async audit(artifacts, context) {
146
- const devtoolsLogs = artifacts.DevtoolsLog;
147
- const networkRecords = await NetworkRecords.request(devtoolsLogs, context);
148
- const {passingURLs, failingURLs} =
149
- FontDisplay.findFontDisplayDeclarations(artifacts, PASSING_FONT_DISPLAY_REGEX);
150
- /** @type {Array<string>} */
151
- const warningURLs = [];
152
-
153
- const results = networkRecords
154
- // Find all fonts...
155
- .filter(record => record.resourceType === 'Font')
156
- // ...and that aren't data URLs, the blocking concern doesn't really apply
157
- .filter(record => !/^data:/.test(record.url))
158
- .filter(record => !/^blob:/.test(record.url))
159
- // ...that have a failing font-display value
160
- .filter(record => {
161
- // Failing URLs should be considered.
162
- if (failingURLs.has(record.url)) return true;
163
- // Everything else shouldn't be, but we should warn if we don't recognize the URL at all.
164
- if (!passingURLs.has(record.url)) warningURLs.push(record.url);
165
- return false;
166
- })
167
- .map(record => {
168
- // In reality the end time should be calculated with paint time included
169
- // all browsers wait 3000ms to block text so we make sure 3000 is our max wasted time
170
- const wastedMs = Math.min(record.networkEndTime - record.networkRequestTime, 3000);
171
-
172
- return {
173
- url: record.url,
174
- wastedMs,
175
- };
176
- });
177
-
178
- /** @type {LH.Audit.Details.Table['headings']} */
179
- const headings = [
180
- {key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL)},
181
- {key: 'wastedMs', valueType: 'ms', label: str_(i18n.UIStrings.columnWastedMs)},
182
- ];
183
-
184
- const details = Audit.makeTableDetails(headings, results);
185
-
186
- return {
187
- score: Number(results.length === 0),
188
- details,
189
- warnings: FontDisplay.getWarningsForFontUrls(warningURLs),
190
- };
191
- }
192
- }
193
-
194
- export default FontDisplay;
195
- export {UIStrings};
@@ -1,34 +0,0 @@
1
- export default LargestContentfulPaintElement;
2
- declare class LargestContentfulPaintElement extends Audit {
3
- /**
4
- * @param {LH.Artifacts} artifacts
5
- * @return {LH.Audit.Details.Table|undefined}
6
- */
7
- static makeElementTable(artifacts: LH.Artifacts): LH.Audit.Details.Table | undefined;
8
- /**
9
- * @param {number} metricLcp
10
- * @param {LH.Artifacts.MetricComputationDataInput} metricComputationData
11
- * @param {LH.Audit.Context} context
12
- * @return {Promise<LH.Audit.Details.Table>}
13
- */
14
- static makePhaseTable(metricLcp: number, metricComputationData: LH.Artifacts.MetricComputationDataInput, context: LH.Audit.Context): Promise<LH.Audit.Details.Table>;
15
- /**
16
- * @param {LH.Artifacts} artifacts
17
- * @param {LH.Audit.Context} context
18
- * @return {Promise<LH.Audit.Product>}
19
- */
20
- static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
21
- }
22
- export namespace UIStrings {
23
- let title: string;
24
- let description: string;
25
- let columnPhase: string;
26
- let columnPercentOfLCP: string;
27
- let columnTiming: string;
28
- let itemTTFB: string;
29
- let itemLoadDelay: string;
30
- let itemLoadTime: string;
31
- let itemRenderDelay: string;
32
- }
33
- import { Audit } from './audit.js';
34
- //# sourceMappingURL=largest-contentful-paint-element.d.ts.map