lighthouse 12.0.0 → 12.1.0-dev.20240618

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 (219) hide show
  1. package/cli/run.js +5 -38
  2. package/cli/test/smokehouse/lighthouse-runners/bundle.js +1 -1
  3. package/cli/test/smokehouse/smokehouse.js +11 -1
  4. package/core/audits/accessibility/aria-allowed-role.js +7 -9
  5. package/core/audits/byte-efficiency/byte-efficiency-audit.d.ts +2 -2
  6. package/core/audits/byte-efficiency/byte-efficiency-audit.js +3 -3
  7. package/core/audits/byte-efficiency/offscreen-images.js +1 -1
  8. package/core/audits/byte-efficiency/render-blocking-resources.d.ts +3 -3
  9. package/core/audits/byte-efficiency/render-blocking-resources.js +10 -10
  10. package/core/audits/dobetterweb/uses-http2.d.ts +2 -2
  11. package/core/audits/dobetterweb/uses-http2.js +5 -5
  12. package/core/audits/long-tasks.d.ts +7 -6
  13. package/core/audits/long-tasks.js +5 -4
  14. package/core/audits/metrics/first-meaningful-paint.d.ts +1 -17
  15. package/core/audits/metrics/first-meaningful-paint.js +5 -47
  16. package/core/audits/metrics/interactive.d.ts +1 -1
  17. package/core/audits/metrics/interactive.js +1 -1
  18. package/core/audits/predictive-perf.js +0 -6
  19. package/core/audits/prioritize-lcp-image.d.ts +1 -1
  20. package/core/audits/prioritize-lcp-image.js +2 -2
  21. package/core/audits/redirects.js +2 -3
  22. package/core/audits/third-party-facades.js +1 -1
  23. package/core/audits/third-party-summary.js +1 -1
  24. package/core/audits/uses-rel-preconnect.js +2 -2
  25. package/core/audits/uses-rel-preload.js +9 -9
  26. package/core/computed/critical-request-chains.js +3 -3
  27. package/core/computed/document-urls.js +3 -2
  28. package/core/computed/load-simulator.d.ts +4 -4
  29. package/core/computed/load-simulator.js +3 -54
  30. package/core/computed/main-resource.js +3 -2
  31. package/core/computed/metrics/interactive.d.ts +6 -0
  32. package/core/computed/metrics/interactive.js +2 -2
  33. package/core/computed/metrics/lantern-first-contentful-paint.d.ts +4 -4
  34. package/core/computed/metrics/lantern-first-contentful-paint.js +3 -3
  35. package/core/computed/metrics/lantern-interactive.d.ts +4 -4
  36. package/core/computed/metrics/lantern-interactive.js +6 -6
  37. package/core/computed/metrics/lantern-largest-contentful-paint.d.ts +4 -4
  38. package/core/computed/metrics/lantern-largest-contentful-paint.js +3 -3
  39. package/core/computed/metrics/lantern-max-potential-fid.d.ts +4 -4
  40. package/core/computed/metrics/lantern-max-potential-fid.js +3 -3
  41. package/core/computed/metrics/lantern-metric.d.ts +21 -2
  42. package/core/computed/metrics/lantern-metric.js +39 -4
  43. package/core/computed/metrics/lantern-speed-index.d.ts +4 -4
  44. package/core/computed/metrics/lantern-speed-index.js +4 -4
  45. package/core/computed/metrics/lantern-total-blocking-time.d.ts +4 -4
  46. package/core/computed/metrics/lantern-total-blocking-time.js +3 -3
  47. package/core/computed/metrics/timing-summary.js +0 -6
  48. package/core/computed/metrics/total-blocking-time.js +3 -1
  49. package/core/computed/navigation-insights.d.ts +2 -20
  50. package/core/computed/network-analysis.d.ts +0 -5
  51. package/core/computed/network-analysis.js +2 -42
  52. package/core/computed/page-dependency-graph.d.ts +5 -3
  53. package/core/computed/page-dependency-graph.js +17 -7
  54. package/core/computed/processed-navigation.d.ts +1 -1
  55. package/core/computed/tbt-impact-tasks.js +4 -2
  56. package/core/computed/trace-engine-result.d.ts +0 -11
  57. package/core/computed/trace-engine-result.js +5 -19
  58. package/core/config/constants.d.ts +28 -53
  59. package/core/config/constants.js +2 -43
  60. package/core/gather/driver/navigation.js +1 -1
  61. package/core/gather/driver/network-monitor.d.ts +2 -1
  62. package/core/gather/driver/network-monitor.js +4 -4
  63. package/core/gather/driver/target-manager.d.ts +1 -1
  64. package/core/gather/driver.d.ts +0 -12
  65. package/core/gather/driver.js +1 -26
  66. package/core/gather/gatherers/inspector-issues.js +1 -0
  67. package/core/gather/gatherers/root-causes.js +0 -1
  68. package/core/gather/session.d.ts +5 -3
  69. package/core/gather/session.js +22 -1
  70. package/core/lib/asset-saver.d.ts +13 -9
  71. package/core/lib/asset-saver.js +77 -30
  72. package/core/lib/bf-cache-strings.js +2 -2
  73. package/core/lib/lantern/{base-node.d.ts → BaseNode.d.ts} +7 -9
  74. package/core/lib/lantern/{base-node.js → BaseNode.js} +6 -6
  75. package/core/lib/lantern/BaseNode.test.js +385 -0
  76. package/core/lib/lantern/CpuNode.d.ts +43 -0
  77. package/core/lib/lantern/{cpu-node.js → CpuNode.js} +8 -9
  78. package/core/lib/lantern/{lantern-error.d.ts → LanternError.d.ts} +1 -1
  79. package/core/lib/lantern/{metric.d.ts → Metric.d.ts} +23 -25
  80. package/core/lib/lantern/{metric.js → Metric.js} +14 -16
  81. package/core/lib/lantern/{network-node.d.ts → NetworkNode.d.ts} +6 -7
  82. package/core/lib/lantern/{network-node.js → NetworkNode.js} +7 -9
  83. package/core/lib/lantern/PageDependencyGraph.d.ts +82 -0
  84. package/core/lib/lantern/{page-dependency-graph.js → PageDependencyGraph.js} +185 -50
  85. package/core/lib/lantern/PageDependencyGraph.test.js +654 -0
  86. package/core/{computed/metrics/tbt-utils.d.ts → lib/lantern/TBTUtils.d.ts} +1 -1
  87. package/core/lib/lantern/TBTUtils.test.d.ts +2 -0
  88. package/core/lib/lantern/TBTUtils.test.js +130 -0
  89. package/core/lib/lantern/TraceEngineComputationData.d.ts +25 -0
  90. package/core/lib/lantern/TraceEngineComputationData.js +466 -0
  91. package/core/lib/lantern/lantern.d.ts +19 -7
  92. package/core/lib/lantern/lantern.js +21 -1
  93. package/core/lib/lantern/metrics/{first-contentful-paint.d.ts → FirstContentfulPaint.d.ts} +11 -11
  94. package/core/lib/lantern/metrics/{first-contentful-paint.js → FirstContentfulPaint.js} +11 -13
  95. package/core/lib/lantern/metrics/FirstContentfulPaint.test.js +54 -0
  96. package/core/lib/lantern/metrics/Interactive.d.ts +20 -0
  97. package/core/lib/lantern/metrics/{interactive.js → Interactive.js} +23 -26
  98. package/core/lib/lantern/metrics/Interactive.test.js +56 -0
  99. package/core/lib/lantern/metrics/LargestContentfulPaint.d.ts +19 -0
  100. package/core/lib/lantern/metrics/{largest-contentful-paint.js → LargestContentfulPaint.js} +16 -19
  101. package/core/lib/lantern/metrics/LargestContentfulPaint.test.js +42 -0
  102. package/core/lib/lantern/metrics/MaxPotentialFID.d.ts +24 -0
  103. package/core/lib/lantern/metrics/{max-potential-fid.js → MaxPotentialFID.js} +12 -13
  104. package/core/lib/lantern/metrics/MetricTestUtils.d.ts +19 -0
  105. package/core/lib/lantern/metrics/MetricTestUtils.js +48 -0
  106. package/core/lib/lantern/metrics/{speed-index.d.ts → SpeedIndex.d.ts} +7 -13
  107. package/core/lib/lantern/metrics/{speed-index.js → SpeedIndex.js} +14 -16
  108. package/core/lib/lantern/metrics/SpeedIndex.test.js +83 -0
  109. package/core/lib/lantern/metrics/TotalBlockingTime.d.ts +25 -0
  110. package/core/lib/lantern/metrics/{total-blocking-time.js → TotalBlockingTime.js} +13 -16
  111. package/core/lib/lantern/metrics/__snapshots__/FirstContentfulPaint.test.js.snap +11 -0
  112. package/core/lib/lantern/metrics/__snapshots__/Interactive.test.js.snap +17 -0
  113. package/core/lib/lantern/metrics/metrics.d.ts +9 -0
  114. package/core/lib/lantern/metrics/metrics.js +16 -0
  115. package/core/lib/lantern/{simulator/connection-pool.d.ts → simulation/ConnectionPool.d.ts} +15 -15
  116. package/core/lib/lantern/{simulator/connection-pool.js → simulation/ConnectionPool.js} +25 -25
  117. package/core/lib/lantern/simulation/ConnectionPool.test.js +195 -0
  118. package/core/lib/lantern/simulation/Constants.d.ts +52 -0
  119. package/core/lib/lantern/simulation/Constants.js +48 -0
  120. package/core/lib/lantern/{simulator/dns-cache.d.ts → simulation/DNSCache.d.ts} +3 -3
  121. package/core/lib/lantern/{simulator/dns-cache.js → simulation/DNSCache.js} +2 -2
  122. package/core/lib/lantern/simulation/DNSCache.test.js +72 -0
  123. package/core/lib/lantern/{simulator/network-analyzer.d.ts → simulation/NetworkAnalyzer.d.ts} +34 -21
  124. package/core/lib/lantern/{simulator/network-analyzer.js → simulation/NetworkAnalyzer.js} +106 -57
  125. package/core/lib/lantern/simulation/NetworkAnalyzer.test.js +475 -0
  126. package/core/lib/lantern/{simulator/simulator-timing-map.d.ts → simulation/SimulationTimingMap.d.ts} +7 -7
  127. package/core/lib/lantern/{simulator/simulator-timing-map.js → simulation/SimulationTimingMap.js} +5 -6
  128. package/core/lib/lantern/{simulator/simulator.d.ts → simulation/Simulator.d.ts} +21 -19
  129. package/core/lib/lantern/{simulator/simulator.js → simulation/Simulator.js} +100 -45
  130. package/core/lib/lantern/simulation/Simulator.test.js +434 -0
  131. package/core/lib/lantern/simulation/TCPConnection.test.d.ts +2 -0
  132. package/core/lib/lantern/simulation/TCPConnection.test.js +374 -0
  133. package/core/lib/lantern/{simulator/tcp-connection.d.ts → simulation/TcpConnection.d.ts} +2 -2
  134. package/core/lib/lantern/{simulator/tcp-connection.js → simulation/TcpConnection.js} +1 -1
  135. package/core/lib/lantern/simulation/simulation.d.ts +21 -0
  136. package/core/lib/lantern/simulation/simulation.js +28 -0
  137. package/core/lib/lantern/types/lantern.d.ts +145 -20
  138. package/core/lib/lantern-trace-saver.d.ts +4 -4
  139. package/core/lib/lantern-trace-saver.js +4 -4
  140. package/core/lib/navigation-error.js +3 -3
  141. package/core/lib/network-recorder.js +2 -2
  142. package/core/lib/network-request.d.ts +29 -3
  143. package/core/lib/network-request.js +20 -13
  144. package/core/lib/tracehouse/trace-processor.d.ts +0 -2
  145. package/core/lib/tracehouse/trace-processor.js +1 -31
  146. package/core/lib/traces/metric-trace-events.js +0 -5
  147. package/dist/report/bundle.esm.js +1 -1
  148. package/dist/report/flow.js +1 -1
  149. package/dist/report/standalone.js +1 -1
  150. package/package.json +14 -13
  151. package/report/renderer/performance-category-renderer.js +1 -1
  152. package/shared/localization/locales/ar-XB.json +43 -4
  153. package/shared/localization/locales/ar.json +43 -4
  154. package/shared/localization/locales/bg.json +43 -4
  155. package/shared/localization/locales/ca.json +44 -5
  156. package/shared/localization/locales/cs.json +43 -4
  157. package/shared/localization/locales/da.json +43 -4
  158. package/shared/localization/locales/de.json +43 -4
  159. package/shared/localization/locales/el.json +43 -4
  160. package/shared/localization/locales/en-GB.json +42 -3
  161. package/shared/localization/locales/en-US.json +4 -4
  162. package/shared/localization/locales/en-XA.json +43 -4
  163. package/shared/localization/locales/en-XL.json +4 -4
  164. package/shared/localization/locales/es-419.json +43 -4
  165. package/shared/localization/locales/es.json +42 -3
  166. package/shared/localization/locales/fi.json +43 -4
  167. package/shared/localization/locales/fil.json +42 -3
  168. package/shared/localization/locales/fr.json +42 -3
  169. package/shared/localization/locales/he.json +48 -9
  170. package/shared/localization/locales/hi.json +43 -4
  171. package/shared/localization/locales/hr.json +43 -4
  172. package/shared/localization/locales/hu.json +42 -3
  173. package/shared/localization/locales/id.json +42 -3
  174. package/shared/localization/locales/it.json +43 -4
  175. package/shared/localization/locales/ja.json +42 -3
  176. package/shared/localization/locales/ko.json +43 -4
  177. package/shared/localization/locales/lt.json +42 -3
  178. package/shared/localization/locales/lv.json +43 -4
  179. package/shared/localization/locales/nl.json +44 -5
  180. package/shared/localization/locales/no.json +42 -3
  181. package/shared/localization/locales/pl.json +43 -4
  182. package/shared/localization/locales/pt-PT.json +43 -4
  183. package/shared/localization/locales/pt.json +43 -4
  184. package/shared/localization/locales/ro.json +43 -4
  185. package/shared/localization/locales/ru.json +43 -4
  186. package/shared/localization/locales/sk.json +43 -4
  187. package/shared/localization/locales/sl.json +42 -3
  188. package/shared/localization/locales/sr-Latn.json +43 -4
  189. package/shared/localization/locales/sr.json +43 -4
  190. package/shared/localization/locales/sv.json +42 -3
  191. package/shared/localization/locales/ta.json +42 -3
  192. package/shared/localization/locales/te.json +43 -4
  193. package/shared/localization/locales/th.json +44 -5
  194. package/shared/localization/locales/tr.json +43 -4
  195. package/shared/localization/locales/uk.json +43 -4
  196. package/shared/localization/locales/vi.json +43 -4
  197. package/shared/localization/locales/zh-HK.json +43 -4
  198. package/shared/localization/locales/zh-TW.json +43 -4
  199. package/shared/localization/locales/zh.json +43 -4
  200. package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +1 -0
  201. package/tsconfig-all.json +1 -0
  202. package/tsconfig.json +11 -7
  203. package/types/artifacts.d.ts +23 -25
  204. package/types/gatherer.d.ts +2 -3
  205. package/types/lhr/lhr.d.ts +2 -0
  206. package/core/computed/metrics/first-meaningful-paint.d.ts +0 -21
  207. package/core/computed/metrics/first-meaningful-paint.js +0 -44
  208. package/core/computed/metrics/lantern-first-meaningful-paint.d.ts +0 -25
  209. package/core/computed/metrics/lantern-first-meaningful-paint.js +0 -43
  210. package/core/lib/lantern/cpu-node.d.ts +0 -44
  211. package/core/lib/lantern/metrics/first-meaningful-paint.d.ts +0 -6
  212. package/core/lib/lantern/metrics/first-meaningful-paint.js +0 -64
  213. package/core/lib/lantern/metrics/interactive.d.ts +0 -26
  214. package/core/lib/lantern/metrics/largest-contentful-paint.d.ts +0 -19
  215. package/core/lib/lantern/metrics/max-potential-fid.d.ts +0 -30
  216. package/core/lib/lantern/metrics/total-blocking-time.d.ts +0 -31
  217. package/core/lib/lantern/page-dependency-graph.d.ts +0 -58
  218. /package/core/lib/lantern/{lantern-error.js → LanternError.js} +0 -0
  219. /package/core/{computed/metrics/tbt-utils.js → lib/lantern/TBTUtils.js} +0 -0
