lighthouse 11.7.0 → 12.0.0-dev.20240422

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 (334) hide show
  1. package/CONTRIBUTING.md +2 -2
  2. package/cli/bin.js +0 -7
  3. package/cli/cli-flags.d.ts +1 -5
  4. package/cli/cli-flags.js +4 -8
  5. package/cli/test/smokehouse/__snapshots__/report-assert-test.js.snap +14 -14
  6. package/cli/test/smokehouse/config/exclusions.js +3 -0
  7. package/cli/test/smokehouse/core-tests.js +6 -20
  8. package/cli/test/smokehouse/frontends/smokehouse-bin.js +2 -2
  9. package/core/audits/accessibility/accesskeys.js +1 -1
  10. package/core/audits/accessibility/aria-allowed-attr.js +1 -1
  11. package/core/audits/accessibility/aria-allowed-role.js +1 -1
  12. package/core/audits/accessibility/aria-command-name.js +1 -1
  13. package/core/audits/accessibility/aria-conditional-attr.d.ts +10 -0
  14. package/core/audits/accessibility/aria-conditional-attr.js +43 -0
  15. package/core/audits/accessibility/{duplicate-id-active.d.ts → aria-deprecated-role.d.ts} +3 -3
  16. package/core/audits/accessibility/aria-deprecated-role.js +43 -0
  17. package/core/audits/accessibility/aria-dialog-name.js +1 -1
  18. package/core/audits/accessibility/aria-hidden-body.js +1 -1
  19. package/core/audits/accessibility/aria-hidden-focus.js +1 -1
  20. package/core/audits/accessibility/aria-input-field-name.js +1 -1
  21. package/core/audits/accessibility/aria-meter-name.js +1 -1
  22. package/core/audits/accessibility/aria-progressbar-name.js +1 -1
  23. package/core/audits/accessibility/aria-prohibited-attr.d.ts +10 -0
  24. package/core/audits/accessibility/aria-prohibited-attr.js +44 -0
  25. package/core/audits/accessibility/aria-required-attr.js +1 -1
  26. package/core/audits/accessibility/aria-required-children.js +1 -1
  27. package/core/audits/accessibility/aria-required-parent.js +1 -1
  28. package/core/audits/accessibility/aria-roles.js +1 -1
  29. package/core/audits/accessibility/aria-text.js +1 -1
  30. package/core/audits/accessibility/aria-toggle-field-name.js +1 -1
  31. package/core/audits/accessibility/aria-tooltip-name.js +1 -1
  32. package/core/audits/accessibility/aria-treeitem-name.js +1 -1
  33. package/core/audits/accessibility/aria-valid-attr-value.js +1 -1
  34. package/core/audits/accessibility/aria-valid-attr.js +1 -1
  35. package/core/audits/accessibility/button-name.js +1 -1
  36. package/core/audits/accessibility/bypass.js +1 -1
  37. package/core/audits/accessibility/color-contrast.js +1 -1
  38. package/core/audits/accessibility/definition-list.js +1 -1
  39. package/core/audits/accessibility/dlitem.js +1 -1
  40. package/core/audits/accessibility/document-title.js +1 -1
  41. package/core/audits/accessibility/duplicate-id-aria.js +1 -1
  42. package/core/audits/accessibility/empty-heading.js +1 -1
  43. package/core/audits/accessibility/form-field-multiple-labels.js +1 -1
  44. package/core/audits/accessibility/frame-title.js +1 -1
  45. package/core/audits/accessibility/heading-order.js +1 -1
  46. package/core/audits/accessibility/html-has-lang.js +1 -1
  47. package/core/audits/accessibility/html-lang-valid.js +1 -1
  48. package/core/audits/accessibility/html-xml-lang-mismatch.js +1 -1
  49. package/core/audits/accessibility/identical-links-same-purpose.js +1 -1
  50. package/core/audits/accessibility/image-alt.js +1 -1
  51. package/core/audits/accessibility/image-redundant-alt.js +1 -1
  52. package/core/audits/accessibility/input-button-name.js +1 -1
  53. package/core/audits/accessibility/input-image-alt.js +1 -1
  54. package/core/audits/accessibility/label-content-name-mismatch.js +1 -1
  55. package/core/audits/accessibility/label.js +1 -1
  56. package/core/audits/accessibility/landmark-one-main.js +1 -1
  57. package/core/audits/accessibility/link-in-text-block.js +1 -1
  58. package/core/audits/accessibility/link-name.js +1 -1
  59. package/core/audits/accessibility/list.js +1 -1
  60. package/core/audits/accessibility/listitem.js +1 -1
  61. package/core/audits/accessibility/meta-refresh.js +1 -1
  62. package/core/audits/accessibility/meta-viewport.js +1 -1
  63. package/core/audits/accessibility/object-alt.js +1 -1
  64. package/core/audits/accessibility/select-name.js +1 -1
  65. package/core/audits/accessibility/skip-link.js +1 -1
  66. package/core/audits/accessibility/tabindex.js +1 -1
  67. package/core/audits/accessibility/table-duplicate-name.js +1 -1
  68. package/core/audits/accessibility/table-fake-caption.js +1 -1
  69. package/core/audits/accessibility/target-size.js +1 -2
  70. package/core/audits/accessibility/td-has-header.js +1 -1
  71. package/core/audits/accessibility/td-headers-attr.js +1 -1
  72. package/core/audits/accessibility/th-has-data-cells.js +1 -1
  73. package/core/audits/accessibility/valid-lang.js +1 -1
  74. package/core/audits/accessibility/video-caption.js +1 -1
  75. package/core/audits/byte-efficiency/byte-efficiency-audit.d.ts +0 -16
  76. package/core/audits/byte-efficiency/byte-efficiency-audit.js +1 -38
  77. package/core/audits/byte-efficiency/offscreen-images.d.ts +0 -11
  78. package/core/audits/byte-efficiency/offscreen-images.js +0 -15
  79. package/core/audits/byte-efficiency/render-blocking-resources.js +27 -26
  80. package/core/audits/byte-efficiency/unminified-css.js +2 -2
  81. package/core/audits/byte-efficiency/unused-css-rules.js +3 -1
  82. package/core/audits/dobetterweb/uses-http2.d.ts +0 -13
  83. package/core/audits/dobetterweb/uses-http2.js +4 -38
  84. package/core/audits/font-display.js +2 -2
  85. package/core/audits/layout-shifts.js +2 -2
  86. package/core/audits/preload-fonts.d.ts +1 -5
  87. package/core/audits/preload-fonts.js +1 -10
  88. package/core/audits/prioritize-lcp-image.js +2 -2
  89. package/core/audits/redirects-http.d.ts +19 -0
  90. package/core/audits/redirects-http.js +75 -0
  91. package/core/audits/resource-summary.d.ts +2 -0
  92. package/core/audits/resource-summary.js +5 -4
  93. package/core/audits/seo/is-crawlable.d.ts +2 -1
  94. package/core/audits/seo/link-text.js +12 -0
  95. package/core/audits/uses-rel-preload.d.ts +1 -5
  96. package/core/audits/uses-rel-preload.js +5 -15
  97. package/core/audits/work-during-interaction.d.ts +2 -2
  98. package/core/audits/work-during-interaction.js +2 -2
  99. package/core/computed/js-bundles.d.ts +1 -1
  100. package/core/computed/metrics/cumulative-layout-shift.js +2 -2
  101. package/core/computed/metrics/lantern-first-contentful-paint.d.ts +13 -82
  102. package/core/computed/metrics/lantern-first-contentful-paint.js +16 -178
  103. package/core/computed/metrics/lantern-first-meaningful-paint.d.ts +13 -12
  104. package/core/computed/metrics/lantern-first-meaningful-paint.js +11 -49
  105. package/core/computed/metrics/lantern-interactive.d.ts +13 -21
  106. package/core/computed/metrics/lantern-interactive.js +12 -84
  107. package/core/computed/metrics/lantern-largest-contentful-paint.d.ts +13 -25
  108. package/core/computed/metrics/lantern-largest-contentful-paint.js +13 -80
  109. package/core/computed/metrics/lantern-max-potential-fid.d.ts +13 -24
  110. package/core/computed/metrics/lantern-max-potential-fid.js +12 -64
  111. package/core/computed/metrics/lantern-metric.d.ts +14 -18
  112. package/core/computed/metrics/lantern-metric.js +34 -30
  113. package/core/computed/metrics/lantern-speed-index.d.ts +13 -32
  114. package/core/computed/metrics/lantern-speed-index.js +13 -116
  115. package/core/computed/metrics/lantern-total-blocking-time.d.ts +13 -25
  116. package/core/computed/metrics/lantern-total-blocking-time.js +10 -94
  117. package/core/computed/metrics/metric.js +1 -3
  118. package/core/computed/module-duplication.d.ts +1 -1
  119. package/core/computed/navigation-insights.d.ts +36 -0
  120. package/core/computed/navigation-insights.js +35 -0
  121. package/core/computed/page-dependency-graph.js +3 -7
  122. package/core/computed/resource-summary.d.ts +10 -12
  123. package/core/computed/resource-summary.js +12 -19
  124. package/core/computed/trace-engine-result.d.ts +16 -3
  125. package/core/computed/trace-engine-result.js +19 -14
  126. package/core/computed/unused-css.d.ts +3 -1
  127. package/core/computed/unused-css.js +6 -5
  128. package/core/config/config-helpers.js +0 -4
  129. package/core/config/constants.js +0 -1
  130. package/core/config/default-config.js +63 -142
  131. package/core/config/experimental-config.js +11 -0
  132. package/core/config/filters.js +0 -1
  133. package/core/gather/driver/navigation.js +4 -1
  134. package/core/gather/driver/prepare.js +1 -1
  135. package/core/gather/driver/target-manager.js +4 -3
  136. package/core/gather/driver/wait-for-condition.js +2 -3
  137. package/core/gather/driver.d.ts +12 -0
  138. package/core/gather/driver.js +27 -0
  139. package/core/gather/gatherers/accessibility.js +4 -6
  140. package/core/gather/gatherers/css-usage.d.ts +0 -21
  141. package/core/gather/gatherers/css-usage.js +9 -119
  142. package/core/gather/gatherers/root-causes.d.ts +2 -2
  143. package/core/gather/gatherers/root-causes.js +6 -5
  144. package/core/gather/gatherers/stylesheets.d.ts +26 -0
  145. package/core/gather/gatherers/stylesheets.js +138 -0
  146. package/core/gather/gatherers/trace-elements.d.ts +4 -13
  147. package/core/gather/gatherers/trace-elements.js +42 -31
  148. package/core/gather/navigation-runner.js +3 -1
  149. package/core/gather/session.d.ts +8 -0
  150. package/core/gather/session.js +14 -1
  151. package/core/lib/emulation.js +2 -2
  152. package/core/lib/i18n/i18n.d.ts +0 -1
  153. package/core/lib/i18n/i18n.js +0 -2
  154. package/core/lib/lantern/cpu-node.d.ts +7 -1
  155. package/core/lib/lantern/cpu-node.js +12 -2
  156. package/core/lib/lantern/lantern-error.d.ts +8 -0
  157. package/core/lib/lantern/lantern-error.js +9 -0
  158. package/core/lib/lantern/metric.js +2 -6
  159. package/core/lib/lantern/metrics/first-contentful-paint.d.ts +79 -0
  160. package/core/lib/lantern/metrics/first-contentful-paint.js +200 -0
  161. package/core/lib/lantern/metrics/first-meaningful-paint.d.ts +6 -0
  162. package/core/lib/lantern/metrics/first-meaningful-paint.js +64 -0
  163. package/core/lib/lantern/metrics/interactive.d.ts +26 -0
  164. package/core/lib/lantern/metrics/interactive.js +112 -0
  165. package/core/lib/lantern/metrics/largest-contentful-paint.d.ts +19 -0
  166. package/core/lib/lantern/metrics/largest-contentful-paint.js +108 -0
  167. package/core/lib/lantern/metrics/max-potential-fid.d.ts +30 -0
  168. package/core/lib/lantern/metrics/max-potential-fid.js +92 -0
  169. package/core/lib/lantern/metrics/speed-index.d.ts +38 -0
  170. package/core/lib/lantern/metrics/speed-index.js +144 -0
  171. package/core/lib/lantern/metrics/total-blocking-time.d.ts +31 -0
  172. package/core/lib/lantern/metrics/total-blocking-time.js +128 -0
  173. package/core/lib/lantern/network-node.js +28 -4
  174. package/core/lib/lantern/page-dependency-graph.d.ts +4 -4
  175. package/core/lib/lantern/page-dependency-graph.js +19 -7
  176. package/core/lib/lantern/simulator/connection-pool.d.ts +2 -12
  177. package/core/lib/lantern/simulator/connection-pool.js +3 -22
  178. package/core/lib/lantern/simulator/network-analyzer.js +1 -12
  179. package/core/lib/lantern/simulator/simulator.d.ts +2 -4
  180. package/core/lib/lantern/simulator/simulator.js +7 -14
  181. package/core/lib/lantern/types/lantern.d.ts +5 -3
  182. package/core/lib/lantern-trace-saver.js +0 -1
  183. package/core/lib/lh-error.d.ts +9 -0
  184. package/core/lib/lh-error.js +13 -3
  185. package/core/lib/lighthouse-compatibility.js +53 -10
  186. package/core/lib/navigation-error.js +3 -0
  187. package/core/lib/network-request.d.ts +1 -0
  188. package/core/lib/network-request.js +29 -1
  189. package/core/lib/proto-preprocessor.js +24 -8
  190. package/core/lib/tracehouse/trace-processor.js +15 -2
  191. package/core/runner.js +18 -25
  192. package/dist/report/bundle.esm.js +11 -112
  193. package/dist/report/flow.js +16 -117
  194. package/dist/report/standalone.js +12 -113
  195. package/flow-report/src/help-dialog.tsx +0 -1
  196. package/flow-report/src/i18n/i18n.d.ts +0 -4
  197. package/flow-report/src/i18n/ui-strings.d.ts +0 -1
  198. package/flow-report/src/i18n/ui-strings.js +0 -2
  199. package/flow-report/src/summary/category.tsx +10 -12
  200. package/package.json +7 -7
  201. package/readme.md +4 -4
  202. package/report/assets/styles.css +1 -60
  203. package/report/assets/templates.html +0 -95
  204. package/report/renderer/category-renderer.js +1 -1
  205. package/report/renderer/components.d.ts +2 -2
  206. package/report/renderer/components.js +2 -103
  207. package/report/renderer/dom.d.ts +1 -1
  208. package/report/renderer/dom.js +1 -1
  209. package/report/renderer/performance-category-renderer.d.ts +0 -7
  210. package/report/renderer/performance-category-renderer.js +1 -32
  211. package/report/renderer/report-renderer.js +3 -13
  212. package/report/renderer/report-ui-features.js +1 -1
  213. package/report/renderer/report-utils.d.ts +0 -1
  214. package/report/renderer/report-utils.js +13 -13
  215. package/shared/localization/locales/ar-XB.json +62 -329
  216. package/shared/localization/locales/ar.json +62 -329
  217. package/shared/localization/locales/bg.json +62 -329
  218. package/shared/localization/locales/ca.json +62 -329
  219. package/shared/localization/locales/cs.json +62 -329
  220. package/shared/localization/locales/da.json +62 -329
  221. package/shared/localization/locales/de.json +62 -329
  222. package/shared/localization/locales/el.json +62 -329
  223. package/shared/localization/locales/en-GB.json +62 -329
  224. package/shared/localization/locales/en-US.json +101 -332
  225. package/shared/localization/locales/en-XA.json +62 -329
  226. package/shared/localization/locales/en-XL.json +101 -332
  227. package/shared/localization/locales/es-419.json +62 -329
  228. package/shared/localization/locales/es.json +62 -329
  229. package/shared/localization/locales/fi.json +62 -329
  230. package/shared/localization/locales/fil.json +61 -328
  231. package/shared/localization/locales/fr.json +62 -329
  232. package/shared/localization/locales/he.json +62 -329
  233. package/shared/localization/locales/hi.json +62 -329
  234. package/shared/localization/locales/hr.json +63 -330
  235. package/shared/localization/locales/hu.json +62 -329
  236. package/shared/localization/locales/id.json +62 -329
  237. package/shared/localization/locales/it.json +62 -329
  238. package/shared/localization/locales/ja.json +62 -329
  239. package/shared/localization/locales/ko.json +62 -329
  240. package/shared/localization/locales/lt.json +62 -329
  241. package/shared/localization/locales/lv.json +62 -329
  242. package/shared/localization/locales/nl.json +62 -329
  243. package/shared/localization/locales/no.json +62 -329
  244. package/shared/localization/locales/pl.json +61 -328
  245. package/shared/localization/locales/pt-PT.json +62 -329
  246. package/shared/localization/locales/pt.json +64 -331
  247. package/shared/localization/locales/ro.json +62 -329
  248. package/shared/localization/locales/ru.json +62 -329
  249. package/shared/localization/locales/sk.json +62 -329
  250. package/shared/localization/locales/sl.json +62 -329
  251. package/shared/localization/locales/sr-Latn.json +62 -329
  252. package/shared/localization/locales/sr.json +62 -329
  253. package/shared/localization/locales/sv.json +62 -329
  254. package/shared/localization/locales/ta.json +61 -328
  255. package/shared/localization/locales/te.json +62 -329
  256. package/shared/localization/locales/th.json +62 -329
  257. package/shared/localization/locales/tr.json +62 -329
  258. package/shared/localization/locales/uk.json +62 -329
  259. package/shared/localization/locales/vi.json +61 -328
  260. package/shared/localization/locales/zh-HK.json +62 -329
  261. package/shared/localization/locales/zh-TW.json +61 -328
  262. package/shared/localization/locales/zh.json +62 -329
  263. package/tsconfig.json +1 -3
  264. package/types/artifacts.d.ts +21 -110
  265. package/types/audit.d.ts +0 -10
  266. package/types/config.d.ts +0 -1
  267. package/types/externs.d.ts +0 -2
  268. package/types/gatherer.d.ts +3 -0
  269. package/types/internal/smokehouse.d.ts +1 -1
  270. package/types/lh.d.ts +0 -2
  271. package/types/lhr/audit-details.d.ts +9 -4
  272. package/types/lhr/lhr.d.ts +0 -4
  273. package/types/lhr/settings.d.ts +0 -4
  274. package/core/audits/accessibility/duplicate-id-active.js +0 -42
  275. package/core/audits/content-width.d.ts +0 -17
  276. package/core/audits/content-width.js +0 -76
  277. package/core/audits/installable-manifest.d.ts +0 -111
  278. package/core/audits/installable-manifest.js +0 -248
  279. package/core/audits/layout-shift-elements.d.ts +0 -16
  280. package/core/audits/layout-shift-elements.js +0 -101
  281. package/core/audits/manual/pwa-cross-browser.d.ts +0 -12
  282. package/core/audits/manual/pwa-cross-browser.js +0 -40
  283. package/core/audits/manual/pwa-each-page-has-url.d.ts +0 -12
  284. package/core/audits/manual/pwa-each-page-has-url.js +0 -38
  285. package/core/audits/manual/pwa-page-transitions.d.ts +0 -12
  286. package/core/audits/manual/pwa-page-transitions.js +0 -38
  287. package/core/audits/maskable-icon.d.ts +0 -25
  288. package/core/audits/maskable-icon.js +0 -70
  289. package/core/audits/multi-check-audit.d.ts +0 -28
  290. package/core/audits/multi-check-audit.js +0 -82
  291. package/core/audits/no-unload-listeners.d.ts +0 -16
  292. package/core/audits/no-unload-listeners.js +0 -86
  293. package/core/audits/performance-budget.d.ts +0 -39
  294. package/core/audits/performance-budget.js +0 -154
  295. package/core/audits/script-elements-test-audit.d.ts +0 -14
  296. package/core/audits/script-elements-test-audit.js +0 -29
  297. package/core/audits/seo/plugins.d.ts +0 -15
  298. package/core/audits/seo/plugins.js +0 -150
  299. package/core/audits/seo/tap-targets.d.ts +0 -50
  300. package/core/audits/seo/tap-targets.js +0 -352
  301. package/core/audits/splash-screen.d.ts +0 -37
  302. package/core/audits/splash-screen.js +0 -98
  303. package/core/audits/themed-omnibox.d.ts +0 -42
  304. package/core/audits/themed-omnibox.js +0 -102
  305. package/core/audits/timing-budget.d.ts +0 -43
  306. package/core/audits/timing-budget.js +0 -175
  307. package/core/computed/manifest-values.d.ts +0 -24
  308. package/core/computed/manifest-values.js +0 -136
  309. package/core/config/budget.d.ts +0 -74
  310. package/core/config/budget.js +0 -340
  311. package/core/config/metrics-to-audits.d.ts +0 -19
  312. package/core/config/metrics-to-audits.js +0 -62
  313. package/core/gather/driver/service-workers.d.ts +0 -16
  314. package/core/gather/driver/service-workers.js +0 -52
  315. package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.d.ts +0 -47
  316. package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.js +0 -233
  317. package/core/gather/gatherers/global-listeners.d.ts +0 -27
  318. package/core/gather/gatherers/global-listeners.js +0 -108
  319. package/core/gather/gatherers/installability-errors.d.ts +0 -17
  320. package/core/gather/gatherers/installability-errors.js +0 -56
  321. package/core/gather/gatherers/script-elements.d.ts +0 -21
  322. package/core/gather/gatherers/script-elements.js +0 -100
  323. package/core/gather/gatherers/seo/embedded-content.d.ts +0 -10
  324. package/core/gather/gatherers/seo/embedded-content.js +0 -63
  325. package/core/gather/gatherers/seo/tap-targets.d.ts +0 -21
  326. package/core/gather/gatherers/seo/tap-targets.js +0 -389
  327. package/core/gather/gatherers/service-worker.d.ts +0 -10
  328. package/core/gather/gatherers/service-worker.js +0 -32
  329. package/core/gather/gatherers/web-app-manifest.d.ts +0 -32
  330. package/core/gather/gatherers/web-app-manifest.js +0 -106
  331. package/report/renderer/pwa-category-renderer.d.ts +0 -55
  332. package/report/renderer/pwa-category-renderer.js +0 -184
  333. package/third-party/chromium-synchronization/installability-errors-test.js +0 -79
  334. package/types/lhr/budget.d.ts +0 -60
