lighthouse 8.0.0-dev.20210709 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/docs/architecture.md +101 -0
  2. package/docs/authenticated-pages.md +44 -0
  3. package/docs/bug-labels.md +35 -0
  4. package/docs/configuration.md +213 -0
  5. package/docs/emulation.md +32 -0
  6. package/docs/error-reporting.md +42 -0
  7. package/docs/hacking-tips.md +55 -0
  8. package/docs/headless-chrome.md +119 -0
  9. package/docs/lantern.md +55 -0
  10. package/docs/new-audits.md +99 -0
  11. package/docs/performance-budgets.md +187 -0
  12. package/docs/plugins.md +374 -0
  13. package/docs/puppeteer.md +95 -0
  14. package/docs/readme.md +164 -0
  15. package/docs/recipes/auth/README.md +129 -0
  16. package/docs/recipes/auth/example-lh-auth.js +81 -0
  17. package/docs/recipes/auth/package.json +11 -0
  18. package/docs/recipes/auth/server/public/dashboard-unauthenticated.html +21 -0
  19. package/docs/recipes/auth/server/public/dashboard.html +25 -0
  20. package/docs/recipes/auth/server/public/home-unauthenticated.html +27 -0
  21. package/docs/recipes/auth/server/public/home.html +17 -0
  22. package/docs/recipes/auth/server/public/unauthenticated.html +22 -0
  23. package/docs/recipes/auth/server/server.js +85 -0
  24. package/docs/recipes/custom-audit/custom-config.js +36 -0
  25. package/docs/recipes/custom-audit/package.json +8 -0
  26. package/docs/recipes/custom-audit/readme.md +32 -0
  27. package/docs/recipes/custom-audit/searchable-audit.js +46 -0
  28. package/docs/recipes/custom-audit/searchable-gatherer.js +32 -0
  29. package/docs/recipes/custom-gatherer-puppeteer/custom-audit.js +34 -0
  30. package/{root.js → docs/recipes/custom-gatherer-puppeteer/custom-config.js} +23 -2
  31. package/docs/recipes/custom-gatherer-puppeteer/custom-gatherer.js +51 -0
  32. package/docs/recipes/custom-gatherer-puppeteer/package.json +13 -0
  33. package/docs/recipes/custom-gatherer-puppeteer/readme.md +7 -0
  34. package/docs/recipes/custom-gatherer-puppeteer/test.sh +9 -0
  35. package/docs/recipes/gulp/gulpfile.js +79 -0
  36. package/docs/recipes/gulp/package.json +12 -0
  37. package/docs/recipes/gulp/public/index.html +22 -0
  38. package/docs/recipes/gulp/readme.md +6 -0
  39. package/docs/recipes/integration-test/README.md +14 -0
  40. package/docs/recipes/integration-test/example-lh-auth.test.js +160 -0
  41. package/docs/recipes/integration-test/package.json +9 -0
  42. package/docs/recipes/lighthouse-plugin-example/audits/preload-as.js +46 -0
  43. package/docs/recipes/lighthouse-plugin-example/package.json +11 -0
  44. package/docs/recipes/lighthouse-plugin-example/plugin-recipe-screenshot.png +0 -0
  45. package/docs/recipes/lighthouse-plugin-example/plugin.js +24 -0
  46. package/docs/recipes/lighthouse-plugin-example/readme.md +53 -0
  47. package/docs/releasing.md +164 -0
  48. package/docs/scoring.md +79 -0
  49. package/docs/throttling.md +150 -0
  50. package/docs/understanding-results.md +209 -0
  51. package/docs/v8-perf-faq.md +244 -0
  52. package/docs/variability.md +150 -0
  53. package/jest.config.js +0 -3
  54. package/lighthouse-cli/bin.js +8 -6
  55. package/lighthouse-core/audits/accessibility/aria-command-name.js +1 -1
  56. package/lighthouse-core/audits/accessibility/aria-meter-name.js +1 -1
  57. package/lighthouse-core/audits/accessibility/aria-progressbar-name.js +1 -1
  58. package/lighthouse-core/audits/accessibility/aria-tooltip-name.js +1 -1
  59. package/lighthouse-core/audits/accessibility/aria-treeitem-name.js +1 -1
  60. package/lighthouse-core/audits/apple-touch-icon.js +0 -1
  61. package/lighthouse-core/audits/audit.js +3 -3
  62. package/lighthouse-core/audits/autocomplete.js +2 -2
  63. package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +14 -29
  64. package/lighthouse-core/audits/byte-efficiency/duplicated-javascript.js +2 -3
  65. package/lighthouse-core/audits/byte-efficiency/efficient-animated-content.js +1 -1
  66. package/lighthouse-core/audits/byte-efficiency/legacy-javascript.js +2 -3
  67. package/lighthouse-core/audits/byte-efficiency/modern-image-formats.js +15 -55
  68. package/lighthouse-core/audits/byte-efficiency/offscreen-images.js +4 -8
  69. package/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js +8 -15
  70. package/lighthouse-core/audits/byte-efficiency/total-byte-weight.js +9 -10
  71. package/lighthouse-core/audits/byte-efficiency/unminified-css.js +1 -1
  72. package/lighthouse-core/audits/byte-efficiency/unminified-javascript.js +1 -1
  73. package/lighthouse-core/audits/byte-efficiency/unused-css-rules.js +1 -1
  74. package/lighthouse-core/audits/byte-efficiency/unused-javascript.js +1 -2
  75. package/lighthouse-core/audits/byte-efficiency/uses-long-cache-ttl.js +2 -2
  76. package/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js +1 -2
  77. package/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +24 -46
  78. package/lighthouse-core/audits/byte-efficiency/uses-text-compression.js +1 -1
  79. package/lighthouse-core/audits/critical-request-chains.js +0 -1
  80. package/lighthouse-core/audits/csp-xss.js +1 -1
  81. package/lighthouse-core/audits/diagnostics.js +0 -1
  82. package/lighthouse-core/audits/dobetterweb/geolocation-on-start.js +0 -1
  83. package/lighthouse-core/audits/dobetterweb/inspector-issues.js +1 -1
  84. package/lighthouse-core/audits/dobetterweb/notification-on-start.js +0 -1
  85. package/lighthouse-core/audits/dobetterweb/uses-http2.js +0 -1
  86. package/lighthouse-core/audits/final-screenshot.js +4 -8
  87. package/lighthouse-core/audits/font-display.js +0 -1
  88. package/lighthouse-core/audits/installable-manifest.js +3 -4
  89. package/lighthouse-core/audits/largest-contentful-paint-element.js +0 -1
  90. package/lighthouse-core/audits/long-tasks.js +1 -1
  91. package/lighthouse-core/audits/maskable-icon.js +0 -1
  92. package/lighthouse-core/audits/metrics/first-contentful-paint-3g.js +2 -4
  93. package/lighthouse-core/audits/metrics/first-contentful-paint.js +2 -4
  94. package/lighthouse-core/audits/metrics/first-meaningful-paint.js +2 -4
  95. package/lighthouse-core/audits/metrics/interactive.js +2 -4
  96. package/lighthouse-core/audits/metrics/largest-contentful-paint.js +2 -4
  97. package/lighthouse-core/audits/metrics/max-potential-fid.js +2 -4
  98. package/lighthouse-core/audits/metrics/speed-index.js +2 -4
  99. package/lighthouse-core/audits/metrics/total-blocking-time.js +2 -10
  100. package/lighthouse-core/audits/metrics.js +2 -4
  101. package/lighthouse-core/audits/performance-budget.js +0 -1
  102. package/lighthouse-core/audits/predictive-perf.js +6 -9
  103. package/lighthouse-core/audits/preload-fonts.js +1 -11
  104. package/lighthouse-core/audits/preload-lcp-image.js +5 -18
  105. package/lighthouse-core/audits/redirects.js +8 -10
  106. package/lighthouse-core/audits/screenshot-thumbnails.js +13 -28
  107. package/lighthouse-core/audits/seo/canonical.js +1 -2
  108. package/lighthouse-core/audits/seo/font-size.js +4 -4
  109. package/lighthouse-core/audits/seo/hreflang.js +2 -3
  110. package/lighthouse-core/audits/seo/http-status-code.js +16 -21
  111. package/lighthouse-core/audits/seo/is-crawlable.js +3 -4
  112. package/lighthouse-core/audits/seo/robots-txt.js +2 -2
  113. package/lighthouse-core/audits/seo/tap-targets.js +5 -5
  114. package/lighthouse-core/audits/server-response-time.js +2 -20
  115. package/lighthouse-core/audits/splash-screen.js +0 -1
  116. package/lighthouse-core/audits/themed-omnibox.js +0 -1
  117. package/lighthouse-core/audits/third-party-facades.js +0 -1
  118. package/lighthouse-core/audits/third-party-summary.js +3 -1
  119. package/lighthouse-core/audits/timing-budget.js +2 -4
  120. package/lighthouse-core/audits/uses-rel-preconnect.js +9 -14
  121. package/lighthouse-core/audits/uses-rel-preload.js +2 -13
  122. package/lighthouse-core/computed/main-thread-tasks.js +2 -2
  123. package/lighthouse-core/computed/metrics/cumulative-layout-shift.js +3 -3
  124. package/lighthouse-core/computed/metrics/first-contentful-paint-all-frames.js +6 -6
  125. package/lighthouse-core/computed/metrics/first-contentful-paint.js +8 -9
  126. package/lighthouse-core/computed/metrics/first-meaningful-paint.js +9 -10
  127. package/lighthouse-core/computed/metrics/interactive.js +24 -25
  128. package/lighthouse-core/computed/metrics/lantern-first-contentful-paint.js +6 -6
  129. package/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js +6 -6
  130. package/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js +6 -6
  131. package/lighthouse-core/computed/metrics/lantern-metric.js +8 -16
  132. package/lighthouse-core/computed/metrics/largest-contentful-paint-all-frames.js +7 -7
  133. package/lighthouse-core/computed/metrics/largest-contentful-paint.js +9 -10
  134. package/lighthouse-core/computed/metrics/max-potential-fid.js +11 -8
  135. package/lighthouse-core/computed/metrics/metric.js +5 -32
  136. package/lighthouse-core/computed/metrics/speed-index.js +5 -6
  137. package/lighthouse-core/computed/metrics/timing-summary.js +45 -55
  138. package/lighthouse-core/computed/metrics/total-blocking-time.js +29 -36
  139. package/lighthouse-core/computed/page-dependency-graph.js +14 -14
  140. package/lighthouse-core/computed/resource-summary.js +7 -3
  141. package/lighthouse-core/computed/speedline.js +3 -3
  142. package/lighthouse-core/computed/trace-of-tab.js +86 -15
  143. package/lighthouse-core/computed/user-timings.js +5 -5
  144. package/lighthouse-core/config/default-config.js +0 -1
  145. package/lighthouse-core/fraggle-rock/config/config.js +7 -9
  146. package/lighthouse-core/fraggle-rock/config/default-config.js +2 -40
  147. package/lighthouse-core/fraggle-rock/config/filters.js +6 -39
  148. package/lighthouse-core/fraggle-rock/config/validation.js +4 -4
  149. package/lighthouse-core/fraggle-rock/gather/base-artifacts.js +19 -54
  150. package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +10 -21
  151. package/lighthouse-core/fraggle-rock/gather/runner-helpers.js +2 -2
  152. package/lighthouse-core/fraggle-rock/gather/snapshot-runner.js +2 -2
  153. package/lighthouse-core/fraggle-rock/gather/timespan-runner.js +2 -2
  154. package/lighthouse-core/gather/driver/prepare.js +0 -3
  155. package/lighthouse-core/gather/fetcher.js +2 -0
  156. package/lighthouse-core/gather/gather-runner.js +14 -2
  157. package/lighthouse-core/gather/gatherers/image-elements.js +61 -24
  158. package/lighthouse-core/gather/gatherers/inspector-issues.js +2 -2
  159. package/lighthouse-core/gather/gatherers/script-elements.js +12 -45
  160. package/lighthouse-core/gather/gatherers/seo/font-size.js +5 -5
  161. package/lighthouse-core/gather/gatherers/seo/tap-targets.js +12 -64
  162. package/lighthouse-core/gather/gatherers/service-worker.js +3 -20
  163. package/lighthouse-core/gather/gatherers/trace-compat.js +1 -1
  164. package/lighthouse-core/gather/gatherers/trace-elements.js +3 -15
  165. package/lighthouse-core/gather/gatherers/trace.js +4 -13
  166. package/lighthouse-core/gather/gatherers/viewport-dimensions.js +1 -1
  167. package/lighthouse-core/lib/dependency-graph/simulator/network-analyzer.js +2 -13
  168. package/lighthouse-core/lib/emulation.js +2 -0
  169. package/lighthouse-core/lib/i18n/i18n.js +2 -2
  170. package/lighthouse-core/lib/i18n/locales/ar-XB.json +141 -141
  171. package/lighthouse-core/lib/i18n/locales/ar.json +143 -143
  172. package/lighthouse-core/lib/i18n/locales/bg.json +143 -143
  173. package/lighthouse-core/lib/i18n/locales/ca.json +141 -141
  174. package/lighthouse-core/lib/i18n/locales/cs.json +141 -141
  175. package/lighthouse-core/lib/i18n/locales/da.json +141 -141
  176. package/lighthouse-core/lib/i18n/locales/de.json +142 -142
  177. package/lighthouse-core/lib/i18n/locales/el.json +141 -141
  178. package/lighthouse-core/lib/i18n/locales/en-GB.json +141 -141
  179. package/lighthouse-core/lib/i18n/locales/en-US.ctc.json +6659 -0
  180. package/lighthouse-core/lib/i18n/locales/en-US.json +144 -150
  181. package/lighthouse-core/lib/i18n/locales/en-XA.json +141 -141
  182. package/lighthouse-core/lib/i18n/locales/en-XL.ctc.json +6628 -0
  183. package/lighthouse-core/lib/i18n/locales/en-XL.json +144 -150
  184. package/lighthouse-core/lib/i18n/locales/es-419.json +141 -141
  185. package/lighthouse-core/lib/i18n/locales/es.json +141 -141
  186. package/lighthouse-core/lib/i18n/locales/fi.json +143 -143
  187. package/lighthouse-core/lib/i18n/locales/fil.json +142 -142
  188. package/lighthouse-core/lib/i18n/locales/fr.json +141 -141
  189. package/lighthouse-core/lib/i18n/locales/he.json +142 -142
  190. package/lighthouse-core/lib/i18n/locales/hi.json +143 -143
  191. package/lighthouse-core/lib/i18n/locales/hr.json +141 -141
  192. package/lighthouse-core/lib/i18n/locales/hu.json +143 -143
  193. package/lighthouse-core/lib/i18n/locales/id.json +143 -143
  194. package/lighthouse-core/lib/i18n/locales/it.json +143 -143
  195. package/lighthouse-core/lib/i18n/locales/ja.json +143 -143
  196. package/lighthouse-core/lib/i18n/locales/ko.json +143 -143
  197. package/lighthouse-core/lib/i18n/locales/lt.json +143 -143
  198. package/lighthouse-core/lib/i18n/locales/lv.json +143 -143
  199. package/lighthouse-core/lib/i18n/locales/nl.json +141 -141
  200. package/lighthouse-core/lib/i18n/locales/no.json +141 -141
  201. package/lighthouse-core/lib/i18n/locales/pl.json +141 -141
  202. package/lighthouse-core/lib/i18n/locales/pt-PT.json +141 -141
  203. package/lighthouse-core/lib/i18n/locales/pt.json +141 -141
  204. package/lighthouse-core/lib/i18n/locales/ro.json +144 -144
  205. package/lighthouse-core/lib/i18n/locales/ru.json +143 -143
  206. package/lighthouse-core/lib/i18n/locales/sk.json +142 -142
  207. package/lighthouse-core/lib/i18n/locales/sl.json +141 -141
  208. package/lighthouse-core/lib/i18n/locales/sr-Latn.json +143 -143
  209. package/lighthouse-core/lib/i18n/locales/sr.json +143 -143
  210. package/lighthouse-core/lib/i18n/locales/sv.json +142 -142
  211. package/lighthouse-core/lib/i18n/locales/ta.json +141 -141
  212. package/lighthouse-core/lib/i18n/locales/te.json +143 -143
  213. package/lighthouse-core/lib/i18n/locales/th.json +143 -143
  214. package/lighthouse-core/lib/i18n/locales/tr.json +143 -143
  215. package/lighthouse-core/lib/i18n/locales/uk.json +141 -141
  216. package/lighthouse-core/lib/i18n/locales/vi.json +143 -143
  217. package/lighthouse-core/lib/i18n/locales/zh-HK.json +141 -141
  218. package/lighthouse-core/lib/i18n/locales/zh-TW.json +143 -143
  219. package/lighthouse-core/lib/i18n/locales/zh.json +143 -143
  220. package/lighthouse-core/lib/lh-error.js +2 -2
  221. package/lighthouse-core/lib/minify-trace.js +1 -1
  222. package/lighthouse-core/lib/network-request.js +1 -17
  223. package/lighthouse-core/lib/page-functions.js +5 -6
  224. package/lighthouse-core/lib/rect-helpers.js +3 -3
  225. package/lighthouse-core/lib/sd-validation/assets/jsonldcontext.json +7137 -0
  226. package/lighthouse-core/lib/sd-validation/assets/schema-tree.json +9900 -0
  227. package/{report/report-assets.js → lighthouse-core/lib/sd-validation/helpers/walk-object.js} +20 -12
  228. package/lighthouse-core/lib/sd-validation/json-expander.js +56 -0
  229. package/lighthouse-core/lib/sd-validation/json-linter.js +49 -0
  230. package/lighthouse-core/lib/sd-validation/jsonld-keyword-validator.js +50 -0
  231. package/lighthouse-core/lib/sd-validation/line-number-from-jsonld-path.js +60 -0
  232. package/lighthouse-core/lib/sd-validation/schema-validator.js +146 -0
  233. package/lighthouse-core/lib/sd-validation/scripts/download-jsonldcontext.js +30 -0
  234. package/lighthouse-core/lib/sd-validation/scripts/generate-schema-tree.js +97 -0
  235. package/lighthouse-core/lib/sd-validation/sd-validation.js +77 -0
  236. package/lighthouse-core/lib/tappable-rects.js +1 -1
  237. package/lighthouse-core/lib/tracehouse/trace-processor.js +42 -116
  238. package/lighthouse-core/lib/url-shim.js +2 -29
  239. package/lighthouse-core/report/html/html-report-assets.js +38 -0
  240. package/{report/README.md → lighthouse-core/report/html/readme.md} +11 -7
  241. package/{report → lighthouse-core/report/html}/renderer/category-renderer.js +0 -0
  242. package/{report → lighthouse-core/report/html}/renderer/crc-details-renderer.js +0 -0
  243. package/{report → lighthouse-core/report/html}/renderer/details-renderer.js +1 -1
  244. package/{report → lighthouse-core/report/html}/renderer/dom.js +0 -0
  245. package/{report → lighthouse-core/report/html}/renderer/element-screenshot-renderer.js +0 -0
  246. package/{report → lighthouse-core/report/html}/renderer/i18n.js +1 -1
  247. package/{report → lighthouse-core/report/html}/renderer/logger.js +0 -0
  248. package/{report → lighthouse-core/report/html}/renderer/performance-category-renderer.js +0 -0
  249. package/{report → lighthouse-core/report/html}/renderer/psi.js +0 -0
  250. package/{report → lighthouse-core/report/html}/renderer/pwa-category-renderer.js +0 -0
  251. package/{report → lighthouse-core/report/html}/renderer/report-renderer.js +0 -0
  252. package/{report → lighthouse-core/report/html}/renderer/report-ui-features.js +3 -3
  253. package/{report → lighthouse-core/report/html}/renderer/snippet-renderer.js +0 -0
  254. package/{report → lighthouse-core/report/html}/renderer/text-encoding.js +0 -0
  255. package/{report → lighthouse-core/report/html}/renderer/util.js +4 -7
  256. package/{report/assets/styles.css → lighthouse-core/report/html/report-styles.css} +0 -0
  257. package/{report/assets/standalone-template.html → lighthouse-core/report/html/report-template.html} +41 -1
  258. package/{report/assets → lighthouse-core/report/html}/templates.html +0 -0
  259. package/{report → lighthouse-core/report}/report-generator.js +1 -1
  260. package/lighthouse-core/runner.js +1 -1
  261. package/package.json +12 -13
  262. package/readme.md +2 -2
  263. package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +2 -3
  264. package/third-party/chromium-synchronization/installability-errors-test.js +2 -2
  265. package/third-party/download-content-shell/download-content-shell.js +1 -2
  266. package/third-party/snyk/snapshot.json +1 -1
  267. package/tsconfig.json +1 -0
  268. package/types/artifacts.d.ts +21 -41
  269. package/types/audit.d.ts +0 -2
  270. package/types/config.d.ts +2 -16
  271. package/types/externs.d.ts +0 -1
  272. package/types/gatherer.d.ts +13 -13
  273. package/types/html-renderer.d.ts +14 -14
  274. package/types/i18n.d.ts +1 -1
  275. package/lighthouse-core/audits/byte-efficiency/uses-responsive-images-snapshot.js +0 -94
  276. package/lighthouse-core/computed/image-records.js +0 -62
  277. package/lighthouse-core/computed/metrics/navigation-metric.js +0 -46
  278. package/lighthouse-core/computed/processed-navigation.js +0 -21
  279. package/lighthouse-core/computed/processed-trace.js +0 -21
  280. package/lighthouse-core/gather/gatherers/gather-context.js +0 -25
  281. package/lighthouse-core/gather/gatherers/host-form-factor.js +0 -31
  282. package/lighthouse-core/gather/gatherers/host-user-agent.js +0 -29
  283. package/lighthouse-core/lib/lh-trace-processor.js +0 -46
  284. package/report/clients/standalone.js +0 -52
  285. package/report/test/renderer/category-renderer-test.js +0 -488
  286. package/report/test/renderer/crc-details-renderer-test.js +0 -115
  287. package/report/test/renderer/details-renderer-test.js +0 -843
  288. package/report/test/renderer/dom-test.js +0 -157
  289. package/report/test/renderer/element-screenshot-renderer-test.js +0 -189
  290. package/report/test/renderer/i18n-test.js +0 -146
  291. package/report/test/renderer/performance-category-renderer-test.js +0 -332
  292. package/report/test/renderer/psi-test.js +0 -152
  293. package/report/test/renderer/pwa-category-renderer-test.js +0 -303
  294. package/report/test/renderer/report-renderer-test.js +0 -325
  295. package/report/test/renderer/report-ui-features-test.js +0 -572
  296. package/report/test/renderer/snippet-renderer-test.js +0 -291
  297. package/report/test/renderer/text-encoding-test.js +0 -41
  298. package/report/test/renderer/util-test.js +0 -388
  299. package/report/test/report-generator-test.js +0 -145
