lighthouse 12.8.2 → 13.0.0-dev.20251009

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,181 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2020 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- import log from 'lighthouse-logger';
8
-
9
- import {Audit} from './audit.js';
10
- import * as i18n from '../lib/i18n/i18n.js';
11
- import {LargestContentfulPaint as LargestContentfulPaintComputed} from '../computed/metrics/largest-contentful-paint.js';
12
- import LargestContentfulPaint from './metrics/largest-contentful-paint.js';
13
- import {LCPBreakdown} from '../computed/metrics/lcp-breakdown.js';
14
- import {Sentry} from '../lib/sentry.js';
15
-
16
- const UIStrings = {
17
- /** Descriptive title of a diagnostic audit that provides the element that was determined to be the Largest Contentful Paint. */
18
- title: 'Largest Contentful Paint element',
19
- /** Description of a Lighthouse audit that tells the user that the element shown was determined to be the Largest Contentful Paint. */
20
- description: 'This is the largest contentful element painted within the viewport. ' +
21
- '[Learn more about the Largest Contentful Paint element](https://developer.chrome.com/docs/lighthouse/performance/lighthouse-largest-contentful-paint/)',
22
- /** Label for a column in a data table; entries will be the name of a phase in the Largest Contentful Paint (LCP) metric. */
23
- columnPhase: 'Phase',
24
- /** Label for a column in a data table; entries will be the percent of Largest Contentful Paint (LCP) that a phase covers. */
25
- columnPercentOfLCP: '% of LCP',
26
- /** Label for a column in a data table; entries will be the amount of time spent in a phase in the Largest Contentful Paint (LCP) metric. */
27
- columnTiming: 'Timing',
28
- /** Table item value for the Time To First Byte (TTFB) phase of the Largest Contentful Paint (LCP) metric. */
29
- itemTTFB: 'TTFB',
30
- /** Table item value for the load delay phase of the Largest Contentful Paint (LCP) metric. */
31
- itemLoadDelay: 'Load Delay',
32
- /** Table item value for the load time phase of the Largest Contentful Paint (LCP) metric. */
33
- itemLoadTime: 'Load Time',
34
- /** Table item value for the render delay phase of the Largest Contentful Paint (LCP) metric. */
35
- itemRenderDelay: 'Render Delay',
36
- };
37
-
38
- const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
39
-
40
- class LargestContentfulPaintElement extends Audit {
41
- /**
42
- * @return {LH.Audit.Meta}
43
- */
44
- static get meta() {
45
- return {
46
- id: 'largest-contentful-paint-element',
47
- title: str_(UIStrings.title),
48
- description: str_(UIStrings.description),
49
- scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
50
- guidanceLevel: 1,
51
- supportedModes: ['navigation'],
52
- requiredArtifacts:
53
- ['Trace', 'TraceElements', 'DevtoolsLog', 'GatherContext', 'settings', 'URL',
54
- 'SourceMaps'],
55
- };
56
- }
57
-
58
- /**
59
- * @param {LH.Artifacts} artifacts
60
- * @return {LH.Audit.Details.Table|undefined}
61
- */
62
- static makeElementTable(artifacts) {
63
- const lcpElement = artifacts.TraceElements
64
- .find(element => element.traceEventType === 'largest-contentful-paint');
65
- if (!lcpElement) return;
66
-
67
- /** @type {LH.Audit.Details.Table['headings']} */
68
- const headings = [
69
- {key: 'node', valueType: 'node', label: str_(i18n.UIStrings.columnElement)},
70
- ];
71
-
72
- const lcpElementDetails = [{node: Audit.makeNodeItem(lcpElement.node)}];
73
-
74
- return Audit.makeTableDetails(headings, lcpElementDetails);
75
- }
76
-
77
- /**
78
- * @param {number} metricLcp
79
- * @param {LH.Artifacts.MetricComputationDataInput} metricComputationData
80
- * @param {LH.Audit.Context} context
81
- * @return {Promise<LH.Audit.Details.Table>}
82
- */
83
- static async makePhaseTable(metricLcp, metricComputationData, context) {
84
- const {ttfb, loadStart, loadEnd} = await LCPBreakdown.request(metricComputationData, context);
85
-
86
- let loadDelay = 0;
87
- let loadTime = 0;
88
- let renderDelay = metricLcp - ttfb;
89
-
90
- if (loadStart && loadEnd) {
91
- loadDelay = loadStart - ttfb;
92
- loadTime = loadEnd - loadStart;
93
- renderDelay = metricLcp - loadEnd;
94
- }
95
-
96
- const results = [
97
- {phase: str_(UIStrings.itemTTFB), timing: ttfb},
98
- {phase: str_(UIStrings.itemLoadDelay), timing: loadDelay},
99
- {phase: str_(UIStrings.itemLoadTime), timing: loadTime},
100
- {phase: str_(UIStrings.itemRenderDelay), timing: renderDelay},
101
- ].map(result => {
102
- const percent = 100 * result.timing / metricLcp;
103
- const percentStr = `${percent.toFixed(0)}%`;
104
- return {...result, percent: percentStr};
105
- });
106
-
107
- /** @type {LH.Audit.Details.Table['headings']} */
108
- const headings = [
109
- {key: 'phase', valueType: 'text', label: str_(UIStrings.columnPhase)},
110
- {key: 'percent', valueType: 'text', label: str_(UIStrings.columnPercentOfLCP)},
111
- {key: 'timing', valueType: 'ms', label: str_(UIStrings.columnTiming)},
112
- ];
113
-
114
- return Audit.makeTableDetails(headings, results);
115
- }
116
-
117
- /**
118
- * @param {LH.Artifacts} artifacts
119
- * @param {LH.Audit.Context} context
120
- * @return {Promise<LH.Audit.Product>}
121
- */
122
- static async audit(artifacts, context) {
123
- const trace = artifacts.Trace;
124
- const devtoolsLog = artifacts.DevtoolsLog;
125
- const gatherContext = artifacts.GatherContext;
126
- const metricComputationData = {
127
- trace, devtoolsLog, gatherContext,
128
- settings: context.settings, URL: artifacts.URL,
129
- SourceMaps: artifacts.SourceMaps, simulator: null,
130
- };
131
-
132
- const elementTable = this.makeElementTable(artifacts);
133
- if (!elementTable) {
134
- return {
135
- score: null,
136
- notApplicable: true,
137
- metricSavings: {LCP: 0},
138
- };
139
- }
140
-
141
- const items = [elementTable];
142
- let displayValue;
143
- let metricLcp = 0;
144
-
145
- try {
146
- const lcpResult =
147
- await LargestContentfulPaintComputed.request(metricComputationData, context);
148
- metricLcp = lcpResult.timing;
149
- displayValue = str_(i18n.UIStrings.ms, {timeInMs: metricLcp});
150
-
151
- const phaseTable = await this.makePhaseTable(metricLcp, metricComputationData, context);
152
- items.push(phaseTable);
153
- } catch (err) {
154
- Sentry.captureException(err, {
155
- tags: {audit: this.meta.id},
156
- level: 'error',
157
- });
158
- log.error(this.meta.id, err.message);
159
- }
160
-
161
- const details = Audit.makeListDetails(items);
162
-
163
- // Conceptually, this doesn't make much sense as "savings" for this audit since there isn't anything to "fix".
164
- // However, this audit will always be useful when improving LCP and that should be reflected in our impact calculations.
165
- const idealLcp = LargestContentfulPaint.defaultOptions[context.settings.formFactor].scoring.p10;
166
- const lcpSavings = Math.max(0, metricLcp - idealLcp);
167
-
168
- return {
169
- score: lcpSavings ? 0 : 1,
170
- scoreDisplayMode: lcpSavings ? undefined : Audit.SCORING_MODES.INFORMATIVE,
171
- displayValue,
172
- details,
173
- metricSavings: {
174
- LCP: lcpSavings,
175
- },
176
- };
177
- }
178
- }
179
-
180
- export default LargestContentfulPaintElement;
181
- export {UIStrings};
@@ -1,22 +0,0 @@
1
- export default LargestContentfulPaintLazyLoaded;
2
- declare class LargestContentfulPaintLazyLoaded extends Audit {
3
- /**
4
- * @param {LH.Artifacts.ImageElement} image
5
- * @param {LH.Artifacts.ViewportDimensions} viewportDimensions
6
- * @return {boolean}
7
- */
8
- static isImageInViewport(image: LH.Artifacts.ImageElement, viewportDimensions: LH.Artifacts.ViewportDimensions): boolean;
9
- /**
10
- * @param {LH.Artifacts} artifacts
11
- * @param {LH.Audit.Context} context
12
- * @return {Promise<LH.Audit.Product>}
13
- */
14
- static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
15
- }
16
- export namespace UIStrings {
17
- let title: string;
18
- let failureTitle: string;
19
- let description: string;
20
- }
21
- import { Audit } from './audit.js';
22
- //# sourceMappingURL=lcp-lazy-loaded.d.ts.map
@@ -1,115 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2021 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- import {Audit} from './audit.js';
8
- import * as i18n from '../lib/i18n/i18n.js';
9
- import {LCPBreakdown} from '../computed/metrics/lcp-breakdown.js';
10
- import {LargestContentfulPaint} from '../computed/metrics/largest-contentful-paint.js';
11
-
12
- const UIStrings = {
13
- /** Title of a Lighthouse audit that provides detail on whether the largest above-the-fold image was loaded with sufficient priority. This descriptive title is shown to users when the image was loaded properly. */
14
- title: 'Largest Contentful Paint image was not lazily loaded',
15
- /** Title of a Lighthouse audit that provides detail on whether the largest above-the-fold image was loaded with sufficient priority. This descriptive title is shown to users when the image was loaded inefficiently using the `loading=lazy` attribute. */
16
- failureTitle: 'Largest Contentful Paint image was lazily loaded',
17
- /** Description of a Lighthouse audit that tells the user why the advice is important. This is displayed after a user expands the section to see more. No character length limits. */
18
- description: 'Above-the-fold images that are lazily loaded render later in the page lifecycle, which can delay the largest contentful paint. [Learn more about optimal lazy loading](https://web.dev/articles/lcp-lazy-loading).',
19
- };
20
-
21
- const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
22
-
23
- const ESTIMATED_PERCENT_SAVINGS = 0.15;
24
-
25
- class LargestContentfulPaintLazyLoaded extends Audit {
26
- /**
27
- * @return {LH.Audit.Meta}
28
- */
29
- static get meta() {
30
- return {
31
- id: 'lcp-lazy-loaded',
32
- title: str_(UIStrings.title),
33
- failureTitle: str_(UIStrings.failureTitle),
34
- description: str_(UIStrings.description),
35
- supportedModes: ['navigation'],
36
- scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
37
- guidanceLevel: 3,
38
- requiredArtifacts: ['TraceElements', 'ViewportDimensions', 'ImageElements',
39
- 'Trace', 'DevtoolsLog', 'GatherContext', 'URL', 'SourceMaps'],
40
- };
41
- }
42
-
43
- /**
44
- * @param {LH.Artifacts.ImageElement} image
45
- * @param {LH.Artifacts.ViewportDimensions} viewportDimensions
46
- * @return {boolean}
47
- */
48
- static isImageInViewport(image, viewportDimensions) {
49
- const imageTop = image.clientRect.top;
50
- const viewportHeight = viewportDimensions.innerHeight;
51
- return imageTop < viewportHeight;
52
- }
53
-
54
- /**
55
- * @param {LH.Artifacts} artifacts
56
- * @param {LH.Audit.Context} context
57
- * @return {Promise<LH.Audit.Product>}
58
- */
59
- static async audit(artifacts, context) {
60
- const lcpElement = artifacts.TraceElements.find(element => {
61
- return element.traceEventType === 'largest-contentful-paint' && element.type === 'image';
62
- });
63
- const lcpElementImage = lcpElement ? artifacts.ImageElements.find(elem => {
64
- return elem.node.devtoolsNodePath === lcpElement.node.devtoolsNodePath;
65
- }) : undefined;
66
-
67
-
68
- if (!lcpElementImage ||
69
- !this.isImageInViewport(lcpElementImage, artifacts.ViewportDimensions)) {
70
- return {
71
- score: null,
72
- notApplicable: true,
73
- metricSavings: {LCP: 0},
74
- };
75
- }
76
-
77
- /** @type {LH.Audit.Details.Table['headings']} */
78
- const headings = [
79
- {key: 'node', valueType: 'node', label: str_(i18n.UIStrings.columnElement)},
80
- ];
81
-
82
- const details = Audit.makeTableDetails(headings, [
83
- {
84
- node: Audit.makeNodeItem(lcpElementImage.node),
85
- },
86
- ]);
87
-
88
- const wasLazyLoaded = lcpElementImage.loading === 'lazy';
89
-
90
- const metricComputationData = Audit.makeMetricComputationDataInput(artifacts, context);
91
- const {timing: metricLcp} =
92
- await LargestContentfulPaint.request(metricComputationData, context);
93
- const lcpBreakdown = await LCPBreakdown.request(metricComputationData, context);
94
- let lcpSavings = 0;
95
- if (wasLazyLoaded && lcpBreakdown.loadStart !== undefined) {
96
- // Estimate the LCP savings using a statistical percentage.
97
- // https://web.dev/articles/lcp-lazy-loading#causal_performance
98
- //
99
- // LCP savings will be at most the LCP load delay.
100
- const lcpLoadDelay = lcpBreakdown.loadStart - lcpBreakdown.ttfb;
101
- lcpSavings = Math.min(metricLcp * ESTIMATED_PERCENT_SAVINGS, lcpLoadDelay);
102
- }
103
-
104
- return {
105
- score: wasLazyLoaded ? 0 : 1,
106
- metricSavings: {
107
- LCP: lcpSavings,
108
- },
109
- details,
110
- };
111
- }
112
- }
113
-
114
- export default LargestContentfulPaintLazyLoaded;
115
- export {UIStrings};
@@ -1,12 +0,0 @@
1
- export default FirstMeaningfulPaint;
2
- declare class FirstMeaningfulPaint extends Audit {
3
- /**
4
- * @return {Promise<LH.Audit.Product>}
5
- */
6
- static audit(): Promise<LH.Audit.Product>;
7
- }
8
- export namespace UIStrings {
9
- let description: string;
10
- }
11
- import { Audit } from '../audit.js';
12
- //# sourceMappingURL=first-meaningful-paint.d.ts.map
@@ -1,47 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2016 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- // TODO(COMPAT): This is just a shell. Remove in future breaking release.
8
-
9
- import {Audit} from '../audit.js';
10
- import * as i18n from '../../lib/i18n/i18n.js';
11
-
12
- const UIStrings = {
13
- /** Description of the First Meaningful Paint (FMP) metric, which marks the time at which a majority of the content has been painted by the browser. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
14
- description: 'First Meaningful Paint measures when the primary content of a page is ' +
15
- 'visible. [Learn more about the First Meaningful Paint metric](https://developer.chrome.com/docs/lighthouse/performance/first-meaningful-paint/).',
16
- };
17
-
18
- const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
19
-
20
- class FirstMeaningfulPaint extends Audit {
21
- /**
22
- * @return {LH.Audit.Meta}
23
- */
24
- static get meta() {
25
- return {
26
- id: 'first-meaningful-paint',
27
- title: str_(i18n.UIStrings.firstMeaningfulPaintMetric),
28
- description: str_(UIStrings.description),
29
- scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
30
- supportedModes: ['navigation'],
31
- requiredArtifacts: ['Trace', 'DevtoolsLog', 'GatherContext', 'URL'],
32
- };
33
- }
34
-
35
- /**
36
- * @return {Promise<LH.Audit.Product>}
37
- */
38
- static async audit() {
39
- return {
40
- score: null,
41
- notApplicable: true,
42
- };
43
- }
44
- }
45
-
46
- export default FirstMeaningfulPaint;
47
- export {UIStrings};
@@ -1,25 +0,0 @@
1
- export default PreloadFontsAudit;
2
- declare class PreloadFontsAudit extends Audit {
3
- /**
4
- * Finds which font URLs were attempted to be preloaded,
5
- * ignoring those that failed to be reused and were requested again.
6
- * Note: document.fonts.load() is a valid way to preload fonts,
7
- * but we are not currently checking for that.
8
- * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
9
- * @return {Set<string>}
10
- */
11
- static getURLsAttemptedToPreload(networkRecords: Array<LH.Artifacts.NetworkRequest>): Set<string>;
12
- /**
13
- * @param {LH.Artifacts} artifacts
14
- * @param {LH.Audit.Context} context
15
- * @return {Promise<LH.Audit.Product>}
16
- */
17
- static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
18
- }
19
- export namespace UIStrings {
20
- let title: string;
21
- let failureTitle: string;
22
- let description: string;
23
- }
24
- import { Audit } from './audit.js';
25
- //# sourceMappingURL=preload-fonts.d.ts.map
@@ -1,97 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2020 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- /**
8
- * @fileoverview
9
- * Audit that checks whether fonts that use `font-display: optional` were preloaded.
10
- */
11
-
12
- import {Audit} from './audit.js';
13
- import * as i18n from './../lib/i18n/i18n.js';
14
- import FontDisplay from './../audits/font-display.js';
15
- const PASSING_FONT_DISPLAY_REGEX = /^(optional)$/;
16
- import {NetworkRecords} from '../computed/network-records.js';
17
-
18
- const UIStrings = {
19
- /** Title of a Lighthouse audit that provides detail on whether fonts that used `font-display: optional` were preloaded. This descriptive title is shown to users when all fonts that used `font-display: optional` were preloaded. */
20
- title: 'Fonts with `font-display: optional` are preloaded',
21
- /** Title of a Lighthouse audit that provides detail on whether fonts that used `font-display: optional` were preloaded. This descriptive title is shown to users when one or more fonts used `font-display: optional` and were not preloaded. */
22
- failureTitle: 'Fonts with `font-display: optional` are not preloaded',
23
- /** Description of a Lighthouse audit that tells the user why they should preload fonts if they are using `font-display: optional`. 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. */
24
- description: 'Preload `optional` fonts so first-time visitors may use them. [Learn more about preloading fonts](https://web.dev/articles/preload-optional-fonts)',
25
- };
26
-
27
- const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
28
-
29
- class PreloadFontsAudit extends Audit {
30
- /**
31
- * @return {LH.Audit.Meta}
32
- */
33
- static get meta() {
34
- return {
35
- id: 'preload-fonts',
36
- title: str_(UIStrings.title),
37
- failureTitle: str_(UIStrings.failureTitle),
38
- description: str_(UIStrings.description),
39
- requiredArtifacts: ['DevtoolsLog', 'URL', 'CSSUsage', 'Stylesheets'],
40
- };
41
- }
42
-
43
- /**
44
- * Finds which font URLs were attempted to be preloaded,
45
- * ignoring those that failed to be reused and were requested again.
46
- * Note: document.fonts.load() is a valid way to preload fonts,
47
- * but we are not currently checking for that.
48
- * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
49
- * @return {Set<string>}
50
- */
51
- static getURLsAttemptedToPreload(networkRecords) {
52
- const attemptedURLs = networkRecords
53
- .filter(req => req.resourceType === 'Font')
54
- .filter(req => req.isLinkPreload)
55
- .map(req => req.url);
56
-
57
- return new Set(attemptedURLs);
58
- }
59
-
60
- /**
61
- * @param {LH.Artifacts} artifacts
62
- * @param {LH.Audit.Context} context
63
- * @return {Promise<LH.Audit.Product>}
64
- */
65
- static async audit(artifacts, context) {
66
- const devtoolsLog = artifacts.DevtoolsLog;
67
- const networkRecords = await NetworkRecords.request(devtoolsLog, context);
68
-
69
- // Gets the URLs of fonts where font-display: optional.
70
- const optionalFontURLs =
71
- FontDisplay.findFontDisplayDeclarations(artifacts, PASSING_FONT_DISPLAY_REGEX).passingURLs;
72
-
73
- // Gets the URLs of fonts attempted to be preloaded.
74
- const preloadedFontURLs =
75
- PreloadFontsAudit.getURLsAttemptedToPreload(networkRecords);
76
-
77
- const results = Array.from(optionalFontURLs)
78
- .filter(url => !preloadedFontURLs.has(url))
79
- .map(url => {
80
- return {url};
81
- });
82
-
83
- /** @type {LH.Audit.Details.Table['headings']} */
84
- const headings = [
85
- {key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL)},
86
- ];
87
-
88
- return {
89
- score: results.length > 0 ? 0 : 1,
90
- details: Audit.makeTableDetails(headings, results),
91
- notApplicable: optionalFontURLs.size === 0,
92
- };
93
- }
94
- }
95
-
96
- export default PreloadFontsAudit;
97
- export {UIStrings};
@@ -1,74 +0,0 @@
1
- export default PrioritizeLcpImage;
2
- export type InitiatorType = LH.Crdp.Network.Initiator["type"] | "redirect" | "fallbackToMain";
3
- export type InitiatorPath = Array<{
4
- url: string;
5
- initiatorType: InitiatorType;
6
- }>;
7
- /**
8
- * @typedef {LH.Crdp.Network.Initiator['type']|'redirect'|'fallbackToMain'} InitiatorType
9
- * @typedef {Array<{url: string, initiatorType: InitiatorType}>} InitiatorPath
10
- */
11
- declare class PrioritizeLcpImage extends Audit {
12
- /**
13
- *
14
- * @param {LH.Artifacts.NetworkRequest} request
15
- * @param {LH.Artifacts.NetworkRequest} mainResource
16
- * @param {InitiatorPath} initiatorPath
17
- * @return {boolean}
18
- */
19
- static shouldPreloadRequest(request: LH.Artifacts.NetworkRequest, mainResource: LH.Artifacts.NetworkRequest, initiatorPath: InitiatorPath): boolean;
20
- /**
21
- * @param {LH.Gatherer.Simulation.GraphNode} graph
22
- * @param {NetworkRequest} lcpRecord
23
- * @return {LH.Gatherer.Simulation.GraphNetworkNode|undefined}
24
- */
25
- static findLCPNode(graph: LH.Gatherer.Simulation.GraphNode, lcpRecord: NetworkRequest): LH.Gatherer.Simulation.GraphNetworkNode | undefined;
26
- /**
27
- * Get the initiator path starting with lcpRecord back to mainResource, inclusive.
28
- * Navigation redirects *to* the mainResource are not included.
29
- * Path returned will always be at least [lcpRecord, mainResource].
30
- * @param {NetworkRequest} lcpRecord
31
- * @param {NetworkRequest} mainResource
32
- * @return {InitiatorPath}
33
- */
34
- static getLcpInitiatorPath(lcpRecord: NetworkRequest, mainResource: NetworkRequest): InitiatorPath;
35
- /**
36
- * @param {LH.Artifacts.NetworkRequest} mainResource
37
- * @param {LH.Gatherer.Simulation.GraphNode} graph
38
- * @param {NetworkRequest|undefined} lcpRecord
39
- * @return {{lcpNodeToPreload?: LH.Gatherer.Simulation.GraphNetworkNode, initiatorPath?: InitiatorPath}}
40
- */
41
- static getLCPNodeToPreload(mainResource: LH.Artifacts.NetworkRequest, graph: LH.Gatherer.Simulation.GraphNode, lcpRecord: NetworkRequest | undefined): {
42
- lcpNodeToPreload?: LH.Gatherer.Simulation.GraphNetworkNode;
43
- initiatorPath?: InitiatorPath;
44
- };
45
- /**
46
- * Computes the estimated effect of preloading the LCP image.
47
- * @param {LH.Artifacts.TraceElement} lcpElement
48
- * @param {LH.Gatherer.Simulation.GraphNetworkNode|undefined} lcpNode
49
- * @param {LH.Gatherer.Simulation.GraphNode} graph
50
- * @param {LH.Gatherer.Simulation.Simulator} simulator
51
- * @return {{wastedMs: number, results: Array<{node: LH.Audit.Details.NodeValue, url: string, wastedMs: number}>}}
52
- */
53
- static computeWasteWithGraph(lcpElement: LH.Artifacts.TraceElement, lcpNode: LH.Gatherer.Simulation.GraphNetworkNode | undefined, graph: LH.Gatherer.Simulation.GraphNode, simulator: LH.Gatherer.Simulation.Simulator): {
54
- wastedMs: number;
55
- results: Array<{
56
- node: LH.Audit.Details.NodeValue;
57
- url: string;
58
- wastedMs: number;
59
- }>;
60
- };
61
- /**
62
- * @param {LH.Artifacts} artifacts
63
- * @param {LH.Audit.Context} context
64
- * @return {Promise<LH.Audit.Product>}
65
- */
66
- static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
67
- }
68
- export namespace UIStrings {
69
- let title: string;
70
- let description: string;
71
- }
72
- import { Audit } from './audit.js';
73
- import { NetworkRequest } from '../lib/network-request.js';
74
- //# sourceMappingURL=prioritize-lcp-image.d.ts.map