@@ -5,11 +5,9 @@
5
5
  */
6
6
 
7
7
  import {Audit} from '../audit.js';
8
- import {LanternInteractive} from '../../computed/metrics/lantern-interactive.js';
9
8
  import * as i18n from '../../lib/i18n/i18n.js';
10
9
  import {NetworkRecords} from '../../computed/network-records.js';
11
10
  import {LoadSimulator} from '../../computed/load-simulator.js';
12
- import {PageDependencyGraph} from '../../computed/page-dependency-graph.js';
13
11
  import {LanternLargestContentfulPaint} from '../../computed/metrics/lantern-largest-contentful-paint.js';
14
12
  import {LanternFirstContentfulPaint} from '../../computed/metrics/lantern-first-contentful-paint.js';
15
13
  import {LCPImageRecord} from '../../computed/lcp-image-record.js';
@@ -151,37 +149,6 @@ class ByteEfficiencyAudit extends Audit {
151
149
  };
152
150
  }
153
151
 
154
- /**
155
- * Computes the estimated effect of all the byte savings on the maximum of the following:
156
- *
157
- * - end time of the last long task in the provided graph
158
- * - (if includeLoad is true or not provided) end time of the last node in the graph
159
- *
160
- * @param {Array<LH.Audit.ByteEfficiencyItem>} results The array of byte savings results per resource
161
- * @param {Node} graph
162
- * @param {Simulator} simulator
163
- * @param {{includeLoad?: boolean, providedWastedBytesByUrl?: Map<string, number>}=} options
164
- * @return {number}
165
- */
166
- static computeWasteWithTTIGraph(results, graph, simulator, options) {
167
- options = Object.assign({includeLoad: true}, options);
168
- const {savings: savingsOnOverallLoad, simulationBeforeChanges, simulationAfterChanges} =
169
- this.computeWasteWithGraph(results, graph, simulator, {
170
- ...options,
171
- label: 'overallLoad',
172
- });
173
-
174
- const savingsOnTTI =
175
- LanternInteractive.getLastLongTaskEndTime(simulationBeforeChanges.nodeTimings) -
176
- LanternInteractive.getLastLongTaskEndTime(simulationAfterChanges.nodeTimings);
177
-
178
- let savings = savingsOnTTI;
179
- if (options.includeLoad) savings = Math.max(savings, savingsOnOverallLoad);
180
-
181
- // Round waste to nearest 10ms
182
- return Math.round(Math.max(savings, 0) / 10) * 10;
183
- }
184
-
185
152
  /**
186
153
  * @param {ByteEfficiencyProduct} result
187
154
  * @param {Simulator} simulator
@@ -204,7 +171,6 @@ class ByteEfficiencyAudit extends Audit {
204
171
  // This is useful information in the LHR and should be preserved.
205
172
  let wastedMs;
206
173
  if (metricComputationInput.gatherContext.gatherMode === 'navigation') {
207
- const graph = await PageDependencyGraph.request(metricComputationInput, context);
208
174
  const {
209
175
  optimisticGraph: optimisticFCPGraph,
210
176
  } = await LanternFirstContentfulPaint.request(metricComputationInput, context);
@@ -212,10 +178,6 @@ class ByteEfficiencyAudit extends Audit {
212
178
  optimisticGraph: optimisticLCPGraph,
213
179
  } = await LanternLargestContentfulPaint.request(metricComputationInput, context);
214
180
 
215
- wastedMs = this.computeWasteWithTTIGraph(results, graph, simulator, {
216
- providedWastedBytesByUrl: result.wastedBytesByUrl,
217
- });
218
-
219
181
  const {savings: fcpSavings} = this.computeWasteWithGraph(
220
182
  results,
221
183
  optimisticFCPGraph,
@@ -243,6 +205,7 @@ class ByteEfficiencyAudit extends Audit {
243
205
 
244
206
  metricSavings.FCP = fcpSavings;
245
207
  metricSavings.LCP = Math.max(lcpGraphSavings, lcpRecordSavings);
208
+ wastedMs = metricSavings.LCP;
246
209
  } else {
247
210
  wastedMs = simulator.computeWastedMsFromWastedBytes(wastedBytes);
248
211
  }
@@ -47,17 +47,6 @@ declare class OffscreenImages extends ByteEfficiencyAudit {
47
47
  * @param {number} interactiveTimestamp
48
48
  */