@@ -53,13 +53,13 @@ const UIStrings = {
53
53
  * @description Error message explaining that the manifest does not contain a suitable icon.
54
54
  * @example {192} value0
55
55
  */
56
- 'manifest-missing-suitable-icon': `Manifest does not contain a suitable icon - PNG, SVG or WebP format of at least {value0}\xa0px is required, the sizes attribute must be set, and the purpose attribute, if set, must include "any".`,
56
+ 'manifest-missing-suitable-icon': `Manifest does not contain a suitable icon - PNG, SVG or WebP format of at least {value0}\xa0px is required, the sizes attribute must be set, and the purpose attribute, if set, must include "any" or "maskable".`,
57
57
 
58
58
  /**
59
59
  * @description Error message explaining that the manifest does not supply an icon of the correct format.
60
60
  * @example {192} value0
61
61
  */
62
- 'no-acceptable-icon': `No supplied icon is at least {value0}\xa0px square in PNG, SVG or WebP format, with the purpose attribute unset or set to "any"`,
62
+ 'no-acceptable-icon': `No supplied icon is at least {value0}\xa0px square in PNG, SVG or WebP format`,
63
63
 
64
64
  /** Error message explaining that the icon could not be downloaded. */
65
65
  'cannot-download-icon': `Could not download a required icon from the manifest`,
@@ -105,7 +105,7 @@ const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
105
105
  *
106
106
  * Requirements based on Chrome Devtools' installability requirements.
107
107
  * Origin of logging:
108
- * https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/installable/installable_logging.cc
108
+ * https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/installable/installable_logging.cc
109
109
  * DevTools InstallabilityError implementation:
110
110
  * https://source.chromium.org/search?q=getInstallabilityErrorMessages&ss=chromium%2Fchromium%2Fsrc:third_party%2Fdevtools-frontend%2Fsrc%2Ffront_end%2Fresources%2F
111
111
  */
@@ -120,7 +120,6 @@ class InstallableManifest extends Audit {
120
120
  title: str_(UIStrings.title),
121
121
  failureTitle: str_(UIStrings.failureTitle),
122
122
  description: str_(UIStrings.description),
123
- supportedModes: ['navigation'],
124
123
  requiredArtifacts: ['URL', 'WebAppManifest', 'InstallabilityErrors'],
125
124
  };
126
125
  }
