lighthouse 11.6.0 → 11.7.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 (141) hide show
  1. package/cli/test/smokehouse/core-tests.js +2 -2
  2. package/core/audits/byte-efficiency/byte-efficiency-audit.d.ts +2 -2
  3. package/core/audits/byte-efficiency/byte-efficiency-audit.js +7 -7
  4. package/core/audits/byte-efficiency/render-blocking-resources.d.ts +4 -3
  5. package/core/audits/byte-efficiency/render-blocking-resources.js +6 -6
  6. package/core/audits/dobetterweb/uses-http2.d.ts +3 -3
  7. package/core/audits/dobetterweb/uses-http2.js +4 -4
  8. package/core/audits/installable-manifest.d.ts +2 -0
  9. package/core/audits/installable-manifest.js +2 -0
  10. package/core/audits/metrics/interaction-to-next-paint.js +1 -3
  11. package/core/audits/prioritize-lcp-image.d.ts +1 -1
  12. package/core/audits/work-during-interaction.js +0 -8
  13. package/core/computed/document-urls.js +1 -1
  14. package/core/computed/load-simulator.d.ts +2 -2
  15. package/core/computed/load-simulator.js +3 -2
  16. package/core/computed/main-resource.js +1 -1
  17. package/core/computed/metrics/lantern-first-contentful-paint.d.ts +18 -6
  18. package/core/computed/metrics/lantern-first-contentful-paint.js +4 -4
  19. package/core/computed/metrics/lantern-first-meaningful-paint.d.ts +14 -2
  20. package/core/computed/metrics/lantern-first-meaningful-paint.js +1 -1
  21. package/core/computed/metrics/lantern-interactive.d.ts +8 -6
  22. package/core/computed/metrics/lantern-interactive.js +3 -3
  23. package/core/computed/metrics/lantern-largest-contentful-paint.d.ts +14 -2
  24. package/core/computed/metrics/lantern-largest-contentful-paint.js +1 -1
  25. package/core/computed/metrics/lantern-max-potential-fid.d.ts +8 -2
  26. package/core/computed/metrics/lantern-max-potential-fid.js +3 -3
  27. package/core/computed/metrics/lantern-metric.d.ts +4 -63
  28. package/core/computed/metrics/lantern-metric.js +6 -124
  29. package/core/computed/metrics/lantern-speed-index.d.ts +8 -2
  30. package/core/computed/metrics/lantern-speed-index.js +3 -3
  31. package/core/computed/metrics/lantern-total-blocking-time.d.ts +8 -2
  32. package/core/computed/metrics/lantern-total-blocking-time.js +3 -3
  33. package/core/computed/metrics/responsiveness.d.ts +5 -13
  34. package/core/computed/metrics/responsiveness.js +10 -14
  35. package/core/computed/network-analysis.js +1 -1
  36. package/core/computed/page-dependency-graph.d.ts +4 -57
  37. package/core/computed/page-dependency-graph.js +4 -451
  38. package/core/config/config-helpers.js +1 -1
  39. package/core/gather/driver/execution-context.d.ts +2 -1
  40. package/core/gather/driver/execution-context.js +9 -9
  41. package/core/gather/driver/wait-for-condition.js +4 -2
  42. package/core/gather/gatherers/accessibility.js +2 -1
  43. package/core/gather/gatherers/css-usage.d.ts +1 -9
  44. package/core/gather/gatherers/css-usage.js +23 -25
  45. package/core/gather/gatherers/devtools-log.d.ts +4 -0
  46. package/core/gather/gatherers/devtools-log.js +7 -0
  47. package/core/gather/gatherers/full-page-screenshot.d.ts +4 -0
  48. package/core/gather/gatherers/full-page-screenshot.js +31 -35
  49. package/core/gather/gatherers/root-causes.js +1 -3
  50. package/core/gather/gatherers/trace-elements.js +1 -1
  51. package/core/gather/gatherers/trace.d.ts +1 -0
  52. package/core/gather/gatherers/trace.js +4 -0
  53. package/core/gather/navigation-runner.js +49 -62
  54. package/core/gather/session.js +5 -0
  55. package/core/gather/snapshot-runner.js +25 -25
  56. package/core/gather/timespan-runner.js +24 -25
  57. package/core/lib/asset-saver.js +1 -1
  58. package/core/lib/emulation.js +0 -3
  59. package/core/lib/{dependency-graph → lantern}/base-node.d.ts +12 -8
  60. package/core/lib/{dependency-graph → lantern}/base-node.js +8 -3
  61. package/core/lib/{dependency-graph → lantern}/cpu-node.d.ts +5 -1
  62. package/core/lib/{dependency-graph → lantern}/cpu-node.js +4 -0
  63. package/core/lib/lantern/lantern.d.ts +8 -0
  64. package/core/lib/lantern/lantern.js +31 -0
  65. package/core/lib/lantern/metric.d.ts +71 -0
  66. package/core/lib/lantern/metric.js +143 -0
  67. package/core/lib/{dependency-graph → lantern}/network-node.d.ts +17 -10
  68. package/core/lib/lantern/network-node.js +114 -0
  69. package/core/lib/lantern/page-dependency-graph.d.ts +58 -0
  70. package/core/lib/lantern/page-dependency-graph.js +463 -0
  71. package/core/lib/{dependency-graph → lantern}/simulator/connection-pool.d.ts +14 -14
  72. package/core/lib/{dependency-graph → lantern}/simulator/connection-pool.js +7 -7
  73. package/core/lib/{dependency-graph → lantern}/simulator/dns-cache.d.ts +5 -5
  74. package/core/lib/{dependency-graph → lantern}/simulator/dns-cache.js +3 -3
  75. package/core/lib/{dependency-graph → lantern}/simulator/network-analyzer.d.ts +36 -32
  76. package/core/lib/{dependency-graph → lantern}/simulator/network-analyzer.js +21 -17
  77. package/core/lib/{dependency-graph → lantern}/simulator/simulator.d.ts +18 -15
  78. package/core/lib/{dependency-graph → lantern}/simulator/simulator.js +18 -15
  79. package/core/lib/lantern/types/lantern.d.ts +129 -0
  80. package/core/lib/lantern/types/lantern.js +7 -0
  81. package/core/lib/lantern-trace-saver.d.ts +4 -4
  82. package/core/lib/lantern-trace-saver.js +6 -4
  83. package/core/lib/navigation-error.js +1 -1
  84. package/core/lib/network-recorder.js +2 -2
  85. package/core/lib/network-request.d.ts +6 -0
  86. package/core/lib/network-request.js +12 -0
  87. package/package.json +4 -5
  88. package/shared/localization/locales/ar-XB.json +1 -1
  89. package/shared/localization/locales/ar.json +1 -1
  90. package/shared/localization/locales/bg.json +1 -1
  91. package/shared/localization/locales/ca.json +1 -1
  92. package/shared/localization/locales/cs.json +1 -1
  93. package/shared/localization/locales/da.json +2 -2
  94. package/shared/localization/locales/de.json +1 -1
  95. package/shared/localization/locales/el.json +1 -1
  96. package/shared/localization/locales/en-GB.json +1 -1
  97. package/shared/localization/locales/en-US.json +3 -0
  98. package/shared/localization/locales/en-XA.json +1 -1
  99. package/shared/localization/locales/en-XL.json +3 -0
  100. package/shared/localization/locales/es-419.json +1 -1
  101. package/shared/localization/locales/es.json +1 -1
  102. package/shared/localization/locales/fi.json +1 -1
  103. package/shared/localization/locales/fil.json +1 -1
  104. package/shared/localization/locales/he.json +1 -1
  105. package/shared/localization/locales/hi.json +1 -1
  106. package/shared/localization/locales/hr.json +1 -1
  107. package/shared/localization/locales/hu.json +1 -1
  108. package/shared/localization/locales/id.json +1 -1
  109. package/shared/localization/locales/it.json +1 -1
  110. package/shared/localization/locales/ko.json +1 -1
  111. package/shared/localization/locales/lt.json +1 -1
  112. package/shared/localization/locales/nl.json +1 -1
  113. package/shared/localization/locales/no.json +1 -1
  114. package/shared/localization/locales/pl.json +1 -1
  115. package/shared/localization/locales/pt-PT.json +1 -1
  116. package/shared/localization/locales/pt.json +1 -1
  117. package/shared/localization/locales/ro.json +1 -1
  118. package/shared/localization/locales/sk.json +1 -1
  119. package/shared/localization/locales/sl.json +1 -1
  120. package/shared/localization/locales/sr-Latn.json +1 -1
  121. package/shared/localization/locales/sr.json +1 -1
  122. package/shared/localization/locales/sv.json +1 -1
  123. package/shared/localization/locales/ta.json +1 -1
  124. package/shared/localization/locales/te.json +1 -1
  125. package/shared/localization/locales/th.json +4 -4
  126. package/shared/localization/locales/tr.json +1 -1
  127. package/shared/localization/locales/uk.json +1 -1
  128. package/shared/localization/locales/vi.json +1 -1
  129. package/shared/localization/locales/zh-HK.json +1 -1
  130. package/shared/localization/locales/zh-TW.json +1 -1
  131. package/shared/localization/locales/zh.json +1 -1
  132. package/third-party/chromium-synchronization/installability-errors-test.js +1 -1
  133. package/tsconfig.json +7 -5
  134. package/types/artifacts.d.ts +1 -1
  135. package/types/gatherer.d.ts +8 -35
  136. package/types/lhr/lhr.d.ts +1 -1
  137. package/core/lib/dependency-graph/network-node.js +0 -99
  138. /package/core/lib/{dependency-graph → lantern}/simulator/simulator-timing-map.d.ts +0 -0
  139. /package/core/lib/{dependency-graph → lantern}/simulator/simulator-timing-map.js +0 -0
  140. /package/core/lib/{dependency-graph → lantern}/simulator/tcp-connection.d.ts +0 -0
  141. /package/core/lib/{dependency-graph → lantern}/simulator/tcp-connection.js +0 -0