49
49
  static filterObservedResults(images: WasteResult[], interactiveTimestamp: number): WasteResult[];
50
- /**
51
- * The default byte efficiency audit will report max(TTI, load), since lazy-loading offscreen
52
- * images won't reduce the overall time and the wasted bytes are really only "wasted" for TTI,
53
- * override the function to just look at TTI savings.
54
- *
55
- * @param {Array<LH.Audit.ByteEfficiencyItem>} results
56
- * @param {LH.Gatherer.Simulation.GraphNode} graph
57
- * @param {LH.Gatherer.Simulation.Simulator} simulator
58
- * @return {number}
59
- */
60
- static computeWasteWithTTIGraph(results: Array<LH.Audit.ByteEfficiencyItem>, graph: LH.Gatherer.Simulation.GraphNode, simulator: LH.Gatherer.Simulation.Simulator): number;
61
50
  /**
62
51
  * @param {LH.Artifacts} artifacts
63
52
  * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
@@ -156,21 +156,6 @@ class OffscreenImages extends ByteEfficiencyAudit {
156
156
  });
157
157
  }
158
158
 
159
- /**
160
- * The default byte efficiency audit will report max(TTI, load), since lazy-loading offscreen
161
- * images won't reduce the overall time and the wasted bytes are really only "wasted" for TTI,
162
- * override the function to just look at TTI savings.
163
- *
164
- * @param {Array<LH.Audit.ByteEfficiencyItem>} results
165
- * @param {LH.Gatherer.Simulation.GraphNode} graph
166
- * @param {LH.Gatherer.Simulation.Simulator} simulator
167
- * @return {number}
168
- */
169
- static computeWasteWithTTIGraph(results, graph, simulator) {
170
- return super.computeWasteWithTTIGraph(results, graph, simulator,
171
- {includeLoad: false});
172
- }
173
-
174
159
  /**
175
160
  * @param {LH.Artifacts} artifacts
176
161
  * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
@@ -14,10 +14,10 @@ import * as i18n from '../../lib/i18n/i18n.js';
14
14
  import {BaseNode} from '../../lib/lantern/base-node.js';
15
15
  import {UnusedCSS} from '../../computed/unused-css.js';
16
16
  import {NetworkRequest} from '../../lib/network-request.js';
17
- import {ProcessedNavigation} from '../../computed/processed-navigation.js';
18
17
  import {LoadSimulator} from '../../computed/load-simulator.js';
19
18
  import {FirstContentfulPaint} from '../../computed/metrics/first-contentful-paint.js';
20
19
  import {LCPImageRecord} from '../../computed/lcp-image-record.js';
20
+ import {NavigationInsights} from '../../computed/navigation-insights.js';
21
21
 
22
22
 
23
23
  /** @typedef {import('../../lib/lantern/simulator/simulator.js').Simulator} Simulator */