@@ -28,7 +28,6 @@ class LargestContentfulPaintElement extends Audit {
28
28
  title: str_(UIStrings.title),
29
29
  description: str_(UIStrings.description),
30
30
  scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE,
31
- supportedModes: ['navigation'],
32
31
  requiredArtifacts: ['traces', 'TraceElements'],
33
32
  };
34
33
  }
@@ -62,7 +62,7 @@ class LongTasks extends Audit {
62
62
  const taskTimingsByEvent = new Map();
63
63
 
64
64
  if (settings.throttlingMethod === 'simulate') {
65
- const simulatorOptions = {devtoolsLog, settings: context.settings};
65
+ const simulatorOptions = {trace, devtoolsLog, settings: context.settings};
66
66
  const pageGraph = await PageDependencyGraph.request({trace, devtoolsLog}, context);
67
67
  const simulator = await LoadSimulator.request(simulatorOptions, context);
68
68
  const simulation = await simulator.simulate(pageGraph, {label: 'long-tasks-diagnostic'});
@@ -42,7 +42,6 @@ class MaskableIcon extends Audit {
42
42
  title: str_(UIStrings.title),
43
43
  failureTitle: str_(UIStrings.failureTitle),
44
44
  description: str_(UIStrings.description),
45
- supportedModes: ['navigation'],
46
45
  requiredArtifacts: ['WebAppManifest', 'InstallabilityErrors'],
47
46
  };
48
47
  }
@@ -20,8 +20,7 @@ class FirstContentfulPaint3G extends Audit {
20
20
  description: 'First Contentful Paint 3G marks the time at which the first text or image is ' +
21
21
  `painted while on a 3G network. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint).`,
22
22
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
23
- supportedModes: ['navigation'],
24
- requiredArtifacts: ['traces', 'devtoolsLogs', 'GatherContext'],
23
+ requiredArtifacts: ['traces', 'devtoolsLogs'],
25
24
  };
26
25
  }
