lighthouse 11.0.0 → 11.1.0-dev.20230908

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 (210) hide show
  1. package/cli/bin.js +1 -1
  2. package/cli/cli-flags.js +1 -1
  3. package/cli/test/smokehouse/core-tests.js +3 -1
  4. package/cli/test/smokehouse/frontends/smokehouse-bin.js +1 -1
  5. package/cli/test/smokehouse/lighthouse-runners/bundle.js +1 -1
  6. package/cli/test/smokehouse/lighthouse-runners/cli.js +1 -1
  7. package/cli/test/smokehouse/lighthouse-runners/devtools.js +1 -1
  8. package/core/audits/accessibility/accesskeys.js +1 -1
  9. package/core/audits/accessibility/aria-allowed-attr.js +1 -1
  10. package/core/audits/accessibility/aria-allowed-role.js +1 -1
  11. package/core/audits/accessibility/aria-command-name.js +1 -1
  12. package/core/audits/accessibility/aria-dialog-name.js +1 -1
  13. package/core/audits/accessibility/aria-hidden-body.js +1 -1
  14. package/core/audits/accessibility/aria-hidden-focus.js +1 -1
  15. package/core/audits/accessibility/aria-input-field-name.js +1 -1
  16. package/core/audits/accessibility/aria-meter-name.js +1 -1
  17. package/core/audits/accessibility/aria-progressbar-name.js +1 -1
  18. package/core/audits/accessibility/aria-required-attr.js +1 -1
  19. package/core/audits/accessibility/aria-required-children.js +1 -1
  20. package/core/audits/accessibility/aria-required-parent.js +1 -1
  21. package/core/audits/accessibility/aria-roles.js +1 -1
  22. package/core/audits/accessibility/aria-text.js +1 -1
  23. package/core/audits/accessibility/aria-toggle-field-name.js +1 -1
  24. package/core/audits/accessibility/aria-tooltip-name.js +1 -1
  25. package/core/audits/accessibility/aria-treeitem-name.js +1 -1
  26. package/core/audits/accessibility/aria-valid-attr-value.js +1 -1
  27. package/core/audits/accessibility/aria-valid-attr.js +1 -1
  28. package/core/audits/accessibility/button-name.js +1 -1
  29. package/core/audits/accessibility/bypass.js +1 -1
  30. package/core/audits/accessibility/color-contrast.js +1 -1
  31. package/core/audits/accessibility/definition-list.js +1 -1
  32. package/core/audits/accessibility/dlitem.js +1 -1
  33. package/core/audits/accessibility/document-title.js +1 -1
  34. package/core/audits/accessibility/duplicate-id-active.js +1 -1
  35. package/core/audits/accessibility/duplicate-id-aria.js +2 -1
  36. package/core/audits/accessibility/empty-heading.js +1 -1
  37. package/core/audits/accessibility/form-field-multiple-labels.js +1 -1
  38. package/core/audits/accessibility/frame-title.js +1 -1
  39. package/core/audits/accessibility/heading-order.js +1 -1
  40. package/core/audits/accessibility/html-has-lang.js +1 -1
  41. package/core/audits/accessibility/html-lang-valid.js +1 -1
  42. package/core/audits/accessibility/html-xml-lang-mismatch.js +1 -1
  43. package/core/audits/accessibility/identical-links-same-purpose.js +1 -1
  44. package/core/audits/accessibility/image-alt.js +1 -1
  45. package/core/audits/accessibility/image-redundant-alt.js +1 -1
  46. package/core/audits/accessibility/input-button-name.js +1 -1
  47. package/core/audits/accessibility/input-image-alt.js +1 -1
  48. package/core/audits/accessibility/label-content-name-mismatch.js +1 -1
  49. package/core/audits/accessibility/label.js +1 -1
  50. package/core/audits/accessibility/landmark-one-main.js +1 -1
  51. package/core/audits/accessibility/link-in-text-block.js +1 -1
  52. package/core/audits/accessibility/link-name.js +1 -1
  53. package/core/audits/accessibility/list.js +1 -1
  54. package/core/audits/accessibility/listitem.js +1 -1
  55. package/core/audits/accessibility/meta-refresh.js +1 -1
  56. package/core/audits/accessibility/meta-viewport.js +1 -1
  57. package/core/audits/accessibility/object-alt.js +1 -1
  58. package/core/audits/accessibility/select-name.js +1 -1
  59. package/core/audits/accessibility/skip-link.js +1 -1
  60. package/core/audits/accessibility/tabindex.js +1 -1
  61. package/core/audits/accessibility/table-duplicate-name.js +1 -1
  62. package/core/audits/accessibility/table-fake-caption.js +1 -1
  63. package/core/audits/accessibility/target-size.js +1 -1
  64. package/core/audits/accessibility/td-has-header.js +1 -1
  65. package/core/audits/accessibility/td-headers-attr.js +1 -1
  66. package/core/audits/accessibility/th-has-data-cells.js +1 -1
  67. package/core/audits/accessibility/valid-lang.js +1 -1
  68. package/core/audits/accessibility/video-caption.js +1 -1
  69. package/core/audits/bf-cache.js +1 -0
  70. package/core/audits/bootup-time.d.ts +6 -0
  71. package/core/audits/bootup-time.js +37 -1
  72. package/core/audits/byte-efficiency/duplicated-javascript.js +1 -0
  73. package/core/audits/byte-efficiency/efficient-animated-content.js +1 -0
  74. package/core/audits/byte-efficiency/legacy-javascript.js +2 -1
  75. package/core/audits/byte-efficiency/modern-image-formats.js +1 -0
  76. package/core/audits/byte-efficiency/offscreen-images.js +1 -0
  77. package/core/audits/byte-efficiency/render-blocking-resources.js +1 -0
  78. package/core/audits/byte-efficiency/total-byte-weight.js +1 -0
  79. package/core/audits/byte-efficiency/unminified-css.js +1 -0
  80. package/core/audits/byte-efficiency/unminified-javascript.js +1 -0
  81. package/core/audits/byte-efficiency/unused-css-rules.js +1 -0
  82. package/core/audits/byte-efficiency/unused-javascript.js +1 -0
  83. package/core/audits/byte-efficiency/uses-long-cache-ttl.js +1 -0
  84. package/core/audits/byte-efficiency/uses-optimized-images.js +1 -0
  85. package/core/audits/byte-efficiency/uses-responsive-images-snapshot.js +1 -0
  86. package/core/audits/byte-efficiency/uses-responsive-images.js +1 -0
  87. package/core/audits/byte-efficiency/uses-text-compression.js +1 -0
  88. package/core/audits/critical-request-chains.js +1 -0
  89. package/core/audits/dobetterweb/dom-size.d.ts +8 -2
  90. package/core/audits/dobetterweb/dom-size.js +51 -3
  91. package/core/audits/dobetterweb/no-document-write.js +1 -0
  92. package/core/audits/dobetterweb/uses-http2.js +1 -0
  93. package/core/audits/dobetterweb/uses-passive-event-listeners.js +1 -0
  94. package/core/audits/font-display.js +1 -0
  95. package/core/audits/image-aspect-ratio.js +10 -1
  96. package/core/audits/installable-manifest.d.ts +0 -6
  97. package/core/audits/installable-manifest.js +1 -17
  98. package/core/audits/largest-contentful-paint-element.js +22 -4
  99. package/core/audits/layout-shift-elements.js +1 -0
  100. package/core/audits/lcp-lazy-loaded.d.ts +3 -2
  101. package/core/audits/lcp-lazy-loaded.js +35 -5
  102. package/core/audits/long-tasks.js +1 -0
  103. package/core/audits/mainthread-work-breakdown.js +1 -0
  104. package/core/audits/non-composited-animations.js +1 -0
  105. package/core/audits/prioritize-lcp-image.js +1 -0
  106. package/core/audits/redirects.js +2 -4
  107. package/core/audits/seo/crawlable-anchors.js +2 -1
  108. package/core/audits/server-response-time.js +1 -0
  109. package/core/audits/third-party-facades.js +14 -5
  110. package/core/audits/third-party-summary.d.ts +4 -2
  111. package/core/audits/third-party-summary.js +25 -11
  112. package/core/audits/unsized-images.js +1 -0
  113. package/core/audits/user-timings.js +1 -0
  114. package/core/audits/uses-rel-preconnect.js +1 -0
  115. package/core/audits/uses-rel-preload.js +1 -0
  116. package/core/audits/viewport.js +1 -0
  117. package/core/audits/work-during-interaction.js +1 -0
  118. package/core/computed/main-resource.d.ts +1 -1
  119. package/core/computed/main-resource.js +10 -4
  120. package/core/computed/page-dependency-graph.js +2 -1
  121. package/core/computed/tbt-impact-tasks.d.ts +8 -13
  122. package/core/computed/tbt-impact-tasks.js +4 -6
  123. package/core/computed/viewport-meta.js +11 -1
  124. package/core/config/config-helpers.js +1 -1
  125. package/core/config/config.js +1 -1
  126. package/core/gather/gatherers/accessibility.js +5 -0
  127. package/core/gather/timespan-runner.d.ts +3 -0
  128. package/core/gather/timespan-runner.js +23 -0
  129. package/core/index.cjs +13 -13
  130. package/core/index.d.cts +15 -2
  131. package/core/lib/asset-saver.d.ts +0 -3
  132. package/core/lib/asset-saver.js +68 -42
  133. package/core/lib/dependency-graph/simulator/network-analyzer.d.ts +7 -1
  134. package/core/lib/dependency-graph/simulator/network-analyzer.js +17 -1
  135. package/core/lib/emulation.js +1 -1
  136. package/core/lib/i18n/i18n.js +2 -2
  137. package/core/runner.js +5 -4
  138. package/dist/report/bundle.esm.js +3 -1
  139. package/dist/report/flow.js +3 -1
  140. package/dist/report/standalone.js +3 -1
  141. package/flow-report/tsconfig.json +0 -2
  142. package/package.json +8 -7
  143. package/readme.md +4 -1
  144. package/report/assets/templates.html +2 -0
  145. package/report/generator/flow-report-assets.js +1 -1
  146. package/report/generator/report-assets.js +1 -1
  147. package/report/generator/tsconfig.json +1 -1
  148. package/report/renderer/components.js +1 -1
  149. package/report/renderer/i18n-formatter.js +1 -1
  150. package/shared/localization/format.js +1 -1
  151. package/shared/localization/locales/ar-XB.json +36 -39
  152. package/shared/localization/locales/ar.json +36 -39
  153. package/shared/localization/locales/bg.json +36 -39
  154. package/shared/localization/locales/ca.json +36 -39
  155. package/shared/localization/locales/cs.json +36 -39
  156. package/shared/localization/locales/da.json +36 -39
  157. package/shared/localization/locales/de.json +36 -39
  158. package/shared/localization/locales/el.json +36 -39
  159. package/shared/localization/locales/en-GB.json +7 -10
  160. package/shared/localization/locales/en-US.json +64 -64
  161. package/shared/localization/locales/en-XA.json +36 -39
  162. package/shared/localization/locales/en-XL.json +64 -64
  163. package/shared/localization/locales/es-419.json +36 -39
  164. package/shared/localization/locales/es.json +36 -39
  165. package/shared/localization/locales/fi.json +36 -39
  166. package/shared/localization/locales/fil.json +36 -39
  167. package/shared/localization/locales/fr.json +36 -39
  168. package/shared/localization/locales/he.json +36 -39
  169. package/shared/localization/locales/hi.json +36 -39
  170. package/shared/localization/locales/hr.json +36 -39
  171. package/shared/localization/locales/hu.json +36 -39
  172. package/shared/localization/locales/id.json +36 -39
  173. package/shared/localization/locales/it.json +36 -39
  174. package/shared/localization/locales/ja.json +36 -39
  175. package/shared/localization/locales/ko.json +36 -39
  176. package/shared/localization/locales/lt.json +36 -39
  177. package/shared/localization/locales/lv.json +36 -39
  178. package/shared/localization/locales/nl.json +36 -39
  179. package/shared/localization/locales/no.json +36 -39
  180. package/shared/localization/locales/pl.json +36 -39
  181. package/shared/localization/locales/pt-PT.json +36 -39
  182. package/shared/localization/locales/pt.json +36 -39
  183. package/shared/localization/locales/ro.json +36 -39
  184. package/shared/localization/locales/ru.json +36 -39
  185. package/shared/localization/locales/sk.json +36 -39
  186. package/shared/localization/locales/sl.json +36 -39
  187. package/shared/localization/locales/sr-Latn.json +36 -39
  188. package/shared/localization/locales/sr.json +36 -39
  189. package/shared/localization/locales/sv.json +36 -39
  190. package/shared/localization/locales/ta.json +36 -39
  191. package/shared/localization/locales/te.json +36 -39
  192. package/shared/localization/locales/th.json +36 -39
  193. package/shared/localization/locales/tr.json +36 -39
  194. package/shared/localization/locales/uk.json +36 -39
  195. package/shared/localization/locales/vi.json +36 -39
  196. package/shared/localization/locales/zh-HK.json +36 -39
  197. package/shared/localization/locales/zh-TW.json +36 -39
  198. package/shared/localization/locales/zh.json +36 -39
  199. package/shared/localization/locales.js +1 -1
  200. package/{root.js → shared/root.js} +2 -1
  201. package/shared/tsconfig.json +0 -1
  202. package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +1 -1
  203. package/third-party/chromium-synchronization/installability-errors-test.js +0 -1
  204. package/third-party/download-content-shell/download-content-shell.js +1 -1
  205. package/tsconfig.json +0 -2
  206. package/types/artifacts.d.ts +2 -1
  207. package/types/audit.d.ts +2 -0
  208. /package/{esm-utils.d.ts → shared/esm-utils.d.ts} +0 -0
  209. /package/{esm-utils.js → shared/esm-utils.js} +0 -0
  210. /package/{root.d.ts → shared/root.d.ts} +0 -0