@@ -32,10 +32,10 @@ export class NetworkAnalyzer {
32
32
  */
33
33
  static get SUMMARY(): string;
34
34
  /**
35
- * @param {LH.Artifacts.NetworkRequest[]} records
36
- * @return {Map<string, LH.Artifacts.NetworkRequest[]>}
35
+ * @param {Lantern.NetworkRequest[]} records
36
+ * @return {Map<string, Lantern.NetworkRequest[]>}
37
37
  */
38
- static groupByOrigin(records: LH.Artifacts.NetworkRequest[]): Map<string, LH.Artifacts.NetworkRequest[]>;
38
+ static groupByOrigin(records: Lantern.NetworkRequest[]): Map<string, Lantern.NetworkRequest[]>;
39
39
  /**
40
40
  * @param {number[]} values
41
41
  * @return {Summary}
@@ -46,14 +46,14 @@ export class NetworkAnalyzer {
46
46
  * @return {Map<string, Summary>}
47
47
  */
48
48
  static summarize(values: Map<string, number[]>): Map<string, Summary>;
49
- /** @typedef {{record: LH.Artifacts.NetworkRequest, timing: LH.Crdp.Network.ResourceTiming, connectionReused?: boolean}} RequestInfo */
49
+ /** @typedef {{record: Lantern.NetworkRequest, timing: LH.Crdp.Network.ResourceTiming, connectionReused?: boolean}} RequestInfo */
50
50
  /**
51
- * @param {LH.Artifacts.NetworkRequest[]} records
51
+ * @param {Lantern.NetworkRequest[]} records
52
52
  * @param {(e: RequestInfo) => number | number[] | undefined} iteratee
53
53
  * @return {Map<string, number[]>}
54
54
  */
55
- static _estimateValueByOrigin(records: LH.Artifacts.NetworkRequest[], iteratee: (e: {
56
- record: LH.Artifacts.NetworkRequest;
55
+ static _estimateValueByOrigin(records: Lantern.NetworkRequest[], iteratee: (e: {
56
+ record: Lantern.NetworkRequest;
57
57
  timing: LH.Crdp.Network.ResourceTiming;
58
58
  connectionReused?: boolean | undefined;
59
59
  }) => number | number[] | undefined): Map<string, number[]>;
@@ -69,7 +69,7 @@ export class NetworkAnalyzer {
69
69
  * @return {number[]|number|undefined}
70
70
  */
71
71
  static _estimateRTTViaConnectionTiming(info: {
72
- record: LH.Artifacts.NetworkRequest;
72
+ record: Lantern.NetworkRequest;
73
73
  timing: LH.Crdp.Network.ResourceTiming;
74
74
  connectionReused?: boolean | undefined;
75
75
  }): number[] | number | undefined;
@@ -82,7 +82,7 @@ export class NetworkAnalyzer {
82
82
  * @return {number|undefined}
83
83
  */
84
84
  static _estimateRTTViaDownloadTiming(info: {
85
- record: LH.Artifacts.NetworkRequest;
85
+ record: Lantern.NetworkRequest;
86
86
  timing: LH.Crdp.Network.ResourceTiming;
87
87
  connectionReused?: boolean | undefined;
88
88
  }): number | undefined;
@@ -96,7 +96,7 @@ export class NetworkAnalyzer {
96
96
  * @return {number|undefined}
97
97
  */
98
98
  static _estimateRTTViaSendStartTiming(info: {
99
- record: LH.Artifacts.NetworkRequest;
99
+ record: Lantern.NetworkRequest;
100
100
  timing: LH.Crdp.Network.ResourceTiming;
101
101
  connectionReused?: boolean | undefined;
102
102
  }): number | undefined;
@@ -110,32 +110,32 @@ export class NetworkAnalyzer {
110
110
  * @return {number|undefined}
111
111
  */
112
112
  static _estimateRTTViaHeadersEndTiming(info: {
113
- record: LH.Artifacts.NetworkRequest;
113
+ record: Lantern.NetworkRequest;
114
114
  timing: LH.Crdp.Network.ResourceTiming;
115
115
  connectionReused?: boolean | undefined;
116
116
  }): number | undefined;
117
117
  /**
118
118
  * Given the RTT to each origin, estimates the observed server response times.
119
119
  *
120
- * @param {LH.Artifacts.NetworkRequest[]} records
120
+ * @param {Lantern.NetworkRequest[]} records
121
121
  * @param {Map<string, number>} rttByOrigin
122
122
  * @return {Map<string, number[]>}
123
123
  */
124
- static _estimateResponseTimeByOrigin(records: LH.Artifacts.NetworkRequest[], rttByOrigin: Map<string, number>): Map<string, number[]>;
124
+ static _estimateResponseTimeByOrigin(records: Lantern.NetworkRequest[], rttByOrigin: Map<string, number>): Map<string, number[]>;
125
125
  /**
126
- * @param {LH.Artifacts.NetworkRequest[]} records
126
+ * @param {Lantern.NetworkRequest[]} records
127
127
  * @return {boolean}
128
128
  */
129
- static canTrustConnectionInformation(records: LH.Artifacts.NetworkRequest[]): boolean;
129
+ static canTrustConnectionInformation(records: Lantern.NetworkRequest[]): boolean;
130
130
  /**
131
131
  * Returns a map of requestId -> connectionReused, estimating the information if the information
132
132
  * available in the records themselves appears untrustworthy.
133
133
  *
134
- * @param {LH.Artifacts.NetworkRequest[]} records
134
+ * @param {Lantern.NetworkRequest[]} records
135
135
  * @param {{forceCoarseEstimates: boolean}} [options]
136
136
  * @return {Map<string, boolean>}
137
137
  */
138
- static estimateIfConnectionWasReused(records: LH.Artifacts.NetworkRequest[], options?: {
138
+ static estimateIfConnectionWasReused(records: Lantern.NetworkRequest[], options?: {
139
139
  forceCoarseEstimates: boolean;
140
140
  } | undefined): Map<string, boolean>;
141
141
  /**
@@ -143,20 +143,20 @@ export class NetworkAnalyzer {
143
143
  * Attempts to use the most accurate information first and falls back to coarser estimates when it
144
144
  * is unavailable.
145
145
  *
146
- * @param {LH.Artifacts.NetworkRequest[]} records
146
+ * @param {Lantern.NetworkRequest[]} records
147
147
  * @param {RTTEstimateOptions} [options]
148
148
  * @return {Map<string, Summary>}
149
149
  */
150
- static estimateRTTByOrigin(records: LH.Artifacts.NetworkRequest[], options?: RTTEstimateOptions | undefined): Map<string, Summary>;
150
+ static estimateRTTByOrigin(records: Lantern.NetworkRequest[], options?: RTTEstimateOptions | undefined): Map<string, Summary>;
151
151
  /**
152
152
  * Estimates the server response time of each origin. RTT times can be passed in or will be
153
153
  * estimated automatically if not provided.
154
154
  *
155
- * @param {LH.Artifacts.NetworkRequest[]} records
155
+ * @param {Lantern.NetworkRequest[]} records
156
156
  * @param {RTTEstimateOptions & {rttByOrigin?: Map<string, number>}} [options]
157
157
  * @return {Map<string, Summary>}
158
158
  */
159
- static estimateServerResponseTimeByOrigin(records: LH.Artifacts.NetworkRequest[], options?: (RTTEstimateOptions & {
159
+ static estimateServerResponseTimeByOrigin(records: Lantern.NetworkRequest[], options?: (RTTEstimateOptions & {
160
160
  rttByOrigin?: Map<string, number> | undefined;
161
161
  }) | undefined): Map<string, Summary>;
162
162
  /**
@@ -164,29 +164,33 @@ export class NetworkAnalyzer {
164
164
  * Excludes data URI, failed or otherwise incomplete, and cached requests.
165
165
  * Returns Infinity if there were no analyzable network records.
166
166
  *
167
- * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
167
+ * @param {Array<Lantern.NetworkRequest>} networkRecords
168
168
  * @return {number}
169
169
  */
170
- static estimateThroughput(networkRecords: Array<LH.Artifacts.NetworkRequest>): number;
170
+ static estimateThroughput(networkRecords: Array<Lantern.NetworkRequest>): number;
171
171
  /**
172
- * @param {Array<LH.Artifacts.NetworkRequest>} records
172
+ * @template {Lantern.NetworkRequest} T
173
+ * @param {Array<T>} records
173
174
  * @param {string} resourceUrl
174
- * @return {LH.Artifacts.NetworkRequest|undefined}
175
+ * @return {T|undefined}
175
176
  */
176
- static findResourceForUrl(records: Array<LH.Artifacts.NetworkRequest>, resourceUrl: string): LH.Artifacts.NetworkRequest | undefined;
177
+ static findResourceForUrl<T extends Lantern.NetworkRequest<any>>(records: T[], resourceUrl: string): T | undefined;
177
178
  /**
178
- * @param {Array<LH.Artifacts.NetworkRequest>} records
179
+ * @template {Lantern.NetworkRequest} T
180
+ * @param {Array<T>} records
179
181
  * @param {string} resourceUrl
180
- * @return {LH.Artifacts.NetworkRequest|undefined}
182
+ * @return {T|undefined}
181
183
  */
182
- static findLastDocumentForUrl(records: Array<LH.Artifacts.NetworkRequest>, resourceUrl: string): LH.Artifacts.NetworkRequest | undefined;
184
+ static findLastDocumentForUrl<T_1 extends Lantern.NetworkRequest<any>>(records: T_1[], resourceUrl: string): T_1 | undefined;
183
185
  /**
184
186
  * Resolves redirect chain given a main document.
185
187
  * See: {@link NetworkAnalyzer.findLastDocumentForUrl}) for how to retrieve main document.
186
188
  *
187
- * @param {LH.Artifacts.NetworkRequest} request
188
- * @return {LH.Artifacts.NetworkRequest}
189
+ * @template {Lantern.NetworkRequest} T
190
+ * @param {T} request
191
+ * @return {T}
189
192
  */
190
- static resolveRedirects(request: LH.Artifacts.NetworkRequest): LH.Artifacts.NetworkRequest;
193
+ static resolveRedirects<T_2 extends Lantern.NetworkRequest<any>>(request: T_2): T_2;
191
194
  }
195
+ import * as Lantern from '../types/lantern.js';
192
196
  //# sourceMappingURL=network-analyzer.d.ts.map
@@ -4,6 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
+ import * as Lantern from '../types/lantern.js';
7
8
  import UrlUtils from '../../url-utils.js';
8
9
 
9
10
  const INITIAL_CWD = 14 * 1024;
@@ -31,8 +32,8 @@ class NetworkAnalyzer {
31
32
  }
32
33
 
33
34
  /**
34
- * @param {LH.Artifacts.NetworkRequest[]} records
35
- * @return {Map<string, LH.Artifacts.NetworkRequest[]>}
35
+ * @param {Lantern.NetworkRequest[]} records
36
+ * @return {Map<string, Lantern.NetworkRequest[]>}
36
37
  */
37
38
  static groupByOrigin(records) {
38
39
  const grouped = new Map();
@@ -87,10 +88,10 @@ class NetworkAnalyzer {
87
88
  return summaryByKey;
88
89
  }
89
90
 
90
- /** @typedef {{record: LH.Artifacts.NetworkRequest, timing: LH.Crdp.Network.ResourceTiming, connectionReused?: boolean}} RequestInfo */
91
+ /** @typedef {{record: Lantern.NetworkRequest, timing: LH.Crdp.Network.ResourceTiming, connectionReused?: boolean}} RequestInfo */
91
92
 
92
93
  /**
93
- * @param {LH.Artifacts.NetworkRequest[]} records
94
+ * @param {Lantern.NetworkRequest[]} records
94
95
  * @param {(e: RequestInfo) => number | number[] | undefined} iteratee
95
96
  * @return {Map<string, number[]>}
96
97
  */
@@ -249,7 +250,7 @@ class NetworkAnalyzer {
249
250
  /**
250
251
  * Given the RTT to each origin, estimates the observed server response times.
251
252
  *
252
- * @param {LH.Artifacts.NetworkRequest[]} records
253
+ * @param {Lantern.NetworkRequest[]} records
253
254
  * @param {Map<string, number>} rttByOrigin
254
255
  * @return {Map<string, number[]>}
255
256
  */
@@ -270,7 +271,7 @@ class NetworkAnalyzer {
270
271
  }
271
272
 
272
273
  /**
273
- * @param {LH.Artifacts.NetworkRequest[]} records
274
+ * @param {Lantern.NetworkRequest[]} records
274
275
  * @return {boolean}
275
276
  */
276
277
  static canTrustConnectionInformation(records) {
@@ -290,7 +291,7 @@ class NetworkAnalyzer {
290
291
  * Returns a map of requestId -> connectionReused, estimating the information if the information
291
292
  * available in the records themselves appears untrustworthy.
292
293
  *
293
- * @param {LH.Artifacts.NetworkRequest[]} records
294
+ * @param {Lantern.NetworkRequest[]} records
294
295
  * @param {{forceCoarseEstimates: boolean}} [options]
295
296
  * @return {Map<string, boolean>}
296
297
  */
@@ -334,7 +335,7 @@ class NetworkAnalyzer {
334
335
  * Attempts to use the most accurate information first and falls back to coarser estimates when it
335
336
  * is unavailable.
336
337
  *
337
- * @param {LH.Artifacts.NetworkRequest[]} records
338
+ * @param {Lantern.NetworkRequest[]} records
338
339
  * @param {RTTEstimateOptions} [options]
339
340
  * @return {Map<string, Summary>}
340
341
  */
@@ -415,7 +416,7 @@ class NetworkAnalyzer {
415
416
  * Estimates the server response time of each origin. RTT times can be passed in or will be
416
417
  * estimated automatically if not provided.
417
418
  *
418
- * @param {LH.Artifacts.NetworkRequest[]} records
419
+ * @param {Lantern.NetworkRequest[]} records
419
420
  * @param {RTTEstimateOptions & {rttByOrigin?: Map<string, number>}} [options]
420
421
  * @return {Map<string, Summary>}
421
422
  */
@@ -441,7 +442,7 @@ class NetworkAnalyzer {
441
442
  * Excludes data URI, failed or otherwise incomplete, and cached requests.
442
443
  * Returns Infinity if there were no analyzable network records.
443
444
  *
444
- * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
445
+ * @param {Array<Lantern.NetworkRequest>} networkRecords
445
446
  * @return {number}
446
447
  */
447
448
  static estimateThroughput(networkRecords) {
@@ -494,9 +495,10 @@ class NetworkAnalyzer {
494
495
  }
495
496
 
496
497
  /**
497
- * @param {Array<LH.Artifacts.NetworkRequest>} records
498
+ * @template {Lantern.NetworkRequest} T
499
+ * @param {Array<T>} records
498
500
  * @param {string} resourceUrl
499
- * @return {LH.Artifacts.NetworkRequest|undefined}
501
+ * @return {T|undefined}
500
502
  */
501
503
  static findResourceForUrl(records, resourceUrl) {
502
504
  // equalWithExcludedFragments is expensive, so check that the resourceUrl starts with the request url first
@@ -507,9 +509,10 @@ class NetworkAnalyzer {
507
509
  }
508
510
 
509
511
  /**
510
- * @param {Array<LH.Artifacts.NetworkRequest>} records
512
+ * @template {Lantern.NetworkRequest} T
513
+ * @param {Array<T>} records
511
514
  * @param {string} resourceUrl
512
- * @return {LH.Artifacts.NetworkRequest|undefined}
515
+ * @return {T|undefined}
513
516
  */
514
517
  static findLastDocumentForUrl(records, resourceUrl) {
515
518
  // equalWithExcludedFragments is expensive, so check that the resourceUrl starts with the request url first
@@ -526,11 +529,12 @@ class NetworkAnalyzer {
526
529
  * Resolves redirect chain given a main document.
527
530
  * See: {@link NetworkAnalyzer.findLastDocumentForUrl}) for how to retrieve main document.
528
531
  *
529
- * @param {LH.Artifacts.NetworkRequest} request
530
- * @return {LH.Artifacts.NetworkRequest}
532
+ * @template {Lantern.NetworkRequest} T
533
+ * @param {T} request
534
+ * @return {T}
531
535
  */
532
536
  static resolveRedirects(request) {
533
- while (request.redirectDestination) request = request.redirectDestination;
537
+ while (request.redirectDestination) request = /** @type {T} */(request.redirectDestination);
534
538
  return request;
535
539
  }
536
540
  }
@@ -3,9 +3,12 @@ export type NetworkNode = import('../network-node.js').NetworkNode;
3
3
  export type CpuNode = import('../cpu-node.js').CPUNode;
4
4
  export type CompleteNodeTiming = import('./simulator-timing-map.js').CpuNodeTimingComplete | import('./simulator-timing-map.js').NetworkNodeTimingComplete;
5
5
  export type ConnectionTiming = import('./simulator-timing-map.js').ConnectionTiming;
6
- export class Simulator {
6
+ /**
7
+ * @template [T=any]
8
+ */
9
+ export class Simulator<T = any> {
7
10
  /** @return {Map<string, Map<Node, CompleteNodeTiming>>} */
8
- static get ALL_NODE_TIMINGS(): Map<string, Map<import("../base-node.js").Node, CompleteNodeTiming>>;
11
+ static get ALL_NODE_TIMINGS(): Map<string, Map<Node, CompleteNodeTiming>>;
9
12
  /**
10
13
  * We attempt to start nodes by their observed start time using the record priority as a tie breaker.
11
14
  * When simulating, just because a low priority image started 5ms before a high priority image doesn't mean
@@ -14,11 +17,11 @@ export class Simulator {
14
17
  */
15
18
  static _computeNodeStartPosition(node: Node): number;
16
19
  /**
17
- * @param {LH.Gatherer.Simulation.Options} [options]
20
+ * @param {Lantern.Simulation.Options} [options]
18
21
  */
19
- constructor(options?: LH.Gatherer.Simulation.Options | undefined);
20
- /** @type {Required<LH.Gatherer.Simulation.Options>} */
21
- _options: Required<LH.Gatherer.Simulation.Options>;
22
+ constructor(options?: Lantern.Simulation.Options | undefined);
23
+ /** @type {Required<Lantern.Simulation.Options>} */
24
+ _options: Required<Lantern.Simulation.Options>;
22
25
  _rtt: number;
23
26
  _throughput: number;
24
27
  _maximumConcurrentRequests: number;
@@ -67,10 +70,10 @@ export class Simulator {
67
70
  */
68
71
  _markNodeAsComplete(node: Node, endTime: number, connectionTiming?: import("./simulator-timing-map.js").ConnectionTiming | undefined): void;
69
72
  /**
70
- * @param {LH.Artifacts.NetworkRequest} record
73
+ * @param {Lantern.NetworkRequest} record
71
74
  * @return {?TcpConnection}
72
75
  */
73
- _acquireConnection(record: LH.Artifacts.NetworkRequest): TcpConnection | null;
76
+ _acquireConnection(record: Lantern.NetworkRequest): TcpConnection | null;
74
77
  /**
75
78
  * @return {Node[]}
76
79
  */
@@ -114,16 +117,16 @@ export class Simulator {
114
117
  */
115
118
  _updateProgressMadeInTimePeriod(node: Node, timePeriodLength: number, totalElapsedTime: number): number | void;
116
119
  /**
117
- * @return {{nodeTimings: Map<Node, LH.Gatherer.Simulation.NodeTiming>, completeNodeTimings: Map<Node, CompleteNodeTiming>}}
120
+ * @return {{nodeTimings: Map<Node, Lantern.Simulation.NodeTiming>, completeNodeTimings: Map<Node, CompleteNodeTiming>}}
118
121
  */
119
122
  _computeFinalNodeTimings(): {
120
- nodeTimings: Map<Node, LH.Gatherer.Simulation.NodeTiming>;
123
+ nodeTimings: Map<Node, Lantern.Simulation.NodeTiming>;
121
124
  completeNodeTimings: Map<Node, CompleteNodeTiming>;
122
125
  };
123
126
  /**
124
- * @return {Required<LH.Gatherer.Simulation.Options>}
127
+ * @return {Required<Lantern.Simulation.Options>}
125
128
  */
126
- getOptions(): Required<LH.Gatherer.Simulation.Options>;
129
+ getOptions(): Required<Lantern.Simulation.Options>;
127
130
  /**
128
131
  * Estimates the time taken to process all of the graph's nodes, returns the overall time along with
129
132
  * each node annotated by start/end times.
@@ -135,18 +138,18 @@ export class Simulator {
135
138
  *
136
139
  * @param {Node} graph
137
140
  * @param {{flexibleOrdering?: boolean, label?: string}=} options
138
- * @return {LH.Gatherer.Simulation.Result}
141
+ * @return {Lantern.Simulation.Result<T>}
139
142
  */
140
143
  simulate(graph: Node, options?: {
141
144
  flexibleOrdering?: boolean;
142
145
  label?: string;
143
- } | undefined): LH.Gatherer.Simulation.Result;
146
+ } | undefined): Lantern.Simulation.Result<T>;
144
147
  /**
145
148
  * @param {number} wastedBytes
146
149
  */
147
150
  computeWastedMsFromWastedBytes(wastedBytes: number): number;
148
151
  }
149
- import * as LH from '../../../../types/lh.js';
152
+ import * as Lantern from '../types/lantern.js';
150
153
  import { SimulatorTimingMap } from './simulator-timing-map.js';
151
154
  import { DNSCache } from './dns-cache.js';
152
155
  import { ConnectionPool } from './connection-pool.js';
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
- import * as LH from '../../../../types/lh.js';
7
+ import * as Lantern from '../types/lantern.js';
8
8
  import {BaseNode} from '../base-node.js';
9
9
  import {TcpConnection} from './tcp-connection.js';
10
10
  import {ConnectionPool} from './connection-pool.js';
@@ -46,12 +46,15 @@ const PriorityStartTimePenalty = {
46
46
  /** @type {Map<string, Map<Node, CompleteNodeTiming>>} */
47
47
  const ALL_SIMULATION_NODE_TIMINGS = new Map();
48
48
 
49
+ /**
50
+ * @template [T=any]
51
+ */
49
52
  class Simulator {
50
53
  /**
51
- * @param {LH.Gatherer.Simulation.Options} [options]
54
+ * @param {Lantern.Simulation.Options} [options]
52
55
  */
53
56
  constructor(options) {
54
- /** @type {Required<LH.Gatherer.Simulation.Options>} */
57
+ /** @type {Required<Lantern.Simulation.Options>} */
55
58
  this._options = Object.assign(
56
59
  {
57
60
  rtt: mobileSlow4G.rttMs,
@@ -101,11 +104,11 @@ class Simulator {
101
104
  * @param {Node} graph
102
105
  */
103
106
  _initializeConnectionPool(graph) {
104
- /** @type {LH.Artifacts.NetworkRequest[]} */
107
+ /** @type {Lantern.NetworkRequest[]} */
105
108
  const records = [];
106
109
  graph.getRootNode().traverse(node => {
107
110
  if (node.type === BaseNode.TYPES.NETWORK) {
108
- records.push(node.record);
111
+ records.push(node.request);
109
112
  }
110
113
  });
111
114
 
@@ -190,7 +193,7 @@ class Simulator {
190
193
  }
191
194
 
192
195
  /**
193
- * @param {LH.Artifacts.NetworkRequest} record
196
+ * @param {Lantern.NetworkRequest} record
194
197
  * @return {?TcpConnection}
195
198
  */
196
199
  _acquireConnection(record) {
@@ -228,7 +231,7 @@ class Simulator {
228
231
  // Start a network request if we're not at max requests and a connection is available
229
232
  const numberOfActiveRequests = this._numberInProgress(node.type);
230
233
  if (numberOfActiveRequests >= this._maximumConcurrentRequests) return;
231
- const connection = this._acquireConnection(node.record);
234
+ const connection = this._acquireConnection(node.request);
232
235
  if (!connection) return;
233
236
  }
234
237
 
@@ -286,7 +289,7 @@ class Simulator {
286
289
  * @return {number}
287
290
  */
288
291
  _estimateNetworkTimeRemaining(networkNode) {
289
- const record = networkNode.record;
292
+ const record = networkNode.request;
290
293
  const timingData = this._nodeTimings.getNetworkStarted(networkNode);
291
294
 
292
295
  let timeElapsed = 0;
@@ -354,7 +357,7 @@ class Simulator {
354
357
  if (node.type !== BaseNode.TYPES.NETWORK) throw new Error('Unsupported');
355
358
  if (!('bytesDownloaded' in timingData)) throw new Error('Invalid timing data');
356
359
 
357
- const record = node.record;
360
+ const record = node.request;
358
361
  const connection = this._connectionPool.acquireActiveConnectionFromRecord(record);
359
362
  const dnsResolutionTime = this._dns.getTimeUntilResolution(record, {
360
363
  requestedAt: timingData.startTime,
@@ -384,7 +387,7 @@ class Simulator {
384
387
  }
385
388
 
386
389
  /**
387
- * @return {{nodeTimings: Map<Node, LH.Gatherer.Simulation.NodeTiming>, completeNodeTimings: Map<Node, CompleteNodeTiming>}}
390
+ * @return {{nodeTimings: Map<Node, Lantern.Simulation.NodeTiming>, completeNodeTimings: Map<Node, CompleteNodeTiming>}}
388
391
  */
389
392
  _computeFinalNodeTimings() {
390
393
  /** @type {Array<[Node, CompleteNodeTiming]>} */
@@ -395,8 +398,8 @@ class Simulator {
395
398
  // Most consumers will want the entries sorted by startTime, so insert them in that order
396
399
  completeNodeTimingEntries.sort((a, b) => a[1].startTime - b[1].startTime);
397
400
 
398
- // Trimmed version of type `LH.Gatherer.Simulation.NodeTiming`.
399
- /** @type {Array<[Node, LH.Gatherer.Simulation.NodeTiming]>} */
401
+ // Trimmed version of type `Lantern.Simulation.NodeTiming`.
402
+ /** @type {Array<[Node, Lantern.Simulation.NodeTiming]>} */
400
403
  const nodeTimingEntries = completeNodeTimingEntries.map(([node, timing]) => {
401
404
  return [node, {
402
405
  startTime: timing.startTime,
@@ -412,7 +415,7 @@ class Simulator {
412
415
  }
413
416
 
414
417
  /**
415
- * @return {Required<LH.Gatherer.Simulation.Options>}
418
+ * @return {Required<Lantern.Simulation.Options>}
416
419
  */
417
420
  getOptions() {
418
421
  return this._options;
@@ -429,7 +432,7 @@ class Simulator {
429
432
  *
430
433
  * @param {Node} graph
431
434
  * @param {{flexibleOrdering?: boolean, label?: string}=} options
432
- * @return {LH.Gatherer.Simulation.Result}
435
+ * @return {Lantern.Simulation.Result<T>}
433
436
  */
434
437
  simulate(graph, options) {
435
438
  if (BaseNode.hasCycle(graph)) {
@@ -535,7 +538,7 @@ class Simulator {
535
538
  */
536
539
  static _computeNodeStartPosition(node) {
537
540
  if (node.type === 'cpu') return node.startTime;
538
- return node.startTime + (PriorityStartTimePenalty[node.record.priority] * 1000 * 1000 || 0);
541
+ return node.startTime + (PriorityStartTimePenalty[node.request.priority] * 1000 * 1000 || 0);
539
542
  }
540
543
  }
541
544
 
@@ -0,0 +1,129 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import * as LH from '../../../../types/lh.js';
8
+
9
+ type ParsedURL = {
10
+ /**
11
+ * Equivalent to a `new URL(url).protocol` BUT w/o the trailing colon (:)
12
+ */
13
+ scheme: string;
14
+ /**
15
+ * Equivalent to a `new URL(url).hostname`
16
+ */
17
+ host: string;
18
+ securityOrigin: string;
19
+ };
20
+ type LightriderStatistics = {
21
+ /**
22
+ * The difference in networkEndTime between the observed Lighthouse networkEndTime and Lightrider's derived networkEndTime.
23
+ */
24
+ endTimeDeltaMs: number;
25
+ /**
26
+ * The time spent making a TCP connection (connect + SSL). Note: this is poorly named.
27
+ */
28
+ TCPMs: number;
29
+ /**
30
+ * The time spent requesting a resource from a remote server, we use this to approx RTT. Note: this is poorly names, it really should be "server response time".
31
+ */
32
+ requestMs: number;
33
+ /**
34
+ * Time to receive the entire response payload starting the clock on receiving the first fragment (first non-header byte).
35
+ */
36
+ responseMs: number;
37
+ };
38
+
39
+ export class NetworkRequest<T = any> {
40
+ /**
41
+ * The canonical network record.
42
+ * Users of Lantern must create NetworkRequests matching this interface,
43
+ * but can store the source-of-truth for their network model in this `record`
44
+ * property. This is then accessible as a read-only property on NetworkNode.
45
+ */
46
+ record?: T;
47
+
48
+ requestId: string;
49
+ connectionId: string;
50
+ connectionReused: boolean;
51
+ url: string;
52
+ protocol: string;
53
+ parsedURL: ParsedURL;
54
+ documentURL: string;
55
+ /** When the renderer process initially discovers a network request, in milliseconds. */
56
+ rendererStartTime: number;
57
+ /**
58
+ * When the network service is about to handle a request, ie. just before going to the
59
+ * HTTP cache or going to the network for DNS/connection setup, in milliseconds.
60
+ */
61
+ networkRequestTime: number;
62
+ /** When the last byte of the response headers is received, in milliseconds. */
63
+ responseHeadersEndTime: number;
64
+ /** When the last byte of the response body is received, in milliseconds. */
65
+ networkEndTime: number;
66
+ transferSize: number;
67
+ resourceSize: number;
68
+ fromDiskCache: boolean;
69
+ fromMemoryCache: boolean;
70
+ // TODO(15841): remove from lantern.
71
+ /** Extra timing information available only when run in Lightrider. */
72
+ lrStatistics: LightriderStatistics | undefined;
73
+ finished: boolean;
74
+ statusCode: number;
75
+ /** The network request that this one redirected to */
76
+ redirectDestination: NetworkRequest<T> | undefined;
77
+ failed: boolean;
78
+ initiator: LH.Crdp.Network.Initiator;
79
+ initiatorRequest: NetworkRequest<T> | undefined;
80
+ /** The chain of network requests that redirected to this one */
81
+ redirects: NetworkRequest[] | undefined;
82
+ timing: LH.Crdp.Network.ResourceTiming | undefined;
83
+ resourceType: LH.Crdp.Network.ResourceType | undefined;
84
+ mimeType: string;
85
+ priority: LH.Crdp.Network.ResourcePriority;
86
+ frameId: string | undefined;
87
+ sessionTargetType: LH.Protocol.TargetType | undefined;
88
+ }
89
+
90
+ export namespace Simulation {
91
+ type GraphNode<T> = import('../base-node.js').Node<T>;
92
+ type GraphNetworkNode<T> = import('../network-node.js').NetworkNode<T>;
93
+ type GraphCPUNode = import('../cpu-node.js').CPUNode;
94
+ type Simulator<T> = import('../simulator/simulator.js').Simulator<T>;
95
+
96
+ interface MetricCoefficients {
97
+ intercept: number;
98
+ optimistic: number;
99
+ pessimistic: number;
100
+ }
101
+
102
+ interface Options {
103
+ rtt?: number;
104
+ throughput?: number;
105
+ observedThroughput: number;
106
+ maximumConcurrentRequests?: number;
107
+ cpuSlowdownMultiplier?: number;
108
+ layoutTaskMultiplier?: number;
109
+ additionalRttByOrigin?: Map<string, number>;
110
+ serverResponseTimeByOrigin?: Map<string, number>;
111
+ }
112
+
113
+ interface NodeTiming {
114
+ startTime: number;
115
+ endTime: number;
116
+ duration: number;
117
+ }
118
+
119
+ interface Result<T = any> {
120
+ timeInMs: number;
121
+ nodeTimings: Map<GraphNode<T>, NodeTiming>;
122
+ }
123
+
124
+ interface MetricComputationDataInput {
125
+ simulator: Simulator<any>;
126
+ graph: GraphNode<any>;
127
+ processedNavigation: LH.Artifacts.ProcessedNavigation;
128
+ }
129
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ export {};
@@ -3,15 +3,15 @@ declare namespace _default {
3
3
  export { convertNodeTimingsToTrace };
4
4
  }
5
5
  export default _default;
6
- export type Node = import('./dependency-graph/base-node.js').Node;
7
- export type CompleteNodeTiming = import('./dependency-graph/simulator/simulator.js').CompleteNodeTiming;
6
+ export type Node = import('./lantern/base-node.js').Node<LH.Artifacts.NetworkRequest>;
7
+ export type CompleteNodeTiming = import('./lantern/simulator/simulator.js').CompleteNodeTiming;
8
8
  /**
9
9
  * @license
10
10
  * Copyright 2018 Google LLC
11
11
  * SPDX-License-Identifier: Apache-2.0
12
12
  */
13
- /** @typedef {import('./dependency-graph/base-node.js').Node} Node */
14
- /** @typedef {import('./dependency-graph/simulator/simulator.js').CompleteNodeTiming} CompleteNodeTiming */
13
+ /** @typedef {import('./lantern/base-node.js').Node<LH.Artifacts.NetworkRequest>} Node */
14
+ /** @typedef {import('./lantern/simulator/simulator.js').CompleteNodeTiming} CompleteNodeTiming */
15
15
  /**
16
16
  * @param {Map<Node, CompleteNodeTiming>} nodeTimings
17
17
  * @return {LH.Trace}