27
26
 
@@ -44,12 +43,11 @@ class FirstContentfulPaint3G extends Audit {
44
43
  * @return {Promise<LH.Audit.Product>}
45
44
  */
46
45
  static async audit(artifacts, context) {
47
- const gatherContext = artifacts.GatherContext;
48
46
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
49
47
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
50
48
  /** @type {Immutable<LH.Config.Settings>} */
51
49
  const settings = {...context.settings, throttlingMethod: 'simulate', throttling: regular3G};
52
- const metricComputationData = {trace, devtoolsLog, gatherContext, settings};
50
+ const metricComputationData = {trace, devtoolsLog, settings};
53
51
  const metricResult = await ComputedFcp.request(metricComputationData, context);
54
52
 
55
53
  return {
@@ -27,8 +27,7 @@ class FirstContentfulPaint extends Audit {
27
27
  title: str_(i18n.UIStrings.firstContentfulPaintMetric),
28
28
  description: str_(UIStrings.description),
29
29
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
30
- supportedModes: ['navigation'],
31
- requiredArtifacts: ['traces', 'devtoolsLogs', 'GatherContext'],
30
+ requiredArtifacts: ['traces', 'devtoolsLogs'],
32
31
  };
33
32
  }
34
33
 
@@ -64,8 +63,7 @@ class FirstContentfulPaint extends Audit {
64
63
  static async audit(artifacts, context) {
65
64
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
66
65
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
67
- const gatherContext = artifacts.GatherContext;
68
- const metricComputationData = {trace, devtoolsLog, gatherContext, settings: context.settings};
66
+ const metricComputationData = {trace, devtoolsLog, settings: context.settings};
69
67
  const metricResult = await ComputedFcp.request(metricComputationData, context);
70
68
  const options = context.options[context.settings.formFactor];
71
69
 
@@ -27,8 +27,7 @@ class FirstMeaningfulPaint extends Audit {
27
27
  title: str_(i18n.UIStrings.firstMeaningfulPaintMetric),
28
28
  description: str_(UIStrings.description),
29
29
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
30
- supportedModes: ['navigation'],
31
- requiredArtifacts: ['traces', 'devtoolsLogs', 'GatherContext'],
30
+ requiredArtifacts: ['traces', 'devtoolsLogs'],
32
31
  };
33
32
  }
34
33
 
@@ -67,8 +66,7 @@ class FirstMeaningfulPaint extends Audit {
67
66
  static async audit(artifacts, context) {
68
67
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
69
68
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
70
- const gatherContext = artifacts.GatherContext;
71
- const metricComputationData = {trace, devtoolsLog, gatherContext, settings: context.settings};
69
+ const metricComputationData = {trace, devtoolsLog, settings: context.settings};
72
70
  const metricResult = await ComputedFmp.request(metricComputationData, context);
73
71
  const options = context.options[context.settings.formFactor];
74
72
 
@@ -33,8 +33,7 @@ class InteractiveMetric extends Audit {
33
33
  title: str_(i18n.UIStrings.interactiveMetric),
34
34
  description: str_(UIStrings.description),
35
35
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
36
- supportedModes: ['navigation'],
37
- requiredArtifacts: ['traces', 'devtoolsLogs', 'GatherContext'],
36
+ requiredArtifacts: ['traces', 'devtoolsLogs'],
38
37
  };
39
38
  }
40
39
 
@@ -70,8 +69,7 @@ class InteractiveMetric extends Audit {
70
69
  static async audit(artifacts, context) {
71
70
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
72
71
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
73
- const gatherContext = artifacts.GatherContext;
74
- const metricComputationData = {trace, devtoolsLog, gatherContext, settings: context.settings};
72
+ const metricComputationData = {trace, devtoolsLog, settings: context.settings};
75
73
  const metricResult = await Interactive.request(metricComputationData, context);
76
74
  const timeInMs = metricResult.timing;
77
75
  const options = context.options[context.settings.formFactor];
@@ -28,8 +28,7 @@ class LargestContentfulPaint extends Audit {
28
28
  title: str_(i18n.UIStrings.largestContentfulPaintMetric),
29
29
  description: str_(UIStrings.description),
30
30
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
31
- supportedModes: ['navigation'],
32
- requiredArtifacts: ['HostUserAgent', 'traces', 'devtoolsLogs', 'GatherContext'],
31
+ requiredArtifacts: ['HostUserAgent', 'traces', 'devtoolsLogs'],
33
32
  };
34
33
  }
35
34
 
@@ -73,8 +72,7 @@ class LargestContentfulPaint extends Audit {
73
72
  static async audit(artifacts, context) {
74
73
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
75
74
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
76
- const gatherContext = artifacts.GatherContext;
77
- const metricComputationData = {trace, devtoolsLog, gatherContext, settings: context.settings};
75
+ const metricComputationData = {trace, devtoolsLog, settings: context.settings};
78
76
 
79
77
  let metricResult;
80
78
  try {
@@ -32,8 +32,7 @@ class MaxPotentialFID extends Audit {
32
32
  title: str_(i18n.UIStrings.maxPotentialFIDMetric),
33
33
  description: str_(UIStrings.description),
34
34
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
35
- supportedModes: ['navigation'],
36
- requiredArtifacts: ['traces', 'devtoolsLogs', 'GatherContext'],
35
+ requiredArtifacts: ['traces', 'devtoolsLogs'],
37
36
  };
38
37
  }
39
38
 
@@ -56,8 +55,7 @@ class MaxPotentialFID extends Audit {
56
55
  static async audit(artifacts, context) {
57
56
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
58
57
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
59
- const gatherContext = artifacts.GatherContext;
60
- const metricComputationData = {trace, devtoolsLog, gatherContext, settings: context.settings};
58
+ const metricComputationData = {trace, devtoolsLog, settings: context.settings};
61
59
  const metricResult = await ComputedFid.request(metricComputationData, context);
62
60
 
63
61
  return {
@@ -27,8 +27,7 @@ class SpeedIndex extends Audit {
27
27
  title: str_(i18n.UIStrings.speedIndexMetric),
28
28
  description: str_(UIStrings.description),
29
29
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
30
- supportedModes: ['navigation'],
31
- requiredArtifacts: ['traces', 'devtoolsLogs', 'GatherContext'],
30
+ requiredArtifacts: ['traces', 'devtoolsLogs'],
32
31
  };
33
32
  }
34
33
 
@@ -66,8 +65,7 @@ class SpeedIndex extends Audit {
66
65
  static async audit(artifacts, context) {
67
66
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
68
67
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
69
- const gatherContext = artifacts.GatherContext;
70
- const metricComputationData = {trace, devtoolsLog, gatherContext, settings: context.settings};
68
+ const metricComputationData = {trace, devtoolsLog, settings: context.settings};
71
69
  const metricResult = await ComputedSi.request(metricComputationData, context);
72
70
  const options = context.options[context.settings.formFactor];
73
71
 
@@ -27,7 +27,7 @@ class TotalBlockingTime extends Audit {
27
27
  title: str_(i18n.UIStrings.totalBlockingTimeMetric),
28
28
  description: str_(UIStrings.description),
29
29
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
30
- requiredArtifacts: ['traces', 'devtoolsLogs', 'GatherContext'],
30
+ requiredArtifacts: ['traces', 'devtoolsLogs'],
31
31
  };
32
32
  }
33
33
 
@@ -87,15 +87,7 @@ class TotalBlockingTime extends Audit {
87
87
  static async audit(artifacts, context) {
88
88
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
89
89
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
90
- const gatherContext = artifacts.GatherContext;
91
- const metricComputationData = {trace, devtoolsLog, gatherContext, settings: context.settings};
92
- if (
93
- gatherContext.gatherMode === 'timespan' &&
94
- context.settings.throttlingMethod === 'simulate'
95
- ) {
96
- return {score: 1, notApplicable: true};
97
- }
98
-
90
+ const metricComputationData = {trace, devtoolsLog, settings: context.settings};
99
91
  const metricResult = await ComputedTBT.request(metricComputationData, context);
100
92
 
101
93
  const options = context.options[context.settings.formFactor];
@@ -28,8 +28,7 @@ class Metrics extends Audit {
28
28
  scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE,
29
29
  title: 'Metrics',
30
30
  description: 'Collects all available metrics.',
31
- supportedModes: ['navigation'],
32
- requiredArtifacts: ['traces', 'devtoolsLogs', 'GatherContext'],
31
+ requiredArtifacts: ['traces', 'devtoolsLogs'],
33
32
  };
34
33
  }
35
34
 
@@ -39,11 +38,10 @@ class Metrics extends Audit {
39
38
  * @return {Promise<LH.Audit.Product>}
40
39
  */
41
40
  static async audit(artifacts, context) {
42
- const gatherContext = artifacts.GatherContext;
43
41
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
44
42
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
45
43
  const summary = await ComputedTimingSummary
46
- .request({trace, devtoolsLog, gatherContext, settings: context.settings}, context);
44
+ .request({trace, devtoolsLog, settings: context.settings}, context);
47
45
  const metrics = summary.metrics;
48
46
  const debugInfo = summary.debugInfo;
49
47
 
@@ -39,7 +39,6 @@ class ResourceBudget extends Audit {
39
39
  title: str_(UIStrings.title),
40
40
  description: str_(UIStrings.description),
41
41
  scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE,
42
- supportedModes: ['navigation'],
43
42
  requiredArtifacts: ['devtoolsLogs', 'URL'],
44
43
  };
45
44
  }
@@ -33,8 +33,7 @@ class PredictivePerf extends Audit {
33
33
  'Predicted performance evaluates how your site will perform under ' +
34
34
  'a cellular connection on a mobile device.',
35
35
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
36
- supportedModes: ['navigation'],
37
- requiredArtifacts: ['traces', 'devtoolsLogs', 'GatherContext'],
36
+ requiredArtifacts: ['traces', 'devtoolsLogs'],
38
37
  };
39
38
  }
40
39
 
@@ -44,18 +43,16 @@ class PredictivePerf extends Audit {
44
43
  * @return {Promise<LH.Audit.Product>}
45
44
  */
46
45
  static async audit(artifacts, context) {
47
- const gatherContext = artifacts.GatherContext;
48
46
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
49
47
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
50
48
  /** @type {LH.Config.Settings} */
51
49
  // @ts-expect-error - TODO(bckenny): allow optional `throttling` settings
52
50
  const settings = {}; // Use default settings.
53
- const computationData = {trace, devtoolsLog, gatherContext, settings};
54
- const fcp = await LanternFcp.request(computationData, context);
55
- const fmp = await LanternFmp.request(computationData, context);
56
- const tti = await LanternInteractive.request(computationData, context);
57
- const si = await LanternSpeedIndex.request(computationData, context);
58
- const lcp = await LanternLcp.request(computationData, context);
51
+ const fcp = await LanternFcp.request({trace, devtoolsLog, settings}, context);
52
+ const fmp = await LanternFmp.request({trace, devtoolsLog, settings}, context);
53
+ const tti = await LanternInteractive.request({trace, devtoolsLog, settings}, context);
54
+ const si = await LanternSpeedIndex.request({trace, devtoolsLog, settings}, context);
55
+ const lcp = await LanternLcp.request({trace, devtoolsLog, settings}, context);
59
56
 
60
57
  const values = {
61
58
  roughEstimateOfFCP: fcp.timing,
@@ -63,7 +63,7 @@ class PreloadFontsAudit extends Audit {
63
63
  * @param {LH.Audit.Context} context
64
64
  * @return {Promise<LH.Audit.Product>}
65
65
  */
66
- static async audit_(artifacts, context) {
66
+ static async audit(artifacts, context) {
67
67
  const devtoolsLog = artifacts.devtoolsLogs[this.DEFAULT_PASS];
68
68
  const networkRecords = await NetworkRecords.request(devtoolsLog, context);
69
69
 
@@ -92,16 +92,6 @@ class PreloadFontsAudit extends Audit {
92
92
  notApplicable: optionalFontURLs.size === 0,
93
93
  };
94
94
  }
95
-
96
- /**
97
- * @return {Promise<LH.Audit.Product>}
98
- */
99
- static async audit() {
100
- // Preload advice is dangerous until https://bugs.chromium.org/p/chromium/issues/detail?id=788757
101
- // has been fixed and validated. All preload audits are on hold until then.
102
- // See https://github.com/GoogleChrome/lighthouse/issues/11960 for more discussion.
103
- return {score: 1, notApplicable: true};
104
- }
105
95
  }
106
96
 
107
97
  module.exports = PreloadFontsAudit;
@@ -32,9 +32,7 @@ class PreloadLCPImageAudit extends Audit {
32
32
  id: 'preload-lcp-image',
33
33
  title: str_(UIStrings.title),
34
34
  description: str_(UIStrings.description),
35
- supportedModes: ['navigation'],
36
- requiredArtifacts: ['traces', 'devtoolsLogs', 'GatherContext', 'URL', 'TraceElements',
37
- 'ImageElements'],
35
+ requiredArtifacts: ['traces', 'devtoolsLogs', 'URL', 'TraceElements', 'ImageElements'],
38
36
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
39
37
  };
40
38
  }
@@ -196,19 +194,18 @@ class PreloadLCPImageAudit extends Audit {
196
194
  * @param {LH.Audit.Context} context
197
195
  * @return {Promise<LH.Audit.Product>}
198
196
  */
199
- static async audit_(artifacts, context) {
200
- const gatherContext = artifacts.GatherContext;
197
+ static async audit(artifacts, context) {
201
198
  const trace = artifacts.traces[PreloadLCPImageAudit.DEFAULT_PASS];
202
199
  const devtoolsLog = artifacts.devtoolsLogs[PreloadLCPImageAudit.DEFAULT_PASS];
203
200
  const URL = artifacts.URL;
204
- const metricData = {trace, devtoolsLog, gatherContext, settings: context.settings};
201
+ const simulatorOptions = {trace, devtoolsLog, settings: context.settings};
205
202
  const lcpElement = artifacts.TraceElements
206
203
  .find(element => element.traceEventType === 'largest-contentful-paint');
207
204
 
208
205
  const [mainResource, lanternLCP, simulator] = await Promise.all([
209
206
  MainResource.request({devtoolsLog, URL}, context),
210
- LanternLCP.request(metricData, context),
211
- LoadSimulator.request({devtoolsLog, settings: context.settings}, context),
207
+ LanternLCP.request(simulatorOptions, context),
208
+ LoadSimulator.request(simulatorOptions, context),
212
209
  ]);
213
210
 
214
211
  const graph = lanternLCP.pessimisticGraph;
@@ -234,16 +231,6 @@ class PreloadLCPImageAudit extends Audit {
234
231
  details,
235
232
  };
236
233
  }
237
-
238
- /**
239
- * @return {Promise<LH.Audit.Product>}
240
- */
241
- static async audit() {
242
- // Preload advice is dangerous until https://bugs.chromium.org/p/chromium/issues/detail?id=788757
243
- // has been fixed and validated. All preload audits are on hold until then.
244
- // See https://github.com/GoogleChrome/lighthouse/issues/11960 for more discussion.
245
- return {score: 1, notApplicable: true, details: Audit.makeOpportunityDetails([], [], 0)};
246
- }
247
234
  }
248
235
 
249
236
  module.exports = PreloadLCPImageAudit;
@@ -8,7 +8,7 @@
8
8
  const Audit = require('./audit.js');
9
9
  const UnusedBytes = require('./byte-efficiency/byte-efficiency-audit.js');
10
10
  const i18n = require('../lib/i18n/i18n.js');
11
- const ProcessedTrace = require('../computed/processed-trace.js');
11
+ const TraceOfTab = require('../computed/trace-of-tab.js');
12
12
  const NetworkRecords = require('../computed/network-records.js');
13
13
  const MainResource = require('../computed/main-resource.js');
14
14
  const LanternInteractive = require('../computed/metrics/lantern-interactive.js');
@@ -32,8 +32,7 @@ class Redirects extends Audit {
32
32
  title: str_(UIStrings.title),
33
33
  description: str_(UIStrings.description),
34
34
  scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
35
- supportedModes: ['navigation'],
36
- requiredArtifacts: ['URL', 'GatherContext', 'devtoolsLogs', 'traces'],
35
+ requiredArtifacts: ['URL', 'devtoolsLogs', 'traces'],
37
36
  };
38
37
  }
39
38
 
@@ -50,15 +49,15 @@ class Redirects extends Audit {
50
49
  *
51
50
  * @param {LH.Artifacts.NetworkRequest} mainResource
52
51
  * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
53
- * @param {LH.Artifacts.ProcessedTrace} processedTrace
52
+ * @param {LH.Artifacts.TraceOfTab} traceOfTab
54
53
  * @return {Array<LH.Artifacts.NetworkRequest>}
55
54
  */
56
- static getDocumentRequestChain(mainResource, networkRecords, processedTrace) {
55
+ static getDocumentRequestChain(mainResource, networkRecords, traceOfTab) {
57
56
  /** @type {Array<LH.Artifacts.NetworkRequest>} */
58
57
  const documentRequests = [];
59
58
 
60
59
  // Find all the document requests by examining navigation events and their redirects
61
- for (const event of processedTrace.processEvents) {
60
+ for (const event of traceOfTab.processEvents) {
62
61
  if (event.name !== 'navigationStart') continue;
63
62
 
64
63
  const data = event.args.data || {};
@@ -87,13 +86,12 @@ class Redirects extends Audit {
87
86
  const settings = context.settings;
88
87
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
89
88
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
90
- const gatherContext = artifacts.GatherContext;
91
89
 
92
- const processedTrace = await ProcessedTrace.request(trace, context);
90
+ const traceOfTab = await TraceOfTab.request(trace, context);
93
91
  const networkRecords = await NetworkRecords.request(devtoolsLog, context);
94
92
  const mainResource = await MainResource.request({URL: artifacts.URL, devtoolsLog}, context);
95
93
 
96
- const metricComputationData = {trace, devtoolsLog, gatherContext, settings};
94
+ const metricComputationData = {trace, devtoolsLog, traceOfTab, networkRecords, settings};
97
95
  const metricResult = await LanternInteractive.request(metricComputationData, context);
98
96
 
99
97
  /** @type {Map<string, LH.Gatherer.Simulation.NodeTiming>} */
@@ -105,7 +103,7 @@ class Redirects extends Audit {
105
103
  }
106
104
 
107
105
  const documentRequests = Redirects.getDocumentRequestChain(
108
- mainResource, networkRecords, processedTrace);
106
+ mainResource, networkRecords, traceOfTab);
109
107
 
110
108
  let totalWastedMs = 0;
111
109
  const tableRows = [];
@@ -9,6 +9,7 @@ const Audit = require('./audit.js');
9
9
  const LHError = require('../lib/lh-error.js');
10
10
  const jpeg = require('jpeg-js');
11
11
  const Speedline = require('../computed/speedline.js');
12
+ const Interactive = require('../computed/metrics/interactive.js');
12
13
 
13
14
  const NUMBER_OF_THUMBNAILS = 10;
14
15
  const THUMBNAIL_WIDTH = 120;
@@ -25,7 +26,7 @@ class ScreenshotThumbnails extends Audit {
25
26
  scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE,
26
27
  title: 'Screenshot Thumbnails',
27
28
  description: 'This is what the load of your site looked like.',
28
- requiredArtifacts: ['traces', 'GatherContext'],
29
+ requiredArtifacts: ['traces', 'devtoolsLogs'],
29
30
  };
30
31
  }
31
32
 
@@ -70,7 +71,7 @@ class ScreenshotThumbnails extends Audit {
70
71
  * @param {LH.Audit.Context} context
71
72
  * @return {Promise<LH.Audit.Product>}
72
73
  */
73
- static async _audit(artifacts, context) {
74
+ static async audit(artifacts, context) {
74
75
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
75
76
  /** @type {Map<SpeedlineFrame, string>} */
76
77
  const cachedThumbnails = new Map();
@@ -78,7 +79,16 @@ class ScreenshotThumbnails extends Audit {
78
79
  const speedline = await Speedline.request(trace, context);
79
80
 
80
81
  // Make the minimum time range 3s so sites that load super quickly don't get a single screenshot
81
- const minimumTimelineDuration = context.options.minimumTimelineDuration || 3000;
82
+ let minimumTimelineDuration = context.options.minimumTimelineDuration || 3000;
83
+ // Ensure thumbnails cover the full range of the trace (TTI can be later than visually complete)
84
+ if (context.settings.throttlingMethod !== 'simulate') {
85
+ const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
86
+ const metricComputationData = {trace, devtoolsLog, settings: context.settings};
87
+ const tti = Interactive.request(metricComputationData, context);
88
+ try {
89
+ minimumTimelineDuration = Math.max((await tti).timing, minimumTimelineDuration);
90
+ } catch (_) {}
91
+ }
82
92
 
83
93
  const thumbnails = [];
84
94
  const analyzedFrames = speedline.frames.filter(frame => !frame.isProgressInterpolated());
@@ -133,31 +143,6 @@ class ScreenshotThumbnails extends Audit {
133
143
  },
134
144
  };
135
145
  }
136
-
137
- /**
138
- * @param {LH.Artifacts} artifacts
139
- * @param {LH.Audit.Context} context
140
- * @return {Promise<LH.Audit.Product>}
141
- */
142
- static async audit(artifacts, context) {
143
- try {
144
- return await this._audit(artifacts, context);
145
- } catch (err) {
146
- const noFramesErrors = new Set([
147
- LHError.errors.NO_SCREENSHOTS.code,
148
- LHError.errors.SPEEDINDEX_OF_ZERO.code,
149
- LHError.errors.NO_SPEEDLINE_FRAMES.code,
150
- LHError.errors.INVALID_SPEEDLINE.code,
151
- ]);
152
-
153
- // If a timespan didn't happen to contain frames, that's fine. Just mark not applicable.
154
- if (noFramesErrors.has(err.code) && artifacts.GatherContext.gatherMode === 'timespan') {
155
- return {notApplicable: true, score: 1};
156
- }
157
-
158
- throw err;
159
- }
160
- }
161
146
  }
162
147
 
163
148
  module.exports = ScreenshotThumbnails;
@@ -32,7 +32,7 @@ const UIStrings = {
32
32
  * @description Explanatory message stating that there was a failure in an audit caused by a URL being relative instead of absolute.
33
33
  * @example {https://example.com/} url
34
34
  * */
35
- explanationRelative: 'Is not an absolute URL ({url})',
35
+ explanationRelative: 'Relative URL ({url})',
36
36
  /**
37
37
  * @description Explanatory message stating that there was a failure in an audit caused by a URL pointing to a different hreflang than the current context.'hreflang' is an HTML attribute and should not be translated.
38
38
  * @example {https://example.com/} url
@@ -68,7 +68,6 @@ class Canonical extends Audit {
68
68
  title: str_(UIStrings.title),
69
69
  failureTitle: str_(UIStrings.failureTitle),
70
70
  description: str_(UIStrings.description),
71
- supportedModes: ['navigation'],
72
71
  requiredArtifacts: ['LinkElements', 'URL', 'devtoolsLogs'],
73
72
  };
74
73
  }
@@ -40,7 +40,7 @@ const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
40
40
 
41
41
  /**
42
42
  * @param {Array<FailingNodeData>} fontSizeArtifact
43
- * @return {Array<FailingNodeData>}
43
+ * @returns {Array<FailingNodeData>}
44
44
  */
45
45
  function getUniqueFailingRules(fontSizeArtifact) {
46
46
  /** @type {Map<string, FailingNodeData>} */
@@ -69,7 +69,7 @@ function getUniqueFailingRules(fontSizeArtifact) {
69
69
 
70
70
  /**
71
71
  * @param {Array<string|undefined>=} attributes
72
- * @return {Map<string, string>}
72
+ * @returns {Map<string, string>}
73
73
  */
74
74
  function getAttributeMap(attributes = []) {
75
75
  const map = new Map();
@@ -92,7 +92,7 @@ function getAttributeMap(attributes = []) {
92
92
  /**
93
93
  * TODO: return unique selector, like axe-core does, instead of just id/class/name of a single node
94
94
  * @param {FailingNodeData['parentNode']} parentNode
95
- * @return {string}
95
+ * @returns {string}
96
96
  */
97
97
  function getSelector(parentNode) {
98
98
  const attributeMap = getAttributeMap(parentNode.attributes);
@@ -130,7 +130,7 @@ function nodeToTableNode(parentNode) {
130
130
  * @param {string} baseURL
131
131
  * @param {FailingNodeData['cssRule']} styleDeclaration
132
132
  * @param {FailingNodeData['parentNode']} parentNode
133
- * @return {{source: LH.Audit.Details.UrlValue | LH.Audit.Details.SourceLocationValue | LH.Audit.Details.CodeValue, selector: string | LH.Audit.Details.NodeValue}}
133
+ * @returns {{source: LH.Audit.Details.UrlValue | LH.Audit.Details.SourceLocationValue | LH.Audit.Details.CodeValue, selector: string | LH.Audit.Details.NodeValue}}
134
134
  */
135
135
  function findStyleRuleSource(baseURL, styleDeclaration, parentNode) {
136
136
  if (!styleDeclaration ||
@@ -49,7 +49,7 @@ function importValidLangs() {
49
49
 
50
50
  /**
51
51
  * @param {string} href
52
- * @return {boolean}
52
+ * @returns {boolean}
53
53
  */
54
54
  function isFullyQualified(href) {
55
55
  return href.startsWith('http:') || href.startsWith('https:');
@@ -57,7 +57,7 @@ function isFullyQualified(href) {
57
57
 
58
58
  /**
59
59
  * @param {string} hreflang
60
- * @return {boolean}
60
+ * @returns {boolean}
61
61
  */
62
62
  function isExpectedLanguageCode(hreflang) {
63
63
  if (hreflang.toLowerCase() === NO_LANGUAGE) {
@@ -79,7 +79,6 @@ class Hreflang extends Audit {
79
79
  title: str_(UIStrings.title),
80
80
  failureTitle: str_(UIStrings.failureTitle),
81
81
  description: str_(UIStrings.description),
82
- supportedModes: ['navigation'],
83
82
  requiredArtifacts: ['LinkElements', 'URL'],
84
83
  };
85
84
  }