@@ -22,7 +22,7 @@ const UIStrings = {
22
22
  /** Description of a Lighthouse audit that tells the user *why* they should try to pass. 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
23
  description: 'Screen readers have a specific way of announcing lists. Ensuring proper list ' +
24
24
  'structure aids screen reader output. ' +
25
- '[Learn more about proper list structure](https://dequeuniversity.com/rules/axe/4.7/list).',
25
+ '[Learn more about proper list structure](https://dequeuniversity.com/rules/axe/4.8/list).',
26
26
  };
27
27
 
28
28
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -21,7 +21,7 @@ const UIStrings = {
21
21
  /** Description of a Lighthouse audit that tells the user *why* they should try to pass. 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
22
  description: 'Screen readers require list items (`<li>`) to be contained within a ' +
23
23
  'parent `<ul>`, `<ol>` or `<menu>` to be announced properly. ' +
24
- '[Learn more about proper list structure](https://dequeuniversity.com/rules/axe/4.7/listitem).',
24
+ '[Learn more about proper list structure](https://dequeuniversity.com/rules/axe/4.8/listitem).',
25
25
  };
26
26
 
27
27
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -21,7 +21,7 @@ const UIStrings = {
21
21
  description: 'Users do not expect a page to refresh automatically, and doing so will move ' +
22
22
  'focus back to the top of the page. This may create a frustrating or ' +
23
23
  'confusing experience. ' +
24
- '[Learn more about the refresh meta tag](https://dequeuniversity.com/rules/axe/4.7/meta-refresh).',
24
+ '[Learn more about the refresh meta tag](https://dequeuniversity.com/rules/axe/4.8/meta-refresh).',
25
25
  };
26
26
 
27
27
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -22,7 +22,7 @@ const UIStrings = {
22
22
  /** Description of a Lighthouse audit that tells the user *why* they should try to pass. 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
23
  description: 'Disabling zooming is problematic for users with low vision who rely on ' +
24
24
  'screen magnification to properly see the contents of a web page. ' +
25
- '[Learn more about the viewport meta tag](https://dequeuniversity.com/rules/axe/4.7/meta-viewport).',
25
+ '[Learn more about the viewport meta tag](https://dequeuniversity.com/rules/axe/4.8/meta-viewport).',
26
26
  };
27
27
 
28
28
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -20,7 +20,7 @@ const UIStrings = {
20
20
  /** Description of a Lighthouse audit that tells the user *why* they should try to pass. 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. */
21
21
  description: 'Screen readers cannot translate non-text content. Adding alternate text to ' +
22
22
  '`<object>` elements helps screen readers convey meaning to users. ' +
23
- '[Learn more about alt text for `object` elements](https://dequeuniversity.com/rules/axe/4.7/object-alt).',
23
+ '[Learn more about alt text for `object` elements](https://dequeuniversity.com/rules/axe/4.8/object-alt).',
24
24
  };