package/cli/run.js CHANGED
@@ -9,7 +9,6 @@
9
9
  import path from 'path';
10
10
  import os from 'os';
11
11
 
12
- import psList from 'ps-list';
13
12
  import * as ChromeLauncher from 'chrome-launcher';
14
13
  import yargsParser from 'yargs-parser';
15
14
  import log from 'lighthouse-logger';
@@ -176,36 +175,6 @@ async function saveResults(runnerResult, flags) {
176
175
  }
177
176
  }
178
177
 
179
- /**
180
- * Attempt to kill the launched Chrome, if defined.
181
- * @param {ChromeLauncher.LaunchedChrome=} launchedChrome
182
- * @return {Promise<void>}
183
- */
184
- async function potentiallyKillChrome(launchedChrome) {
185
- if (!launchedChrome) return;
186
-
187
- /** @type {NodeJS.Timeout} */
188
- let timeout;
189
- const timeoutPromise = new Promise((_, reject) => {
190
- timeout = setTimeout(reject, 5000, new Error('Timed out waiting to kill Chrome'));
191
- });
192
-
193
- return Promise.race([
194
- launchedChrome.kill(),
195
- timeoutPromise,
196
- ]).catch(async err => {
197
- const runningProcesses = await psList();
198
- if (!runningProcesses.some(proc => proc.pid === launchedChrome.pid)) {
199
- log.warn('CLI', 'Warning: Chrome process could not be killed because it already exited.');
200
- return;
201
- }
202
-
203
- throw new Error(`Couldn't quit Chrome process. ${err}`);
204
- }).finally(() => {
205
- clearTimeout(timeout);
206
- });
207
- }
208
-
209
178
  /**
210
179
  * @param {string} url
211
180
  * @param {LH.CliFlags} flags
@@ -214,12 +183,10 @@ async function potentiallyKillChrome(launchedChrome) {
214
183
  */