@@ -44,21 +44,19 @@ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
44
44
  /**
45
45
  * Given a simulation's nodeTimings, return an object with the nodes/timing keyed by network URL
46
46
  * @param {LH.Gatherer.Simulation.Result['nodeTimings']} nodeTimings
47
- * @return {Object<string, {node: Node, nodeTiming: LH.Gatherer.Simulation.NodeTiming}>}
47
+ * @return {Map<string, {node: Node, nodeTiming: LH.Gatherer.Simulation.NodeTiming}>}
48
48
  */
49
- function getNodesAndTimingByUrl(nodeTimings) {
50
- /** @type {Object<string, {node: Node, nodeTiming: LH.Gatherer.Simulation.NodeTiming}>} */
51
- const urlMap = {};
52
- const nodes = Array.from(nodeTimings.keys());
53
- nodes.forEach(node => {
54
- if (node.type !== 'network') return;
55
- const nodeTiming = nodeTimings.get(node);
56
- if (!nodeTiming) return;
57
-
58
- urlMap[node.record.url] = {node, nodeTiming};
59
- });
49
+ function getNodesAndTimingByRequestId(nodeTimings) {
50
+ /** @type {Map<string, {node: Node, nodeTiming: LH.Gatherer.Simulation.NodeTiming}>} */
51
+ const requestIdToNode = new Map();
52
+
53
+ for (const [node, nodeTiming] of nodeTimings) {
54
+ if (node.type !== 'network') continue;
60
55
 
61
- return urlMap;
56
+ requestIdToNode.set(node.record.requestId, {node, nodeTiming});
57
+ }
58
+
59
+ return requestIdToNode;
62
60
  }
63
61
 
64
62
  /**
@@ -119,8 +117,8 @@ class RenderBlockingResources extends Audit {
119
117
  guidanceLevel: 2,
120
118
  // TODO: look into adding an `optionalArtifacts` property that captures the non-required nature
121
119
  // of CSSUsage
122
- requiredArtifacts: ['URL', 'TagsBlockingFirstPaint', 'traces', 'devtoolsLogs', 'CSSUsage',
123
- 'GatherContext', 'Stacks'],
120
+ requiredArtifacts:
121
+ ['URL', 'traces', 'devtoolsLogs', 'Stylesheets', 'CSSUsage', 'GatherContext', 'Stacks'],
124
122
  };
125
123
  }
126
124
 
@@ -134,9 +132,12 @@ class RenderBlockingResources extends Audit {
134
132
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
135
133
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
136
134
  const simulatorData = {devtoolsLog, settings: context.settings};
137
- const processedNavigation = await ProcessedNavigation.request(trace, context);
138
135
  const simulator = await LoadSimulator.request(simulatorData, context);
139
136
  const wastedCssBytes = await RenderBlockingResources.computeWastedCSSBytes(artifacts, context);
137
+ const navInsights = await NavigationInsights.request(trace, context);
138
+
139
+ const renderBlocking = navInsights.RenderBlocking;
140
+ if (renderBlocking instanceof Error) throw renderBlocking;
140
141
 
141
142
  /** @type {LH.Audit.Context['settings']} */
142
143
  const metricSettings = {
@@ -150,19 +151,18 @@ class RenderBlockingResources extends Audit {
150
151
  // Cast to just `LanternMetric` since we explicitly set `throttlingMethod: 'simulate'`.
151
152
  const fcpSimulation = /** @type {LH.Artifacts.LanternMetric} */
152
153
  (await FirstContentfulPaint.request(metricComputationData, context));
153
- const fcpTsInMs = processedNavigation.timestamps.firstContentfulPaint / 1000;
154
154
 
155
- const nodesByUrl = getNodesAndTimingByUrl(fcpSimulation.optimisticEstimate.nodeTimings);
155
+ const nodesAndTimingsByRequestId =
156
+ getNodesAndTimingByRequestId(fcpSimulation.optimisticEstimate.nodeTimings);
156
157
 
157
158
  const results = [];
158
159
  const deferredNodeIds = new Set();
159
- for (const resource of artifacts.TagsBlockingFirstPaint) {
160
- // Ignore any resources that finished after observed FCP (they're clearly not render-blocking)
161
- if (resource.endTime > fcpTsInMs) continue;
160
+ for (const resource of renderBlocking.renderBlockingRequests) {
161
+ const nodeAndTiming = nodesAndTimingsByRequestId.get(resource.args.data.requestId);
162
162
  // TODO: beacon to Sentry, https://github.com/GoogleChrome/lighthouse/issues/7041
163
- if (!nodesByUrl[resource.tag.url]) continue;
163
+ if (!nodeAndTiming) continue;
164
164
 
165
- const {node, nodeTiming} = nodesByUrl[resource.tag.url];
165
+ const {node, nodeTiming} = nodeAndTiming;
166
166
 
167
167
  const stackSpecificTiming = computeStackSpecificTiming(node, nodeTiming, artifacts.Stacks);
168
168
 
@@ -174,8 +174,8 @@ class RenderBlockingResources extends Audit {
174
174
  if (wastedMs < MINIMUM_WASTED_MS) continue;
175
175
 
176
176
  results.push({
177
- url: resource.tag.url,
178
- totalBytes: resource.transferSize,
177
+ url: resource.args.data.url,
178
+ totalBytes: resource.args.data.encodedDataLength,
179
179
  wastedMs,
180
180
  });
181
181
  }
@@ -264,6 +264,7 @@ class RenderBlockingResources extends Audit {
264
264
  const wastedBytesByUrl = new Map();
265
265
  try {
266
266
  const unusedCssItems = await UnusedCSS.request({
267
+ Stylesheets: artifacts.Stylesheets,
267
268
  CSSUsage: artifacts.CSSUsage,
268
269
  devtoolsLog: artifacts.devtoolsLogs[Audit.DEFAULT_PASS],
269
270
  }, context);
@@ -37,7 +37,7 @@ class UnminifiedCSS extends ByteEfficiencyAudit {
37
37
  description: str_(UIStrings.description),
38
38
  scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
39
39
  guidanceLevel: 3,
40
- requiredArtifacts: ['CSSUsage', 'devtoolsLogs', 'traces', 'URL', 'GatherContext'],
40
+ requiredArtifacts: ['Stylesheets', 'devtoolsLogs', 'traces', 'URL', 'GatherContext'],
41
41
  };
42
42
  }
43
43
 
@@ -85,7 +85,7 @@ class UnminifiedCSS extends ByteEfficiencyAudit {
85
85
  */
86
86
  static audit_(artifacts, networkRecords) {
87
87
  const items = [];
88
- for (const stylesheet of artifacts.CSSUsage.stylesheets) {
88
+ for (const stylesheet of artifacts.Stylesheets) {
89
89
  const networkRecord = networkRecords
90
90
  .find(record => record.url === stylesheet.header.sourceURL);
91
91
  if (!stylesheet.content) continue;
@@ -34,7 +34,8 @@ class UnusedCSSRules extends ByteEfficiencyAudit {
34
34
  description: str_(UIStrings.description),
35
35
  scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
36
36
  guidanceLevel: 1,
37
- requiredArtifacts: ['CSSUsage', 'URL', 'devtoolsLogs', 'traces', 'GatherContext'],
37
+ requiredArtifacts:
38
+ ['Stylesheets', 'CSSUsage', 'URL', 'devtoolsLogs', 'traces', 'GatherContext'],
38
39
  };
39
40
  }
40
41
 
@@ -46,6 +47,7 @@ class UnusedCSSRules extends ByteEfficiencyAudit {
46
47
  */
47
48
  static async audit_(artifacts, _, context) {
48
49
  const unusedCssItems = await UnusedCSS.request({
50
+ Stylesheets: artifacts.Stylesheets,
49
51
  CSSUsage: artifacts.CSSUsage,
50
52
  devtoolsLog: artifacts.devtoolsLogs[ByteEfficiencyAudit.DEFAULT_PASS],
51
53
  }, context);
@@ -20,19 +20,6 @@ declare class UsesHTTP2Audit extends Audit {
20
20
  simulationBefore: LH.Gatherer.Simulation.Result;
21
21
  simulationAfter: LH.Gatherer.Simulation.Result;
22
22
  };
23
- /**
24
- * Computes the estimated effect all results being converted to use http/2, the max of:
25
- *
26
- * - end time of the last long task in the provided graph
27
- * - end time of the last node in the graph
28
- * @param {Array<{url: string}>} results
29
- * @param {Node} graph
30
- * @param {Simulator} simulator
31
- * @return {number}
32
- */
33
- static computeWasteWithTTIGraph(results: Array<{
34
- url: string;
35
- }>, graph: Node, simulator: Simulator): number;
36
23
  /**
37
24
  * Determines whether a network request is a "static resource" that would benefit from H2 multiplexing.
38
25
  * XHRs, tracking pixels, etc generally don't benefit as much because they aren't requested en-masse
@@ -15,11 +15,9 @@
15
15
  import {Audit} from '../audit.js';
16
16
  import {EntityClassification} from '../../computed/entity-classification.js';
17
17
  import UrlUtils from '../../lib/url-utils.js';
18
- import {LanternInteractive} from '../../computed/metrics/lantern-interactive.js';
19
18
  import {NetworkRequest} from '../../lib/network-request.js';
20
19
  import {NetworkRecords} from '../../computed/network-records.js';
21
20
  import {LoadSimulator} from '../../computed/load-simulator.js';
22
- import {PageDependencyGraph} from '../../computed/page-dependency-graph.js';
23
21
  import {LanternLargestContentfulPaint} from '../../computed/metrics/lantern-largest-contentful-paint.js';
24
22
  import {LanternFirstContentfulPaint} from '../../computed/metrics/lantern-first-contentful-paint.js';
25
23
  import * as i18n from '../../lib/i18n/i18n.js';
@@ -80,11 +78,9 @@ class UsesHTTP2Audit extends Audit {
80
78
  options = Object.assign({label: ''}, options);
81
79
  const beforeLabel = `${this.meta.id}-${options.label}-before`;
82
80
  const afterLabel = `${this.meta.id}-${options.label}-after`;
83
- const flexibleOrdering = true;
84
81
 
85
82
  const urlsToChange = new Set(results.map(result => result.url));
86
- const simulationBefore =
87
- simulator.simulate(graph, {label: beforeLabel, flexibleOrdering});
83
+ const simulationBefore = simulator.simulate(graph, {label: beforeLabel});
88
84
 
89
85
  // Update all the protocols to reflect implementing our recommendations
90
86
  /** @type {Map<string, string>} */
@@ -97,7 +93,7 @@ class UsesHTTP2Audit extends Audit {
97
93
  node.request.protocol = 'h2';
98
94
  });
99
95
 
100
- const simulationAfter = simulator.simulate(graph, {label: afterLabel, flexibleOrdering});
96
+ const simulationAfter = simulator.simulate(graph, {label: afterLabel});
101
97
 
102
98
  // Restore the original protocol after we've done our simulation
103
99
  graph.traverse(node => {
@@ -117,32 +113,6 @@ class UsesHTTP2Audit extends Audit {
117
113
  };
118
114
  }
119
115
 
120
- /**
121
- * Computes the estimated effect all results being converted to use http/2, the max of:
122
- *
123
- * - end time of the last long task in the provided graph
124
- * - end time of the last node in the graph
125
- * @param {Array<{url: string}>} results
126
- * @param {Node} graph
127
- * @param {Simulator} simulator
128
- * @return {number}
129
- */
130
- static computeWasteWithTTIGraph(results, graph, simulator) {
131
- const {savings: savingsOnOverallLoad, simulationBefore, simulationAfter} =
132
- this.computeWasteWithGraph(results, graph, simulator, {
133
- label: 'tti',
134
- });
135
-
136
- const savingsOnTTI =
137
- LanternInteractive.getLastLongTaskEndTime(simulationBefore.nodeTimings) -
138
- LanternInteractive.getLastLongTaskEndTime(simulationAfter.nodeTimings);
139
-
140
- const savings = Math.max(savingsOnTTI, savingsOnOverallLoad);
141
-
142
- // Round waste to nearest 10ms
143
- return Math.round(Math.max(savings, 0) / 10) * 10;
144
- }
145
-
146
116
  /**
147
117
  * Determines whether a network request is a "static resource" that would benefit from H2 multiplexing.
148
118
  * XHRs, tracking pixels, etc generally don't benefit as much because they aren't requested en-masse
@@ -235,7 +205,6 @@ class UsesHTTP2Audit extends Audit {
235
205
  * @return {Promise<LH.Audit.Product>}
236
206
  */
237
207
  static async audit(artifacts, context) {
238
- const trace = artifacts.traces[Audit.DEFAULT_PASS];
239
208
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
240
209
  const URL = artifacts.URL;
241
210
  const networkRecords = await NetworkRecords.request(devtoolsLog, context);
@@ -269,7 +238,6 @@ class UsesHTTP2Audit extends Audit {
269
238
  devtoolsLog,
270
239
  settings,
271
240
  };
272
- const pageGraph = await PageDependencyGraph.request({trace, devtoolsLog, URL}, context);
273
241
  const simulator = await LoadSimulator.request(simulatorOptions, context);
274
242
  const metricComputationInput = Audit.makeMetricComputationDataInput(artifacts, context);
275
243
 
@@ -280,8 +248,6 @@ class UsesHTTP2Audit extends Audit {
280
248
  pessimisticGraph: lcpGraph,
281
249
  } = await LanternLargestContentfulPaint.request(metricComputationInput, context);
282
250
 
283
- const wastedMsTti = UsesHTTP2Audit.computeWasteWithTTIGraph(
284
- resources, pageGraph, simulator);
285
251
  const wasteFcp =
286
252
  UsesHTTP2Audit.computeWasteWithGraph(resources,
287
253
  fcpGraph, simulator, {label: 'fcp'});
@@ -296,11 +262,11 @@ class UsesHTTP2Audit extends Audit {
296
262
  ];
297
263
 
298
264
  const details = Audit.makeOpportunityDetails(headings, resources,
299
- {overallSavingsMs: wastedMsTti});
265
+ {overallSavingsMs: wasteLcp.savings});
300
266
 
301
267
  return {
302
268
  displayValue,
303
- numericValue: wastedMsTti,
269
+ numericValue: wasteLcp.savings,
304
270
  numericUnit: 'millisecond',
305
271
  score: resources.length ? 0 : 1,
306
272
  details,
@@ -50,7 +50,7 @@ class FontDisplay extends Audit {
50
50
  description: str_(UIStrings.description),
51
51
  supportedModes: ['navigation'],
52
52
  guidanceLevel: 3,
53
- requiredArtifacts: ['devtoolsLogs', 'CSSUsage', 'URL'],
53
+ requiredArtifacts: ['devtoolsLogs', 'Stylesheets', 'URL'],
54
54
  scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
55
55
  };
56
56
  }
@@ -67,7 +67,7 @@ class FontDisplay extends Audit {
67
67
  const failingURLs = new Set();
68
68
 
69
69
  // Go through all the stylesheets to find all @font-face declarations
70
- for (const stylesheet of artifacts.CSSUsage.stylesheets) {
70
+ for (const stylesheet of artifacts.Stylesheets) {
71
71
  // Eliminate newlines so we can more easily scan through with a regex
72
72
  const newlinesStripped = stylesheet.content.replace(/(\r|\n)+/g, ' ');
73
73
  // Find the @font-faces
@@ -61,7 +61,7 @@ class LayoutShifts extends Audit {
61
61
  static async audit(artifacts, context) {
62
62
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
63
63
  const traceEngineResult = await TraceEngineResult.request({trace}, context);
64
- const clusters = traceEngineResult.LayoutShifts.clusters ?? [];
64
+ const clusters = traceEngineResult.data.LayoutShifts.clusters ?? [];
65
65
  const {cumulativeLayoutShift: clsSavings, impactByNodeId} =
66
66
  await CumulativeLayoutShiftComputed.request(trace, context);
67
67
  const traceElements = artifacts.TraceElements
@@ -78,7 +78,7 @@ class LayoutShifts extends Audit {
78
78
  .slice(0, MAX_LAYOUT_SHIFTS);
79
79
  for (const event of topLayoutShiftEvents) {
80
80
  const biggestImpactNodeId = TraceElements.getBiggestImpactNodeForShiftEvent(
81
- event.args.data.impacted_nodes || [], impactByNodeId);
81
+ event.args.data.impacted_nodes || [], impactByNodeId, event);
82
82
  const biggestImpactElement = traceElements.find(t => t.nodeId === biggestImpactNodeId);
83
83
 
84
84
  // Turn root causes into sub-items.
@@ -14,11 +14,7 @@ declare class PreloadFontsAudit extends Audit {
14
14
  * @param {LH.Audit.Context} context
15
15
  * @return {Promise<LH.Audit.Product>}
16
16
  */
17
- static audit_(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
18
- /**
19
- * @return {Promise<LH.Audit.Product>}
20
- */
21
- static audit(): Promise<LH.Audit.Product>;
17
+ static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
22
18
  }
23
19
  export namespace UIStrings {
24
20
  const title: string;
@@ -62,7 +62,7 @@ class PreloadFontsAudit extends Audit {
62
62
  * @param {LH.Audit.Context} context
63
63
  * @return {Promise<LH.Audit.Product>}
64
64
  */
65
- static async audit_(artifacts, context) {
65
+ static async audit(artifacts, context) {
66
66
  const devtoolsLog = artifacts.devtoolsLogs[this.DEFAULT_PASS];
67
67
  const networkRecords = await NetworkRecords.request(devtoolsLog, context);
68
68
 
@@ -91,15 +91,6 @@ class PreloadFontsAudit extends Audit {
91
91
  notApplicable: optionalFontURLs.size === 0,
92
92
  };
93
93
  }
94
-
95
- /**
96
- * @return {Promise<LH.Audit.Product>}
97
- */
98
- static async audit() {
99
- // Preload advice is on hold until https://github.com/GoogleChrome/lighthouse/issues/11960
100
- // is resolved.
101
- return {score: 1, notApplicable: true};
102
- }
103
94
  }
104
95
 
105
96
  export default PreloadFontsAudit;
@@ -194,8 +194,8 @@ class PrioritizeLcpImage extends Audit {
194
194
  modifiedLCPNode.removeAllDependencies();
195
195
  modifiedLCPNode.addDependency(mainDocumentNode);
196
196
 
197
- const simulationBeforeChanges = simulator.simulate(graph, {flexibleOrdering: true});
198
- const simulationAfterChanges = simulator.simulate(modifiedGraph, {flexibleOrdering: true});
197
+ const simulationBeforeChanges = simulator.simulate(graph);
198
+ const simulationAfterChanges = simulator.simulate(modifiedGraph);
199
199
  const lcpTimingsBefore = simulationBeforeChanges.nodeTimings.get(lcpNode);
200
200
  if (!lcpTimingsBefore) throw new Error('Impossible - node timings should never be undefined');
201
201
  const lcpTimingsAfter = simulationAfterChanges.nodeTimings.get(modifiedLCPNode);
@@ -0,0 +1,19 @@
1
+ export default RedirectsHTTP;
2
+ /**
3
+ * An audit for checking if a site starting on http redirects to https. The audit
4
+ * is marked not applicable if the requestedUrl is already https.
5
+ */
6
+ declare class RedirectsHTTP extends Audit {
7
+ /**
8
+ * @param {LH.Artifacts} artifacts
9
+ * @return {LH.Audit.Product}
10
+ */
11
+ static audit(artifacts: LH.Artifacts): LH.Audit.Product;
12
+ }
13
+ export namespace UIStrings {
14
+ const title: string;
15
+ const failureTitle: string;
16
+ const description: string;
17
+ }
18
+ import { Audit } from './audit.js';
19
+ //# sourceMappingURL=redirects-http.d.ts.map
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @license Copyright 2024 The Lighthouse Authors. All Rights Reserved.
3
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
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
+ */
6
+
7
+ import {Audit} from './audit.js';
8
+ import * as i18n from '../lib/i18n/i18n.js';
9
+ import UrlUtils from '../lib/url-utils.js';
10
+
11
+ const UIStrings = {
12
+ /** Title of a Lighthouse audit that provides detail on HTTP to HTTPS redirects. This descriptive title is shown to users when HTTP traffic is redirected to HTTPS. */
13
+ title: 'Redirects HTTP traffic to HTTPS',
14
+ /** Title of a Lighthouse audit that provides detail on HTTP to HTTPS redirects. This descriptive title is shown to users when HTTP traffic is not redirected to HTTPS. */
15
+ failureTitle: 'Does not redirect HTTP traffic to HTTPS',
16
+ /** Description of a Lighthouse audit that tells the user why they should direct HTTP traffic to HTTPS. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
17
+ description: 'Make sure that you redirect all HTTP ' +
18
+ 'traffic to HTTPS in order to enable secure web features for all your users. [Learn more](https://developer.chrome.com/docs/lighthouse/pwa/redirects-http/).',
19
+ };
20
+
21
+ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
22
+
23
+ /**
24
+ * An audit for checking if a site starting on http redirects to https. The audit
25
+ * is marked not applicable if the requestedUrl is already https.
26
+ */
27
+ class RedirectsHTTP extends Audit {
28
+ /**
29
+ * @return {LH.Audit.Meta}
30
+ */
31
+ static get meta() {
32
+ return {
33
+ id: 'redirects-http',
34
+ title: str_(UIStrings.title),
35
+ failureTitle: str_(UIStrings.failureTitle),
36
+ description: str_(UIStrings.description),
37
+ requiredArtifacts: ['URL'],
38
+ supportedModes: ['navigation'],
39
+ };
40
+ }
41
+
42
+ /**
43
+ * @param {LH.Artifacts} artifacts
44
+ * @return {LH.Audit.Product}
45
+ */
46
+ static audit(artifacts) {
47
+ if (!artifacts.URL.requestedUrl) {
48
+ throw new Error('Missing requestedUrl');
49
+ }
50
+
51
+ const requestedUrl = new URL(artifacts.URL.requestedUrl);
52
+ const finalDisplayedUrl = new URL(artifacts.URL.finalDisplayedUrl);
53
+
54
+ // Not applicable unless starting on http.
55
+ const startedInsecure = requestedUrl.protocol === 'http:';
56
+
57
+ // Relax requirements on localhost.
58
+ const isLocalhost = UrlUtils.isLikeLocalhost(finalDisplayedUrl.hostname);
59
+
60
+ if (!startedInsecure || isLocalhost) {
61
+ return {
62
+ score: null,
63
+ notApplicable: true,
64
+ };
65
+ }
66
+
67
+ const endedSecure = finalDisplayedUrl.protocol === 'https:';
68
+ return {
69
+ score: Number(endedSecure),
70
+ };
71
+ }
72
+ }
73
+
74
+ export default RedirectsHTTP;
75
+ export {UIStrings};
@@ -1,4 +1,6 @@
1
1
  export default ResourceSummary;
2
+ export type ResourceType = import('../computed/resource-summary.js').ResourceType;
3
+ /** @typedef {import('../computed/resource-summary.js').ResourceType} ResourceType */
2
4
  declare class ResourceSummary extends Audit {
3
5
  /**
4
6
  * @param {LH.Artifacts} artifacts
@@ -10,6 +10,8 @@ import * as i18n from '../lib/i18n/i18n.js';
10
10
 
11
11
  const str_ = i18n.createIcuMessageFn(import.meta.url);
12
12
 
13
+ /** @typedef {import('../computed/resource-summary.js').ResourceType} ResourceType */
14
+
13
15
  class ResourceSummary extends Audit {
14
16
  /**
15
17
  * @return {LH.Audit.Meta}
@@ -32,7 +34,7 @@ class ResourceSummary extends Audit {
32
34
  static async audit(artifacts, context) {
33
35
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
34
36
  const summary = await ComputedResourceSummary
35
- .request({devtoolsLog, URL: artifacts.URL, budgets: context.settings.budgets}, context);
37
+ .request({devtoolsLog, URL: artifacts.URL}, context);
36
38
 
37
39
  /** @type {LH.Audit.Details.Table['headings']} */
38
40
  const headings = [
@@ -41,8 +43,7 @@ class ResourceSummary extends Audit {
41
43
  {key: 'transferSize', valueType: 'bytes', label: str_(i18n.UIStrings.columnTransferSize)},
42
44
  ];
43
45
 
44
-
45
- /** @type {Record<LH.Budget.ResourceType, LH.IcuMessage>} */
46
+ /** @type {Record<ResourceType, LH.IcuMessage>} */
46
47
  const strMappings = {
47
48
  'total': str_(i18n.UIStrings.totalResourceType),
48
49
  'document': str_(i18n.UIStrings.documentResourceType),
@@ -55,7 +56,7 @@ class ResourceSummary extends Audit {
55
56
  'third-party': str_(i18n.UIStrings.thirdPartyResourceType),
56
57
  };
57
58
 
58
- const types = /** @type {Array<LH.Budget.ResourceType>} */ (Object.keys(summary));
59
+ const types = /** @type {Array<ResourceType>} */ (Object.keys(summary));
59
60
  const rows = types.map(type => {
60
61
  return {
61
62
  // ResourceType is included as an "id" for ease of use.
@@ -6,11 +6,12 @@ declare class IsCrawlable extends Audit {
6
6
  static handleMetaElement(metaElement: LH.Artifacts.MetaElement): {
7
7
  source: {
8
8
  snippet: string;
9
+ /** @type {Array<string|undefined>} */
9
10
  type: "node";
10
11
  lhId?: string | undefined;
11
12
  path?: string | undefined;
12
13
  selector?: string | undefined;
13
- boundingRect?: import("../../../types/lhr/audit-details.js").default.Rect | undefined;
14
+ boundingRect?: import("../../../types/lhr/audit-details.js").default.Rect | undefined; /** @type {Array<string|undefined>} */
14
15
  nodeLabel?: string | undefined;
15
16
  };
16
17
  } | undefined;
@@ -84,6 +84,18 @@ const BLOCKLIST = new Set([
84
84
  'மேலும் தரவுகளுக்கு',
85
85
  'தயவுசெய்து இங்கே அழுத்தவும்',
86
86
  'இங்கே கிளிக் செய்யவும்',
87
+ // Persian
88
+ 'اطلاعات بیشتر',
89
+ 'اطلاعات',
90
+ 'این',
91
+ 'اینجا بزنید',
92
+ 'اینجا کلیک کنید',
93
+ 'اینجا',
94
+ 'برو',
95
+ 'بیشتر بخوانید',
96
+ 'بیشتر بدانید',
97
+ 'بیشتر',
98
+ 'شروع',
87
99
  ]);
88
100
 
89
101
  const UIStrings = {