25
25
 
26
26
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -20,7 +20,7 @@ const UIStrings = {
20
20
  /** Description of a Lighthouse audit that tells the user *why* they should try to pass. 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. */
21
21
  description: 'Form elements without effective labels can create frustrating experiences ' +
22
22
  'for screen reader users. ' +
23
- '[Learn more about the `select` element](https://dequeuniversity.com/rules/axe/4.7/select-name).',
23
+ '[Learn more about the `select` element](https://dequeuniversity.com/rules/axe/4.8/select-name).',
24
24
  };
25
25
 
26
26
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -19,7 +19,7 @@ const UIStrings = {
19
19
  failureTitle: 'Skip links are not focusable.',
20
20
  /** Description of a Lighthouse audit that tells the user *why* they should try to pass. 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. */
21
21
  description: 'Including a skip link can help users skip to the main content to save time. ' +
22
- '[Learn more about skip links](https://dequeuniversity.com/rules/axe/4.7/skip-link).',
22
+ '[Learn more about skip links](https://dequeuniversity.com/rules/axe/4.8/skip-link).',
23
23
  };
24
24
 
25
25
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -20,7 +20,7 @@ const UIStrings = {
20
20
  /** Description of a Lighthouse audit that tells the user *why* they should try to pass. 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. */
21
21
  description: 'A value greater than 0 implies an explicit navigation ordering. ' +
22
22
  'Although technically valid, this often creates frustrating experiences ' +
23
- 'for users who rely on assistive technologies. [Learn more about the `tabindex` attribute](https://dequeuniversity.com/rules/axe/4.7/tabindex).',
23
+ 'for users who rely on assistive technologies. [Learn more about the `tabindex` attribute](https://dequeuniversity.com/rules/axe/4.8/tabindex).',
24
24
  };