215
184
  async function runLighthouse(url, flags, config) {
216
185
  /** @param {any} reason */
217
- async function handleTheUnhandled(reason) {
186
+ function handleTheUnhandled(reason) {
218
187
  process.stderr.write(`Unhandled Rejection. Reason: ${reason}\n`);
219
- await potentiallyKillChrome(launchedChrome).catch(() => {});
220
- setTimeout(_ => {
221
- process.exit(1);
222
- }, 100);
188
+ launchedChrome?.kill();
189
+ process.exit(1);
223
190
  }
224
191
  process.on('unhandledRejection', handleTheUnhandled);
225
192
 
@@ -247,7 +214,7 @@ async function runLighthouse(url, flags, config) {
247
214
  await saveResults(runnerResult, flags);
248
215
  }
249
216
 
250
- await potentiallyKillChrome(launchedChrome);
217
+ launchedChrome?.kill();
251
218
  process.removeListener('unhandledRejection', handleTheUnhandled);
252
219
 
253
220
  // Runtime errors indicate something was *very* wrong with the page result.
@@ -265,7 +232,7 @@ async function runLighthouse(url, flags, config) {
265
232
 
266
233
  return runnerResult;
267
234
  } catch (err) {
268
- await potentiallyKillChrome(launchedChrome).catch(() => {});
235
+ launchedChrome?.kill();
269
236
  return printErrorAndExit(err);
270
237
  }
271
238
  }
@@ -97,7 +97,7 @@ async function runBundledLighthouse(url, config, testRunnerOptions) {
97
97
  };
98
98
  } finally {
99
99
  // Clean up and return results.
100
- await launchedChrome.kill();
100
+ launchedChrome.kill();
101
101
  }