25
25
 
26
26
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -20,7 +20,7 @@ const UIStrings = {
20
20
  /** Description of a Lighthouse audit that tells the user *why* they should try to pass. 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. */
21
21
  description: 'The summary attribute should describe the table structure, while `<caption>` ' +
22
22
  'should have the onscreen title. Accurate table mark-up helps users of screen readers. ' +
23
- '[Learn more about summary and caption](https://dequeuniversity.com/rules/axe/4.7/table-duplicate-name).',
23
+ '[Learn more about summary and caption](https://dequeuniversity.com/rules/axe/4.8/table-duplicate-name).',
24
24
  };
25
25
 
26
26
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -23,7 +23,7 @@ const UIStrings = {
23
23
  description: 'Screen readers have features to make navigating tables easier. Ensuring ' +
24
24
  'that tables use the actual caption element instead of cells with the `[colspan]` ' +
25
25
  'attribute may improve the experience for screen reader users. ' +
26
- '[Learn more about captions](https://dequeuniversity.com/rules/axe/4.7/table-fake-caption).',
26
+ '[Learn more about captions](https://dequeuniversity.com/rules/axe/4.8/table-fake-caption).',
27
27
  };
28
28
 
29
29
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -20,7 +20,7 @@ const UIStrings = {
20
20
  /** Description of a Lighthouse audit that tells the user *why* they should try to pass. 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. */
21
21
  description: 'Touch targets with sufficient size and spacing help users who may have ' +
22
22
  'difficulty targeting small controls to activate the targets. ' +
23
- '[Learn more about touch targets](https://dequeuniversity.com/rules/axe/4.7/target-size).',
23
+ '[Learn more about touch targets](https://dequeuniversity.com/rules/axe/4.8/target-size).',
24
24
  };
25
25
 
26
26
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -21,7 +21,7 @@ const UIStrings = {
21
21
  description: 'Screen readers have features to make navigating tables easier. Ensuring ' +
22
22
  'that `<td>` elements in a large table (3 or more cells in width and height) have an ' +
23
23
  'associated table header may improve the experience for screen reader users. ' +
24
- '[Learn more about table headers](https://dequeuniversity.com/rules/axe/4.7/td-has-header).',
24
+ '[Learn more about table headers](https://dequeuniversity.com/rules/axe/4.8/td-has-header).',
25
25
  };
26
26
 
27
27
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -24,7 +24,7 @@ const UIStrings = {
24
24
  description: 'Screen readers have features to make navigating tables easier. Ensuring ' +
25
25
  '`<td>` cells using the `[headers]` attribute only refer to other cells in the same ' +
26
26
  'table may improve the experience for screen reader users. ' +
27
- '[Learn more about the `headers` attribute](https://dequeuniversity.com/rules/axe/4.7/td-headers-attr).',
27
+ '[Learn more about the `headers` attribute](https://dequeuniversity.com/rules/axe/4.8/td-headers-attr).',
28
28
  };
29
29
 
30
30
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -23,7 +23,7 @@ const UIStrings = {
23
23
  description: 'Screen readers have features to make navigating tables easier. Ensuring ' +
24
24
  'table headers always refer to some set of cells may improve the experience for screen ' +
25
25
  'reader users. ' +
26
- '[Learn more about table headers](https://dequeuniversity.com/rules/axe/4.7/th-has-data-cells).',
26
+ '[Learn more about table headers](https://dequeuniversity.com/rules/axe/4.8/th-has-data-cells).',
27
27
  };
28
28
 
29
29
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -20,7 +20,7 @@ const UIStrings = {
20
20
  /** Description of a Lighthouse audit that tells the user *why* they should try to pass. 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. */
21
21
  description: 'Specifying a valid [BCP 47 language](https://www.w3.org/International/questions/qa-choosing-language-tags#question) ' +
22
22
  'on elements helps ensure that text is pronounced correctly by a screen reader. ' +
23
- '[Learn how to use the `lang` attribute](https://dequeuniversity.com/rules/axe/4.7/valid-lang).',
23
+ '[Learn how to use the `lang` attribute](https://dequeuniversity.com/rules/axe/4.8/valid-lang).',
24
24
  };
25
25
 
26
26
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -21,7 +21,7 @@ const UIStrings = {
21
21
  /** Description of a Lighthouse audit that tells the user *why* they should try to pass. 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
22
  description: 'When a video provides a caption it is easier for deaf and hearing impaired ' +
23
23
  'users to access its information. ' +
24
- '[Learn more about video captions](https://dequeuniversity.com/rules/axe/4.7/video-caption).',
24
+ '[Learn more about video captions](https://dequeuniversity.com/rules/axe/4.8/video-caption).',
25
25
  };
26
26
 
27
27
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -59,6 +59,7 @@ class BFCache extends Audit {
59
59
  failureTitle: str_(UIStrings.failureTitle),
60
60
  description: str_(UIStrings.description),
61
61
  supportedModes: ['navigation', 'timespan'],
62
+ guidanceLevel: 2,
62
63
  requiredArtifacts: ['BFCacheFailures'],
63
64
  };
64
65
  }
@@ -6,6 +6,12 @@ declare class BootupTime extends Audit {
6
6
  static get defaultOptions(): import("../../types/audit.js").default.ScoreOptions & {
7
7
  thresholdInMs: number;
8
8
  };
9
+ /**
10
+ * @param {LH.Artifacts} artifacts
11
+ * @param {LH.Audit.Context} context
12
+ * @return {Promise<number>}
13
+ */
14
+ static getTbtImpact(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<number>;
9
15
  /**
10
16
  * @param {LH.Artifacts} artifacts
11
17
  * @param {LH.Audit.Context} context
@@ -4,12 +4,16 @@
4
4
  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
5
5
  */
6
6
 
7
+ import log from 'lighthouse-logger';
8
+
7
9
  import {Audit} from './audit.js';
8
10
  import {taskGroups} from '../lib/tracehouse/task-groups.js';
9
11
  import * as i18n from '../lib/i18n/i18n.js';
10
12
  import {NetworkRecords} from '../computed/network-records.js';
11
13
  import {MainThreadTasks} from '../computed/main-thread-tasks.js';
12
14
  import {getExecutionTimingsByURL} from '../lib/tracehouse/task-summary.js';
15
+ import {TBTImpactTasks} from '../computed/tbt-impact-tasks.js';
16
+ import {Sentry} from '../lib/sentry.js';
13
17
 
14
18
  const UIStrings = {
15
19
  /** Title of a diagnostic audit that provides detail on the time spent executing javascript files during the load. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
@@ -44,7 +48,8 @@ class BootupTime extends Audit {
44
48
  failureTitle: str_(UIStrings.failureTitle),
45
49
  description: str_(UIStrings.description),
46
50
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
47
- requiredArtifacts: ['traces', 'devtoolsLogs'],
51
+ guidanceLevel: 1,
52
+ requiredArtifacts: ['traces', 'devtoolsLogs', 'URL', 'GatherContext'],
48
53
  };
49
54
  }
50
55
 
@@ -61,6 +66,33 @@ class BootupTime extends Audit {
61
66
  };
62
67
  }
63
68
 
69
+ /**
70
+ * @param {LH.Artifacts} artifacts
71
+ * @param {LH.Audit.Context} context
72
+ * @return {Promise<number>}
73
+ */
74
+ static async getTbtImpact(artifacts, context) {
75
+ let tbtImpact = 0;
76
+
77
+ try {
78
+ const metricComputationData = Audit.makeMetricComputationDataInput(artifacts, context);
79
+ const tasks = await TBTImpactTasks.request(metricComputationData, context);
80
+ for (const task of tasks) {
81
+ const groupId = task.group.id;
82
+ if (groupId !== 'scriptEvaluation' && groupId !== 'scriptParseCompile') continue;
83
+ tbtImpact += task.selfTbtImpact;
84
+ }
85
+ } catch (err) {
86
+ Sentry.captureException(err, {
87
+ tags: {audit: this.meta.id},
88
+ level: 'error',
89
+ });
90
+ log.error(this.meta.id, err.message);
91
+ }
92
+
93
+ return tbtImpact;
94
+ }
95
+
64
96
  /**
65
97
  * @param {LH.Artifacts} artifacts
66
98
  * @param {LH.Audit.Context} context
@@ -76,6 +108,7 @@ class BootupTime extends Audit {
76
108
  settings.throttling.cpuSlowdownMultiplier : 1;
77
109
 
78
110
  const executionTimings = getExecutionTimingsByURL(tasks, networkRecords);
111
+ const tbtImpact = await this.getTbtImpact(artifacts, context);
79
112
 
80
113
  let hadExcessiveChromeExtension = false;
81
114
  let totalBootupTime = 0;
@@ -142,6 +175,9 @@ class BootupTime extends Audit {
142
175
  str_(i18n.UIStrings.seconds, {timeInMs: totalBootupTime}) : '',
143
176
  details,
144
177
  runWarnings,
178
+ metricSavings: {
179
+ TBT: tbtImpact,
180
+ },
145
181
  };
146
182
  }
147
183
  }
@@ -47,6 +47,7 @@ class DuplicatedJavascript extends ByteEfficiencyAudit {
47
47
  title: str_(UIStrings.title),
48
48
  description: str_(UIStrings.description),
49
49
  scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
50
+ guidanceLevel: 2,
50
51
  requiredArtifacts: ['devtoolsLogs', 'traces', 'SourceMaps', 'Scripts',
51
52
  'GatherContext', 'URL'],
52
53
  };
@@ -37,6 +37,7 @@ class EfficientAnimatedContent extends ByteEfficiencyAudit {
37
37
  title: str_(UIStrings.title),
38
38
  description: str_(UIStrings.description),
39
39
  scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
40
+ guidanceLevel: 3,
40
41
  requiredArtifacts: ['devtoolsLogs', 'traces', 'GatherContext', 'URL'],
41
42
  };
42
43
  }
@@ -25,7 +25,7 @@ import {EntityClassification} from '../../computed/entity-classification.js';
25
25
  import {JSBundles} from '../../computed/js-bundles.js';
26
26
  import * as i18n from '../../lib/i18n/i18n.js';
27
27
  import {getRequestForScript} from '../../lib/script-helpers.js';
28
- import {LH_ROOT} from '../../../root.js';
28
+ import {LH_ROOT} from '../../../shared/root.js';
29
29
 
30
30
  const graphJson = fs.readFileSync(
31
31
  `${LH_ROOT}/core/audits/byte-efficiency/polyfill-graph-data.json`, 'utf-8');
@@ -118,6 +118,7 @@ class LegacyJavascript extends ByteEfficiencyAudit {
118
118
  scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
119
119
  description: str_(UIStrings.description),
120
120
  title: str_(UIStrings.title),
121
+ guidanceLevel: 2,
121
122
  requiredArtifacts: ['devtoolsLogs', 'traces', 'Scripts', 'SourceMaps',
122
123
  'GatherContext', 'URL'],
123
124
  };
@@ -35,6 +35,7 @@ class ModernImageFormats extends ByteEfficiencyAudit {
35
35
  title: str_(UIStrings.title),
36
36
  description: str_(UIStrings.description),
37
37
  scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
38
+ guidanceLevel: 3,
38
39
  requiredArtifacts: ['OptimizedImages', 'devtoolsLogs', 'traces', 'URL', 'GatherContext',
39
40
  'ImageElements'],
40
41
  };
@@ -50,6 +50,7 @@ class OffscreenImages extends ByteEfficiencyAudit {
50
50
  description: str_(UIStrings.description),
51
51
  scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
52
52
  supportedModes: ['navigation'],
53
+ guidanceLevel: 2,
53
54
  requiredArtifacts: ['ImageElements', 'ViewportDimensions', 'GatherContext', 'devtoolsLogs',
54
55
  'traces', 'URL'],
55
56
  };
@@ -115,6 +115,7 @@ class RenderBlockingResources extends Audit {
115
115
  supportedModes: ['navigation'],
116
116
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
117
117
  description: str_(UIStrings.description),
118
+ guidanceLevel: 2,
118
119
  // TODO: look into adding an `optionalArtifacts` property that captures the non-required nature
119
120
  // of CSSUsage
120
121
  requiredArtifacts: ['URL', 'TagsBlockingFirstPaint', 'traces', 'devtoolsLogs', 'CSSUsage',
@@ -35,6 +35,7 @@ class TotalByteWeight extends Audit {
35
35
  failureTitle: str_(UIStrings.failureTitle),
36
36
  description: str_(UIStrings.description),
37
37
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
38
+ guidanceLevel: 1,
38
39
  requiredArtifacts: ['devtoolsLogs'],
39
40
  };
40
41
  }
@@ -35,6 +35,7 @@ class UnminifiedCSS extends ByteEfficiencyAudit {
35
35
  title: str_(UIStrings.title),
36
36
  description: str_(UIStrings.description),
37
37
  scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
38
+ guidanceLevel: 3,
38
39
  requiredArtifacts: ['CSSUsage', 'devtoolsLogs', 'traces', 'URL', 'GatherContext'],
39
40
  };
40
41
  }
@@ -43,6 +43,7 @@ class UnminifiedJavaScript extends ByteEfficiencyAudit {
43
43
  title: str_(UIStrings.title),
44
44
  description: str_(UIStrings.description),
45
45
  scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
46
+ guidanceLevel: 3,
46
47
  requiredArtifacts: ['Scripts', 'devtoolsLogs', 'traces', 'GatherContext', 'URL'],
47
48
  };
48
49
  }
@@ -33,6 +33,7 @@ class UnusedCSSRules extends ByteEfficiencyAudit {
33
33
  title: str_(UIStrings.title),
34
34
  description: str_(UIStrings.description),
35
35
  scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
36
+ guidanceLevel: 2,
36
37
  requiredArtifacts: ['CSSUsage', 'URL', 'devtoolsLogs', 'traces', 'GatherContext'],
37
38
  };
38
39
  }
@@ -67,6 +67,7 @@ class UnusedJavaScript extends ByteEfficiencyAudit {
67
67
  title: str_(UIStrings.title),
68
68
  description: str_(UIStrings.description),
69
69
  scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
70
+ guidanceLevel: 2,
70
71
  requiredArtifacts: ['JsUsage', 'Scripts', 'SourceMaps', 'GatherContext',
71
72
  'devtoolsLogs', 'traces', 'URL'],
72
73
  };
@@ -45,6 +45,7 @@ class CacheHeaders extends Audit {
45
45
  failureTitle: str_(UIStrings.failureTitle),
46
46
  description: str_(UIStrings.description),
47
47
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
48
+ guidanceLevel: 3,
48
49
  requiredArtifacts: ['devtoolsLogs'],
49
50
  };
50
51
  }
@@ -35,6 +35,7 @@ class UsesOptimizedImages extends ByteEfficiencyAudit {
35
35
  title: str_(UIStrings.title),
36
36
  description: str_(UIStrings.description),
37
37
  scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
38
+ guidanceLevel: 2,
38
39
  requiredArtifacts: ['OptimizedImages', 'ImageElements', 'GatherContext', 'devtoolsLogs',
39
40
  'traces', 'URL'],
40
41
  };
@@ -43,6 +43,7 @@ class UsesResponsiveImagesSnapshot extends Audit {
43
43
  failureTitle: str_(UIStrings.failureTitle),
44
44
  description: UsesResponsiveImages.str_(UsesResponsiveImages.UIStrings.description),
45
45
  supportedModes: ['snapshot'],
46
+ guidanceLevel: 2,
46
47
  requiredArtifacts: ['ImageElements', 'ViewportDimensions'],
47
48
  };
48
49
  }
@@ -46,6 +46,7 @@ class UsesResponsiveImages extends ByteEfficiencyAudit {
46
46
  title: str_(UIStrings.title),
47
47
  description: str_(UIStrings.description),
48
48
  scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
49
+ guidanceLevel: 2,
49
50
  requiredArtifacts: ['ImageElements', 'ViewportDimensions', 'GatherContext',
50
51
  'devtoolsLogs', 'traces', 'URL'],
51
52
  };
@@ -37,6 +37,7 @@ class ResponsesAreCompressed extends ByteEfficiencyAudit {
37
37
  title: str_(UIStrings.title),
38
38
  description: str_(UIStrings.description),
39
39
  scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
40
+ guidanceLevel: 3,
40
41
  requiredArtifacts: ['ResponseCompression', 'GatherContext', 'devtoolsLogs', 'traces', 'URL'],
41
42
  };
42
43
  }
@@ -37,6 +37,7 @@ class CriticalRequestChains extends Audit {
37
37
  description: str_(UIStrings.description),
38
38
  scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE,
39
39
  supportedModes: ['navigation'],
40
+ guidanceLevel: 1,
40
41
  requiredArtifacts: ['traces', 'devtoolsLogs', 'URL'],
41
42
  };
42
43
  }
@@ -7,9 +7,15 @@ declare class DOMSize extends Audit {
7
7
  /**
8
8
  * @param {LH.Artifacts} artifacts
9
9
  * @param {LH.Audit.Context} context
10
- * @return {LH.Audit.Product}
10
+ * @return {Promise<number|undefined>}
11
11
  */
12
- static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): LH.Audit.Product;
12
+ static computeTbtImpact(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<number | undefined>;
13
+ /**
14
+ * @param {LH.Artifacts} artifacts
15
+ * @param {LH.Audit.Context} context
16
+ * @return {Promise<LH.Audit.Product>}
17
+ */
18
+ static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
13
19
  }
14
20
  export namespace UIStrings {
15
21
  const title: string;
@@ -13,6 +13,7 @@
13
13
 
14
14
  import {Audit} from '../audit.js';
15
15
  import * as i18n from '../../lib/i18n/i18n.js';
16
+ import {TBTImpactTasks} from '../../computed/tbt-impact-tasks.js';
16
17
 
17
18
  const UIStrings = {
18
19
  /** Title of a diagnostic audit that provides detail on the size of the web page's DOM. The size of a DOM is characterized by the total number of DOM elements and greatest DOM depth. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
@@ -53,7 +54,9 @@ class DOMSize extends Audit {
53
54
  failureTitle: str_(UIStrings.failureTitle),
54
55
  description: str_(UIStrings.description),
55
56
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
56
- requiredArtifacts: ['DOMStats'],
57
+ guidanceLevel: 1,
58
+ requiredArtifacts: ['DOMStats', 'URL', 'GatherContext'],
59
+ __internalOptionalArtifacts: ['traces', 'devtoolsLogs'],
57
60
  };
58
61
  }
59
62
 
@@ -69,13 +72,53 @@ class DOMSize extends Audit {
69
72
  };
70
73
  }
71
74
 
75
+ /**
76
+ * @param {LH.Artifacts} artifacts
77
+ * @param {LH.Audit.Context} context
78
+ * @return {Promise<number|undefined>}
79
+ */
80
+ static async computeTbtImpact(artifacts, context) {
81
+ let tbtImpact = 0;
82
+
83
+ // We still want to surface this audit in snapshot mode, but since we don't compute TBT
84
+ // the impact should always be undefined.
85
+ const {GatherContext, devtoolsLogs, traces} = artifacts;
86
+ if (GatherContext.gatherMode !== 'navigation') {
87
+ return undefined;
88
+ }
89
+
90
+ // Since the artifacts are optional, it's still possible for them to be missing in navigation mode.
91
+ // Navigation mode does compute TBT so we should surface a numerical savings of 0.
92
+ if (!devtoolsLogs?.[Audit.DEFAULT_PASS] || !traces?.[Audit.DEFAULT_PASS]) {
93
+ return 0;
94
+ }
95
+
96
+ const metricComputationData = Audit.makeMetricComputationDataInput(artifacts, context);
97
+
98
+ try {
99
+ // The TBT impact of style/layout tasks is correlated to the DOM size.
100
+ // Even in situations where the page forces a style recalc, the DOM size is partially to blame
101
+ // for any time spent blocking the main thread.
102
+ //
103
+ // `tbtImpact` should be exactly 0 for small DOMs since `selfTbtImpact` accounts for the blocking
104
+ // time and not the main thread time.
105
+ const tbtImpactTasks = await TBTImpactTasks.request(metricComputationData, context);
106
+ for (const task of tbtImpactTasks) {
107
+ if (task.group.id !== 'styleLayout') continue;
108
+ tbtImpact += task.selfTbtImpact;
109
+ }
110
+ } catch {}
111
+
112
+ return Math.round(tbtImpact);
113
+ }
114
+
72
115
 
73
116
  /**
74
117
  * @param {LH.Artifacts} artifacts
75
118
  * @param {LH.Audit.Context} context
76
- * @return {LH.Audit.Product}
119
+ * @return {Promise<LH.Audit.Product>}
77
120
  */
78
- static audit(artifacts, context) {
121
+ static async audit(artifacts, context) {
79
122
  const stats = artifacts.DOMStats;
80
123
 
81
124
  const score = Audit.computeLogNormalScore(
@@ -120,12 +163,17 @@ class DOMSize extends Audit {
120
163
  },
121
164
  ];
122
165
 
166
+ const tbtImpact = await this.computeTbtImpact(artifacts, context);
167
+
123
168
  return {
124
169
  score,
125
170
  numericValue: stats.totalBodyElements,
126
171
  numericUnit: 'element',
127
172
  displayValue: str_(UIStrings.displayValue, {itemCount: stats.totalBodyElements}),
128
173
  details: Audit.makeTableDetails(headings, items),
174
+ metricSavings: {
175
+ TBT: tbtImpact,
176
+ },
129
177
  };
130
178
  }
131
179
  }
@@ -53,6 +53,7 @@ class NoDocWriteAudit extends ViolationAudit {
53
53
  title: str_(UIStrings.title),
54
54
  failureTitle: str_(UIStrings.failureTitle),
55
55
  description: str_(UIStrings.description),
56
+ guidanceLevel: 2,
56
57
  requiredArtifacts: ['ConsoleMessages', 'SourceMaps', 'Scripts'],
57
58
  };
58
59
  }
@@ -62,6 +62,7 @@ class UsesHTTP2Audit extends Audit {
62
62
  title: str_(UIStrings.title),
63
63
  description: str_(UIStrings.description),
64
64
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
65
+ guidanceLevel: 3,
65
66
  supportedModes: ['timespan', 'navigation'],
66
67
  requiredArtifacts: ['URL', 'devtoolsLogs', 'traces', 'GatherContext'],
67
68
  };
@@ -36,6 +36,7 @@ class PassiveEventsAudit extends ViolationAudit {
36
36
  title: str_(UIStrings.title),
37
37
  failureTitle: str_(UIStrings.failureTitle),
38
38
  description: str_(UIStrings.description),
39
+ guidanceLevel: 3,
39
40
  requiredArtifacts: ['ConsoleMessages', 'SourceMaps', 'Scripts'],
40
41
  };
41
42
  }
@@ -49,6 +49,7 @@ class FontDisplay extends Audit {
49
49
  failureTitle: str_(UIStrings.failureTitle),
50
50
  description: str_(UIStrings.description),
51
51
  supportedModes: ['navigation'],
52
+ guidanceLevel: 3,
52
53
  requiredArtifacts: ['devtoolsLogs', 'CSSUsage', 'URL'],
53
54
  };
54
55
  }
@@ -59,7 +59,16 @@ class ImageAspectRatio extends Audit {
59
59
  const displayedAspectRatio = image.displayedWidth / image.displayedHeight;
60
60
 
61
61
  const targetDisplayHeight = image.displayedWidth / actualAspectRatio;
62
- const doRatiosMatch = Math.abs(targetDisplayHeight - image.displayedHeight) < THRESHOLD_PX;
62
+ const targetDisplayWidth = image.displayedHeight * actualAspectRatio;
63
+
64
+ // Small rounding errors in aspect ratio can lead to large differences in target width/height
65
+ // if the aspect ratio is close to 0.
66
+ //
67
+ // In these cases, we should compare the smaller dimension because any rounding errors will
68
+ // affect that dimension less.
69
+ const doRatiosMatch = targetDisplayHeight < targetDisplayWidth
70
+ ? Math.abs(targetDisplayHeight - image.displayedHeight) < THRESHOLD_PX
71
+ : Math.abs(targetDisplayWidth - image.displayedWidth) < THRESHOLD_PX;
63
72
 
64
73
  return {
65
74
  url,
@@ -104,12 +104,6 @@ export const UIStrings: {
104
104
  'protocol-timeout': string;
105
105
  /** Message logged when the web app has been uninstalled o desktop, signalling that the install banner state is being reset. */
106
106
  'pipeline-restarted': string;
107
- /**
108
- * TODO: This error was removed in M114, we can remove this message when it hits stable.
109
- * @description Error message explaining that the URL of the manifest uses a scheme that is not supported on Android.
110
- * @example {data:} scheme
111
- */
112
- 'scheme-not-supported-for-webapk': string;
113
107
  };
114
108
  import { Audit } from './audit.js';
115
109
  //# sourceMappingURL=installable-manifest.d.ts.map