102
102
  }
103
103
 
@@ -163,8 +163,18 @@ async function runSmokeTest(smokeTestDefn, testOptions) {
163
163
 
164
164
  // Run Lighthouse.
165
165
  try {
166
+ // Each individual runner has internal timeouts, but we've had bugs where
167
+ // that didn't cover some edge case. So to be safe give a (long) timeout here.
168
+ const timeoutPromise = new Promise((_, reject) => {
169
+ setTimeout(() =>
170
+ reject(new Error('Timed out waiting for provided lighthouseRunner')), 1000 * 120);
171
+ });
172
+ const timedResult = await Promise.race([
173
+ lighthouseRunner(requestedUrl, config, testRunnerOptions),
174
+ timeoutPromise,
175
+ ]);
166
176
  result = {
167
- ...await lighthouseRunner(requestedUrl, config, testRunnerOptions),
177
+ ...timedResult,
168
178
  networkRequests: takeNetworkRequestUrls ? takeNetworkRequestUrls() : undefined,
169
179
  };
170
180
 
@@ -13,16 +13,14 @@ import AxeAudit from './axe-audit.js';
13
13
  import * as i18n from '../../lib/i18n/i18n.js';
14
14
 
15
15
  const UIStrings = {
16
- /** Title of an accesibility audit that evaluates if the ARIA role attributes are valid for the HTML element. This title is descriptive of the successful state and is shown to users when no user action is required. */
17
- title: 'Values assigned to `role=""` are valid ARIA roles.',
18
- /** Title of an accesibility audit that evaluates if the ARIA role attributes are valid for the HTML element. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
19
- failureTitle: 'Values assigned to `role=""` are not valid ARIA roles.',
16
+ /** Title of an accessibility audit that evaluates if the ARIA role attributes are valid for the HTML element. This title is descriptive of the successful state and is shown to users when no user action is required. */
17
+ title: 'Uses ARIA roles only on compatible elements',
18
+ /** Title of an accessibility audit that evaluates if the ARIA role attributes are valid for the HTML element. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
19
+ failureTitle: 'Uses ARIA roles on incompatible elements',
20
20
  /** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
21
- description: 'ARIA `role`s enable assistive technologies to know the role of each element on ' +
22
- 'the web page. If the `role` values are misspelled, not existing ARIA `role` values, or ' +
23
- 'abstract roles, then the purpose of the element will not be communicated to users of ' +
24
- 'assistive technologies. ' +
25
- '[Learn more about ARIA roles](https://dequeuniversity.com/rules/axe/4.9/aria-allowed-role).',
21
+ description: 'Many HTML elements can only be assigned certain ARIA roles. Using ARIA ' +
22
+ 'roles where they are not allowed can interfere with the accessibility of the web page. ' +
23
+ '[Learn more about ARIA roles](https://dequeuniversity.com/rules/axe/4.9/aria-allowed-role).',
26
24
  };
27
25
 
28
26
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
@@ -1,5 +1,5 @@
1
- export type Simulator = import('../../lib/lantern/simulator/simulator.js').Simulator;
2
- export type Node = import('../../lib/lantern/base-node.js').Node<LH.Artifacts.NetworkRequest>;
1
+ export type Simulator = import('../../lib/lantern/simulation/Simulator.js').Simulator;
2
+ export type Node = import('../../lib/lantern/BaseNode.js').Node<LH.Artifacts.NetworkRequest>;
3
3
  export type ByteEfficiencyProduct = {
4
4
  items: Array<LH.Audit.ByteEfficiencyItem>;
5
5
  wastedBytesByUrl?: Map<string, number> | undefined;
@@ -14,8 +14,8 @@ import {LCPImageRecord} from '../../computed/lcp-image-record.js';
14
14
 
15
15
  const str_ = i18n.createIcuMessageFn(import.meta.url, {});
16
16
 
17
- /** @typedef {import('../../lib/lantern/simulator/simulator.js').Simulator} Simulator */
18
- /** @typedef {import('../../lib/lantern/base-node.js').Node<LH.Artifacts.NetworkRequest>} Node */
17
+ /** @typedef {import('../../lib/lantern/simulation/Simulator.js').Simulator} Simulator */
18
+ /** @typedef {import('../../lib/lantern/BaseNode.js').Node<LH.Artifacts.NetworkRequest>} Node */
19
19
 
20
20
  // Parameters for log-normal distribution scoring. These values were determined by fitting the
21
21
  // log-normal cumulative distribution function curve to the former method of linear interpolation
@@ -120,7 +120,7 @@ class ByteEfficiencyAudit extends Audit {
120
120
  const originalTransferSizes = new Map();
121
121
  graph.traverse(node => {
122
122
  if (node.type !== 'network') return;
123
- const wastedBytes = wastedBytesByUrl.get(node.record.url);
123
+ const wastedBytes = wastedBytesByUrl.get(node.request.url);
124
124
  if (!wastedBytes) return;
125
125
 
126
126
  const original = node.request.transferSize;
@@ -128,7 +128,7 @@ class OffscreenImages extends ByteEfficiencyAudit {
128
128
  if (node.type === 'cpu' && timing.duration >= 50) {
129
129
  lastLongTaskStartTime = Math.max(lastLongTaskStartTime, timing.startTime);
130
130
  } else if (node.type === 'network') {
131
- startTimesByURL.set(node.record.url, timing.startTime);
131
+ startTimesByURL.set(node.request.url, timing.startTime);
132
132
  }
133
133
  }
134
134
 
@@ -1,7 +1,7 @@
1
1
  export default RenderBlockingResources;
2
- export type Simulator = import('../../lib/lantern/simulator/simulator.js').Simulator;
3
- export type Node = import('../../lib/lantern/base-node.js').Node<LH.Artifacts.NetworkRequest>;
4
- export type NetworkNode = import('../../lib/lantern/network-node.js').NetworkNode<LH.Artifacts.NetworkRequest>;
2
+ export type Simulator = import('../../lib/lantern/simulation/Simulator.js').Simulator;
3
+ export type Node = import('../../lib/lantern/BaseNode.js').Node<LH.Artifacts.NetworkRequest>;
4
+ export type NetworkNode = import('../../lib/lantern/NetworkNode.js').NetworkNode<LH.Artifacts.NetworkRequest>;
5
5
  declare class RenderBlockingResources extends Audit {
6
6
  /**
7
7
  * @param {LH.Artifacts} artifacts
@@ -11,7 +11,7 @@
11
11
 
12
12
  import {Audit} from '../audit.js';
13
13
  import * as i18n from '../../lib/i18n/i18n.js';
14
- import {BaseNode} from '../../lib/lantern/base-node.js';
14
+ import {BaseNode} from '../../lib/lantern/lantern.js';
15
15
  import {UnusedCSS} from '../../computed/unused-css.js';
16
16
  import {NetworkRequest} from '../../lib/network-request.js';
17
17
  import {LoadSimulator} from '../../computed/load-simulator.js';
@@ -20,9 +20,9 @@ import {LCPImageRecord} from '../../computed/lcp-image-record.js';
20
20
  import {NavigationInsights} from '../../computed/navigation-insights.js';
21
21
 
22
22
 
23
- /** @typedef {import('../../lib/lantern/simulator/simulator.js').Simulator} Simulator */
24
- /** @typedef {import('../../lib/lantern/base-node.js').Node<LH.Artifacts.NetworkRequest>} Node */
25
- /** @typedef {import('../../lib/lantern/network-node.js').NetworkNode<LH.Artifacts.NetworkRequest>} NetworkNode */
23
+ /** @typedef {import('../../lib/lantern/simulation/Simulator.js').Simulator} Simulator */
24
+ /** @typedef {import('../../lib/lantern/BaseNode.js').Node<LH.Artifacts.NetworkRequest>} Node */
25
+ /** @typedef {import('../../lib/lantern/NetworkNode.js').NetworkNode<LH.Artifacts.NetworkRequest>} NetworkNode */
26
26
 
27
27
  // Because of the way we detect blocking stylesheets, asynchronously loaded
28
28
  // CSS with link[rel=preload] and an onload handler (see https://github.com/filamentgroup/loadCSS)
@@ -53,7 +53,7 @@ function getNodesAndTimingByRequestId(nodeTimings) {
53
53
  for (const [node, nodeTiming] of nodeTimings) {
54
54
  if (node.type !== 'network') continue;
55
55
 
56
- requestIdToNode.set(node.record.requestId, {node, nodeTiming});
56
+ requestIdToNode.set(node.request.requestId, {node, nodeTiming});
57
57
  }
58
58
 
59
59
  return requestIdToNode;
@@ -94,7 +94,7 @@ function computeStackSpecificTiming(node, nodeTiming, Stacks) {
94
94
  // https://github.com/ampproject/amphtml/blob/8e03ac2f315774070651584a7e046ff24212c9b1/src/font-stylesheet-timeout.js#L54-L59
95
95
  // Any potential savings must only include time spent on AMP stylesheet nodes before 2.1 seconds.
96
96
  if (node.type === BaseNode.TYPES.NETWORK &&
97
- node.record.resourceType === NetworkRequest.TYPES.Stylesheet &&
97
+ node.request.resourceType === NetworkRequest.TYPES.Stylesheet &&
98
98
  nodeTiming.endTime > 2100) {
99
99
  stackSpecificTiming.endTime = Math.max(nodeTiming.startTime, 2100);
100
100
  stackSpecificTiming.duration = stackSpecificTiming.endTime - stackSpecificTiming.startTime;
@@ -228,11 +228,11 @@ class RenderBlockingResources extends Audit {
228
228
  if (node.type !== BaseNode.TYPES.NETWORK) return !canDeferRequest;
229
229
 
230
230
  const isStylesheet =
231
- node.record.resourceType === NetworkRequest.TYPES.Stylesheet;
231
+ node.request.resourceType === NetworkRequest.TYPES.Stylesheet;
232
232
  if (canDeferRequest && isStylesheet) {
233
233
  // We'll inline the used bytes of the stylesheet and assume the rest can be deferred
234
- const wastedBytes = wastedCssBytesByUrl.get(node.record.url) || 0;
235
- totalChildNetworkBytes += (node.record.transferSize || 0) - wastedBytes;
234
+ const wastedBytes = wastedCssBytesByUrl.get(node.request.url) || 0;
235
+ totalChildNetworkBytes += (node.request.transferSize || 0) - wastedBytes;
236
236
  }
237
237
  return !canDeferRequest;
238
238
  });
@@ -247,7 +247,7 @@ class RenderBlockingResources extends Audit {
247
247
  ));
248
248
 
249
249
  // Add the inlined bytes to the HTML response
250
- const originalTransferSize = minimalFCPGraph.record.transferSize;
250
+ const originalTransferSize = minimalFCPGraph.request.transferSize;
251
251
  const safeTransferSize = originalTransferSize || 0;
252
252
  minimalFCPGraph.request.transferSize = safeTransferSize + totalChildNetworkBytes;
253
253
  const estimateAfterInline = simulator.simulate(minimalFCPGraph).timeInMs;
@@ -1,6 +1,6 @@
1
1
  export default UsesHTTP2Audit;
2
- export type Simulator = import('../../lib/lantern/simulator/simulator.js').Simulator;
3
- export type Node = import('../../lib/lantern/base-node.js').Node<LH.Artifacts.NetworkRequest>;
2
+ export type Simulator = import('../../lib/lantern/simulation/Simulator.js').Simulator;
3
+ export type Node = import('../../lib/lantern/BaseNode.js').Node<LH.Artifacts.NetworkRequest>;
4
4
  declare class UsesHTTP2Audit extends Audit {
5
5
  /**
6
6
  * Computes the estimated effect of all results being converted to http/2 on the provided graph.
@@ -9,8 +9,8 @@
9
9
  * origin are over the http/2 protocol.
10
10
  */
11
11
 
12
- /** @typedef {import('../../lib/lantern/simulator/simulator.js').Simulator} Simulator */
13
- /** @typedef {import('../../lib/lantern/base-node.js').Node<LH.Artifacts.NetworkRequest>} Node */
12
+ /** @typedef {import('../../lib/lantern/simulation/Simulator.js').Simulator} Simulator */
13
+ /** @typedef {import('../../lib/lantern/BaseNode.js').Node<LH.Artifacts.NetworkRequest>} Node */
14
14
 
15
15
  import {Audit} from '../audit.js';
16
16
  import {EntityClassification} from '../../computed/entity-classification.js';
@@ -87,9 +87,9 @@ class UsesHTTP2Audit extends Audit {
87
87
  const originalProtocols = new Map();
88
88
  graph.traverse(node => {
89
89
  if (node.type !== 'network') return;
90
- if (!urlsToChange.has(node.record.url)) return;
90
+ if (!urlsToChange.has(node.request.url)) return;
91
91
 
92
- originalProtocols.set(node.record.requestId, node.record.protocol);
92
+ originalProtocols.set(node.request.requestId, node.request.protocol);
93
93
  node.request.protocol = 'h2';
94
94
  });
95
95
 
@@ -98,7 +98,7 @@ class UsesHTTP2Audit extends Audit {
98
98
  // Restore the original protocol after we've done our simulation
99
99
  graph.traverse(node => {
100
100
  if (node.type !== 'network') return;
101
- const originalProtocol = originalProtocols.get(node.record.requestId);
101
+ const originalProtocol = originalProtocols.get(node.request.requestId);
102
102
  if (originalProtocol === undefined) return;
103
103
  node.request.protocol = originalProtocol;
104
104
  });
@@ -25,11 +25,11 @@ declare class LongTasks extends Audit {
25
25
  * most time will be attributed to 'other' (the category of the top-level
26
26
  * RunTask). See pruning in `PageDependencyGraph.linkCPUNodes`.
27
27
  * @param {LH.Artifacts.TaskNode} task
28
- * @param {Map<LH.TraceEvent, LH.Gatherer.Simulation.NodeTiming>|undefined} taskTimingsByEvent
28
+ * @param {Map<Lantern.TraceEvent, LH.Gatherer.Simulation.NodeTiming>|undefined} taskTimingsByEvent
29
29
  * @param {Map<TaskGroupIds, number>} [timeByTaskGroup]
30
30
  * @return {{startTime: number, duration: number, timeByTaskGroup: Map<TaskGroupIds, number>}}
31
31
  */
32
- static getTimingBreakdown(task: LH.Artifacts.TaskNode, taskTimingsByEvent: Map<LH.TraceEvent, LH.Gatherer.Simulation.NodeTiming> | undefined, timeByTaskGroup?: Map<import("../lib/tracehouse/task-groups.js").TaskGroupIds, number> | undefined): {
32
+ static getTimingBreakdown(task: LH.Artifacts.TaskNode, taskTimingsByEvent: Map<Lantern.TraceEvent, LH.Gatherer.Simulation.NodeTiming> | undefined, timeByTaskGroup?: Map<import("../lib/tracehouse/task-groups.js").TaskGroupIds, number> | undefined): {
33
33
  startTime: number;
34
34
  duration: number;
35
35
  timeByTaskGroup: Map<TaskGroupIds, number>;
@@ -37,17 +37,17 @@ declare class LongTasks extends Audit {
37
37
  /**
38
38
  * @param {Array<LH.Artifacts.TaskNode>} longTasks
39
39
  * @param {Set<string>} jsUrls
40
- * @param {Map<LH.TraceEvent, LH.Gatherer.Simulation.NodeTiming>|undefined} taskTimingsByEvent
40
+ * @param {Map<Lantern.TraceEvent, LH.Gatherer.Simulation.NodeTiming>|undefined} taskTimingsByEvent
41
41
  * @return {LH.Audit.Details.DebugData}
42
42
  */
43
- static makeDebugData(longTasks: Array<LH.Artifacts.TaskNode>, jsUrls: Set<string>, taskTimingsByEvent: Map<LH.TraceEvent, LH.Gatherer.Simulation.NodeTiming> | undefined): LH.Audit.Details.DebugData;
43
+ static makeDebugData(longTasks: Array<LH.Artifacts.TaskNode>, jsUrls: Set<string>, taskTimingsByEvent: Map<Lantern.TraceEvent, LH.Gatherer.Simulation.NodeTiming> | undefined): LH.Audit.Details.DebugData;
44
44
  /**
45
45
  * Get timing from task, overridden by taskTimingsByEvent if provided.
46
46
  * @param {LH.Artifacts.TaskNode} task
47
- * @param {Map<LH.TraceEvent, LH.Gatherer.Simulation.NodeTiming>|undefined} taskTimingsByEvent
47
+ * @param {Map<Lantern.TraceEvent, LH.Gatherer.Simulation.NodeTiming>|undefined} taskTimingsByEvent
48
48
  * @return {Timing}
49
49
  */
50
- static getTiming(task: LH.Artifacts.TaskNode, taskTimingsByEvent: Map<LH.TraceEvent, LH.Gatherer.Simulation.NodeTiming> | undefined): Timing;
50
+ static getTiming(task: LH.Artifacts.TaskNode, taskTimingsByEvent: Map<Lantern.TraceEvent, LH.Gatherer.Simulation.NodeTiming> | undefined): Timing;
51
51
  /**
52
52
  * @param {LH.Artifacts} artifacts
53
53
  * @param {LH.Audit.Context} context
@@ -61,4 +61,5 @@ export namespace UIStrings {
61
61
  const displayValue: string;
62
62
  }
63
63
  import { Audit } from './audit.js';
64
+ import * as Lantern from '../lib/lantern/lantern.js';
64
65
  //# sourceMappingURL=long-tasks.d.ts.map
@@ -4,6 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
+ import * as Lantern from '../lib/lantern/lantern.js';
7
8
  import {Audit} from './audit.js';
8
9
  import {NetworkRecords} from '../computed/network-records.js';
9
10
  import * as i18n from '../lib/i18n/i18n.js';
@@ -85,7 +86,7 @@ class LongTasks extends Audit {
85
86
  * most time will be attributed to 'other' (the category of the top-level
86
87
  * RunTask). See pruning in `PageDependencyGraph.linkCPUNodes`.
87
88
  * @param {LH.Artifacts.TaskNode} task
88
- * @param {Map<LH.TraceEvent, LH.Gatherer.Simulation.NodeTiming>|undefined} taskTimingsByEvent
89
+ * @param {Map<Lantern.TraceEvent, LH.Gatherer.Simulation.NodeTiming>|undefined} taskTimingsByEvent
89
90
  * @param {Map<TaskGroupIds, number>} [timeByTaskGroup]
90
91
  * @return {{startTime: number, duration: number, timeByTaskGroup: Map<TaskGroupIds, number>}}
91
92
  */
@@ -116,7 +117,7 @@ class LongTasks extends Audit {
116
117
  /**
117
118
  * @param {Array<LH.Artifacts.TaskNode>} longTasks
118
119
  * @param {Set<string>} jsUrls
119
- * @param {Map<LH.TraceEvent, LH.Gatherer.Simulation.NodeTiming>|undefined} taskTimingsByEvent
120
+ * @param {Map<Lantern.TraceEvent, LH.Gatherer.Simulation.NodeTiming>|undefined} taskTimingsByEvent
120
121
  * @return {LH.Audit.Details.DebugData}
121
122
  */
122
123
  static makeDebugData(longTasks, jsUrls, taskTimingsByEvent) {
@@ -154,7 +155,7 @@ class LongTasks extends Audit {
154
155
  /**
155
156
  * Get timing from task, overridden by taskTimingsByEvent if provided.
156
157
  * @param {LH.Artifacts.TaskNode} task
157
- * @param {Map<LH.TraceEvent, LH.Gatherer.Simulation.NodeTiming>|undefined} taskTimingsByEvent
158
+ * @param {Map<Lantern.TraceEvent, LH.Gatherer.Simulation.NodeTiming>|undefined} taskTimingsByEvent
158
159
  * @return {Timing}
159
160
  */
160
161
  static getTiming(task, taskTimingsByEvent) {
@@ -184,7 +185,7 @@ class LongTasks extends Audit {
184
185
  const metricComputationData = Audit.makeMetricComputationDataInput(artifacts, context);
185
186
  const tbtResult = await TotalBlockingTime.request(metricComputationData, context);
186
187
 
187
- /** @type {Map<LH.TraceEvent, LH.Gatherer.Simulation.NodeTiming>|undefined} */
188
+ /** @type {Map<Lantern.TraceEvent, LH.Gatherer.Simulation.NodeTiming>|undefined} */
188
189
  let taskTimingsByEvent;
189
190
 
190
191
  if (settings.throttlingMethod === 'simulate') {
@@ -1,25 +1,9 @@
1
1
  export default FirstMeaningfulPaint;
2
2
  declare class FirstMeaningfulPaint extends Audit {
3
3
  /**
4
- * @return {{mobile: {scoring: LH.Audit.ScoreOptions}, desktop: {scoring: LH.Audit.ScoreOptions}}}
5
- */
6
- static get defaultOptions(): {
7
- mobile: {
8
- scoring: LH.Audit.ScoreOptions;
9
- };
10
- desktop: {
11
- scoring: LH.Audit.ScoreOptions;
12
- };
13
- };
14
- /**
15
- * Audits the page to give a score for First Meaningful Paint.
16
- * @see https://github.com/GoogleChrome/lighthouse/issues/26
17
- * @see https://docs.google.com/document/d/1BR94tJdZLsin5poeet0XoTW60M0SjvOJQttKT-JK8HI/view
18
- * @param {LH.Artifacts} artifacts The artifacts from the gather phase.
19
- * @param {LH.Audit.Context} context
20
4
  * @return {Promise<LH.Audit.Product>}
21
5
  */
22
- static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
6
+ static audit(): Promise<LH.Audit.Product>;
23
7
  }
24
8
  export namespace UIStrings {
25
9
  const description: string;
@@ -4,9 +4,10 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
+ // TODO(COMPAT): This is just a shell. Remove in future breaking release.
8
+
7
9
  import {Audit} from '../audit.js';
8
10
  import * as i18n from '../../lib/i18n/i18n.js';
9
- import {FirstMeaningfulPaint as ComputedFmp} from '../../computed/metrics/first-meaningful-paint.js';
10
11
 
11
12
  const UIStrings = {
12
13
  /** Description of the First Meaningful Paint (FMP) metric, which marks the time at which a majority of the content has been painted by the browser. This is displayed within a tooltip when the user hovers on the metric name to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
@@ -32,55 +33,12 @@ class FirstMeaningfulPaint extends Audit {
32
33
  }
33
34
 
34
35
  /**
35
- * @return {{mobile: {scoring: LH.Audit.ScoreOptions}, desktop: {scoring: LH.Audit.ScoreOptions}}}
36
- */
37
- static get defaultOptions() {
38
- return {
39
- mobile: {
40
- // 25th and 5th percentiles HTTPArchive -> median and PODR, then p10 derived from them.
41
- // https://bigquery.cloud.google.com/table/httparchive:lighthouse.2018_04_01_mobile?pli=1
42
- // see https://www.desmos.com/calculator/i4znkdccut
43
- scoring: {
44
- p10: 2336,
45
- median: 4000,
46
- },
47
- },
48
- desktop: {
49
- // SELECT QUANTILES(renderStart, 21) FROM [httparchive:summary_pages.2018_12_15_desktop] LIMIT 1000
50
- scoring: {
51
- p10: 934,
52
- median: 1600,
53
- },
54
- },
55
- };
56
- }
57
-
58
- /**
59
- * Audits the page to give a score for First Meaningful Paint.
60
- * @see https://github.com/GoogleChrome/lighthouse/issues/26
61
- * @see https://docs.google.com/document/d/1BR94tJdZLsin5poeet0XoTW60M0SjvOJQttKT-JK8HI/view
62
- * @param {LH.Artifacts} artifacts The artifacts from the gather phase.
63
- * @param {LH.Audit.Context} context
64
36
  * @return {Promise<LH.Audit.Product>}
65
37
  */
66
- static async audit(artifacts, context) {
67
- const trace = artifacts.traces[Audit.DEFAULT_PASS];
68
- const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
69
- const gatherContext = artifacts.GatherContext;
70
- const metricComputationData = {trace, devtoolsLog, gatherContext,
71
- settings: context.settings, URL: artifacts.URL};
72
- const metricResult = await ComputedFmp.request(metricComputationData, context);
73
- const options = context.options[context.settings.formFactor];
74
-
75
-
38
+ static async audit() {
76
39
  return {
77
- score: Audit.computeLogNormalScore(
78
- options.scoring,
79
- metricResult.timing
80
- ),
81
- numericValue: metricResult.timing,
82
- numericUnit: 'millisecond',
83
- displayValue: str_(i18n.UIStrings.seconds, {timeInMs: metricResult.timing}),
40
+ score: null,
41
+ notApplicable: true,
84
42
  };
85
43
  }
86
44
  }
@@ -1,7 +1,7 @@
1
1
  export default InteractiveMetric;
2
2
  /**
3
3
  * @fileoverview This audit identifies the time the page is "consistently interactive".
4
- * Looks for the first period of at least 5 seconds after FMP where both CPU and network were quiet,
4
+ * Looks for the first period of at least 5 seconds after FCP where both CPU and network were quiet,
5
5
  * and returns the timestamp of the beginning of the CPU quiet period.
6
6
  * @see https://docs.google.com/document/d/1GGiI9-7KeY3TPqS3YT271upUVimo-XiL5mwWorDUD4c/edit#
7
7
  */
@@ -18,7 +18,7 @@ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
18
18
 
19
19
  /**
20
20
  * @fileoverview This audit identifies the time the page is "consistently interactive".
21
- * Looks for the first period of at least 5 seconds after FMP where both CPU and network were quiet,
21
+ * Looks for the first period of at least 5 seconds after FCP where both CPU and network were quiet,
22
22
  * and returns the timestamp of the beginning of the CPU quiet period.
23
23
  * @see https://docs.google.com/document/d/1GGiI9-7KeY3TPqS3YT271upUVimo-XiL5mwWorDUD4c/edit#
24
24
  */
@@ -7,7 +7,6 @@
7
7
  import {Audit} from './audit.js';
8
8
  import * as i18n from '../lib/i18n/i18n.js';
9
9
  import {LanternFirstContentfulPaint} from '../computed/metrics/lantern-first-contentful-paint.js';
10
- import {LanternFirstMeaningfulPaint} from '../computed/metrics/lantern-first-meaningful-paint.js';
11
10
  import {LanternInteractive} from '../computed/metrics/lantern-interactive.js';
12
11
  import {LanternSpeedIndex} from '../computed/metrics/lantern-speed-index.js';
13
12
  import {LanternLargestContentfulPaint} from '../computed/metrics/lantern-largest-contentful-paint.js';
@@ -52,7 +51,6 @@ class PredictivePerf extends Audit {
52
51
  const settings = JSON.parse(JSON.stringify(defaultSettings)); // Use default settings.
53
52
  const computationData = {trace, devtoolsLog, gatherContext, settings, URL};
54
53
  const fcp = await LanternFirstContentfulPaint.request(computationData, context);
55
- const fmp = await LanternFirstMeaningfulPaint.request(computationData, context);
56
54
  const tti = await LanternInteractive.request(computationData, context);
57
55
  const si = await LanternSpeedIndex.request(computationData, context);
58
56
  const lcp = await LanternLargestContentfulPaint.request(computationData, context);
@@ -64,10 +62,6 @@ class PredictivePerf extends Audit {
64
62
  optimisticFCP: fcp.optimisticEstimate.timeInMs,
65
63
  pessimisticFCP: fcp.pessimisticEstimate.timeInMs,
66
64
 
67
- roughEstimateOfFMP: fmp.timing,
68
- optimisticFMP: fmp.optimisticEstimate.timeInMs,
69
- pessimisticFMP: fmp.pessimisticEstimate.timeInMs,
70
-
71
65
  roughEstimateOfTTI: tti.timing,
72
66
  optimisticTTI: tti.optimisticEstimate.timeInMs,
73
67
  pessimisticTTI: tti.pessimisticEstimate.timeInMs,
@@ -39,7 +39,7 @@ declare class PrioritizeLcpImage extends Audit {
39
39
  * @return {{lcpNodeToPreload?: LH.Gatherer.Simulation.GraphNetworkNode, initiatorPath?: InitiatorPath}}
40
40
  */
41
41
  static getLCPNodeToPreload(mainResource: LH.Artifacts.NetworkRequest, graph: LH.Gatherer.Simulation.GraphNode, lcpRecord: NetworkRequest | undefined): {
42
- lcpNodeToPreload?: import("../lib/lantern/network-node.js").NetworkNode<NetworkRequest> | undefined;
42
+ lcpNodeToPreload?: import("../lib/lantern/NetworkNode.js").NetworkNode<NetworkRequest> | undefined;
43
43
  initiatorPath?: InitiatorPath | undefined;
44
44
  };
45
45
  /**
@@ -69,7 +69,7 @@ class PrioritizeLcpImage extends Audit {
69
69
  static findLCPNode(graph, lcpRecord) {
70
70
  for (const {node} of graph.traverseGenerator()) {
71
71
  if (node.type !== 'network') continue;
72
- if (node.record.requestId === lcpRecord.requestId) {
72
+ if (node.request.requestId === lcpRecord.requestId) {
73
73
  return node;
74
74
  }
75
75
  }
@@ -222,7 +222,7 @@ class PrioritizeLcpImage extends Audit {
222
222
  wastedMs,
223
223
  results: [{
224
224
  node: Audit.makeNodeItem(lcpElement.node),
225
- url: lcpNode.record.url,
225
+ url: lcpNode.request.url,
226
226
  wastedMs,
227
227
  }],
228
228
  };
@@ -90,6 +90,7 @@ class Redirects extends Audit {
90
90
 
91
91
  const processedTrace = await ProcessedTrace.request(trace, context);
92
92
  const networkRecords = await NetworkRecords.request(devtoolsLog, context);
93
+ const documentRequests = Redirects.getDocumentRequestChain(networkRecords, processedTrace);
93
94
 
94
95
  const metricComputationData = {trace, devtoolsLog, gatherContext, settings, URL: artifacts.URL};
95
96
  const metricResult = await LanternInteractive.request(metricComputationData, context);
@@ -98,12 +99,10 @@ class Redirects extends Audit {
98
99
  const nodeTimingsById = new Map();
99
100
  for (const [node, timing] of metricResult.pessimisticEstimate.nodeTimings.entries()) {
100
101
  if (node.type === 'network') {
101
- nodeTimingsById.set(node.record.requestId, timing);
102
+ nodeTimingsById.set(node.request.requestId, timing);
102
103
  }
103
104
  }
104
105
 
105
- const documentRequests = Redirects.getDocumentRequestChain(networkRecords, processedTrace);
106
-
107
106
  let totalWastedMs = 0;
108
107
  const tableRows = [];
109
108
 
@@ -225,7 +225,7 @@ class ThirdPartyFacades extends Audit {
225
225
  itemCount: results.length,
226
226
  }),
227
227
  details: Audit.makeTableDetails(headings, results),
228
- metricSavings: {TBT: tbtImpact},
228
+ metricSavings: {TBT: Math.round(tbtImpact)},
229
229
  };
230
230
  }
231
231
  }
@@ -223,7 +223,7 @@ class ThirdPartySummary extends Audit {
223
223
  }),
224
224
  details,
225
225
  metricSavings: {
226
- TBT: overallSummary.tbtImpact,
226
+ TBT: Math.round(overallSummary.tbtImpact),
227
227
  },
228
228
  };
229
229
  }
@@ -146,14 +146,14 @@ class UsesRelPreconnectAudit extends Audit {
146
146
  /** @type {Set<string>} */
147
147
  const lcpGraphURLs = new Set();
148
148
  lcpGraph.traverse(node => {
149
- if (node.type === 'network') lcpGraphURLs.add(node.record.url);
149
+ if (node.type === 'network') lcpGraphURLs.add(node.request.url);
150
150
  });
151
151
 
152
152
  const fcpGraph =
153
153
  await LanternFirstContentfulPaint.getPessimisticGraph(pageGraph, processedNavigation);
154
154
  const fcpGraphURLs = new Set();
155
155
  fcpGraph.traverse(node => {
156
- if (node.type === 'network') fcpGraphURLs.add(node.record.url);
156
+ if (node.type === 'network') fcpGraphURLs.add(node.request.url);
157
157
  });
158
158
 
159
159
  /** @type {Map<string, LH.Artifacts.NetworkRequest[]>} */