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.
- package/cli/test/smokehouse/core-tests.js +2 -2
- package/core/audits/byte-efficiency/byte-efficiency-audit.d.ts +2 -2
- package/core/audits/byte-efficiency/byte-efficiency-audit.js +7 -7
- package/core/audits/byte-efficiency/render-blocking-resources.d.ts +4 -3
- package/core/audits/byte-efficiency/render-blocking-resources.js +6 -6
- package/core/audits/dobetterweb/uses-http2.d.ts +3 -3
- package/core/audits/dobetterweb/uses-http2.js +4 -4
- package/core/audits/installable-manifest.d.ts +2 -0
- package/core/audits/installable-manifest.js +2 -0
- package/core/audits/metrics/interaction-to-next-paint.js +1 -3
- package/core/audits/prioritize-lcp-image.d.ts +1 -1
- package/core/audits/work-during-interaction.js +0 -8
- package/core/computed/document-urls.js +1 -1
- package/core/computed/load-simulator.d.ts +2 -2
- package/core/computed/load-simulator.js +3 -2
- package/core/computed/main-resource.js +1 -1
- package/core/computed/metrics/lantern-first-contentful-paint.d.ts +18 -6
- package/core/computed/metrics/lantern-first-contentful-paint.js +4 -4
- package/core/computed/metrics/lantern-first-meaningful-paint.d.ts +14 -2
- package/core/computed/metrics/lantern-first-meaningful-paint.js +1 -1
- package/core/computed/metrics/lantern-interactive.d.ts +8 -6
- package/core/computed/metrics/lantern-interactive.js +3 -3
- package/core/computed/metrics/lantern-largest-contentful-paint.d.ts +14 -2
- package/core/computed/metrics/lantern-largest-contentful-paint.js +1 -1
- package/core/computed/metrics/lantern-max-potential-fid.d.ts +8 -2
- package/core/computed/metrics/lantern-max-potential-fid.js +3 -3
- package/core/computed/metrics/lantern-metric.d.ts +4 -63
- package/core/computed/metrics/lantern-metric.js +6 -124
- package/core/computed/metrics/lantern-speed-index.d.ts +8 -2
- package/core/computed/metrics/lantern-speed-index.js +3 -3
- package/core/computed/metrics/lantern-total-blocking-time.d.ts +8 -2
- package/core/computed/metrics/lantern-total-blocking-time.js +3 -3
- package/core/computed/metrics/responsiveness.d.ts +5 -13
- package/core/computed/metrics/responsiveness.js +10 -14
- package/core/computed/network-analysis.js +1 -1
- package/core/computed/page-dependency-graph.d.ts +4 -57
- package/core/computed/page-dependency-graph.js +4 -451
- package/core/config/config-helpers.js +1 -1
- package/core/gather/driver/execution-context.d.ts +2 -1
- package/core/gather/driver/execution-context.js +9 -9
- package/core/gather/driver/wait-for-condition.js +4 -2
- package/core/gather/gatherers/accessibility.js +2 -1
- package/core/gather/gatherers/css-usage.d.ts +1 -9
- package/core/gather/gatherers/css-usage.js +23 -25
- package/core/gather/gatherers/devtools-log.d.ts +4 -0
- package/core/gather/gatherers/devtools-log.js +7 -0
- package/core/gather/gatherers/full-page-screenshot.d.ts +4 -0
- package/core/gather/gatherers/full-page-screenshot.js +31 -35
- package/core/gather/gatherers/root-causes.js +1 -3
- package/core/gather/gatherers/trace-elements.js +1 -1
- package/core/gather/gatherers/trace.d.ts +1 -0
- package/core/gather/gatherers/trace.js +4 -0
- package/core/gather/navigation-runner.js +49 -62
- package/core/gather/session.js +5 -0
- package/core/gather/snapshot-runner.js +25 -25
- package/core/gather/timespan-runner.js +24 -25
- package/core/lib/asset-saver.js +1 -1
- package/core/lib/emulation.js +0 -3
- package/core/lib/{dependency-graph → lantern}/base-node.d.ts +12 -8
- package/core/lib/{dependency-graph → lantern}/base-node.js +8 -3
- package/core/lib/{dependency-graph → lantern}/cpu-node.d.ts +5 -1
- package/core/lib/{dependency-graph → lantern}/cpu-node.js +4 -0
- package/core/lib/lantern/lantern.d.ts +8 -0
- package/core/lib/lantern/lantern.js +31 -0
- package/core/lib/lantern/metric.d.ts +71 -0
- package/core/lib/lantern/metric.js +143 -0
- package/core/lib/{dependency-graph → lantern}/network-node.d.ts +17 -10
- package/core/lib/lantern/network-node.js +114 -0
- package/core/lib/lantern/page-dependency-graph.d.ts +58 -0
- package/core/lib/lantern/page-dependency-graph.js +463 -0
- package/core/lib/{dependency-graph → lantern}/simulator/connection-pool.d.ts +14 -14
- package/core/lib/{dependency-graph → lantern}/simulator/connection-pool.js +7 -7
- package/core/lib/{dependency-graph → lantern}/simulator/dns-cache.d.ts +5 -5
- package/core/lib/{dependency-graph → lantern}/simulator/dns-cache.js +3 -3
- package/core/lib/{dependency-graph → lantern}/simulator/network-analyzer.d.ts +36 -32
- package/core/lib/{dependency-graph → lantern}/simulator/network-analyzer.js +21 -17
- package/core/lib/{dependency-graph → lantern}/simulator/simulator.d.ts +18 -15
- package/core/lib/{dependency-graph → lantern}/simulator/simulator.js +18 -15
- package/core/lib/lantern/types/lantern.d.ts +129 -0
- package/core/lib/lantern/types/lantern.js +7 -0
- package/core/lib/lantern-trace-saver.d.ts +4 -4
- package/core/lib/lantern-trace-saver.js +6 -4
- package/core/lib/navigation-error.js +1 -1
- package/core/lib/network-recorder.js +2 -2
- package/core/lib/network-request.d.ts +6 -0
- package/core/lib/network-request.js +12 -0
- package/package.json +4 -5
- package/shared/localization/locales/ar-XB.json +1 -1
- package/shared/localization/locales/ar.json +1 -1
- package/shared/localization/locales/bg.json +1 -1
- package/shared/localization/locales/ca.json +1 -1
- package/shared/localization/locales/cs.json +1 -1
- package/shared/localization/locales/da.json +2 -2
- package/shared/localization/locales/de.json +1 -1
- package/shared/localization/locales/el.json +1 -1
- package/shared/localization/locales/en-GB.json +1 -1
- package/shared/localization/locales/en-US.json +3 -0
- package/shared/localization/locales/en-XA.json +1 -1
- package/shared/localization/locales/en-XL.json +3 -0
- package/shared/localization/locales/es-419.json +1 -1
- package/shared/localization/locales/es.json +1 -1
- package/shared/localization/locales/fi.json +1 -1
- package/shared/localization/locales/fil.json +1 -1
- package/shared/localization/locales/he.json +1 -1
- package/shared/localization/locales/hi.json +1 -1
- package/shared/localization/locales/hr.json +1 -1
- package/shared/localization/locales/hu.json +1 -1
- package/shared/localization/locales/id.json +1 -1
- package/shared/localization/locales/it.json +1 -1
- package/shared/localization/locales/ko.json +1 -1
- package/shared/localization/locales/lt.json +1 -1
- package/shared/localization/locales/nl.json +1 -1
- package/shared/localization/locales/no.json +1 -1
- package/shared/localization/locales/pl.json +1 -1
- package/shared/localization/locales/pt-PT.json +1 -1
- package/shared/localization/locales/pt.json +1 -1
- package/shared/localization/locales/ro.json +1 -1
- package/shared/localization/locales/sk.json +1 -1
- package/shared/localization/locales/sl.json +1 -1
- package/shared/localization/locales/sr-Latn.json +1 -1
- package/shared/localization/locales/sr.json +1 -1
- package/shared/localization/locales/sv.json +1 -1
- package/shared/localization/locales/ta.json +1 -1
- package/shared/localization/locales/te.json +1 -1
- package/shared/localization/locales/th.json +4 -4
- package/shared/localization/locales/tr.json +1 -1
- package/shared/localization/locales/uk.json +1 -1
- package/shared/localization/locales/vi.json +1 -1
- package/shared/localization/locales/zh-HK.json +1 -1
- package/shared/localization/locales/zh-TW.json +1 -1
- package/shared/localization/locales/zh.json +1 -1
- package/third-party/chromium-synchronization/installability-errors-test.js +1 -1
- package/tsconfig.json +7 -5
- package/types/artifacts.d.ts +1 -1
- package/types/gatherer.d.ts +8 -35
- package/types/lhr/lhr.d.ts +1 -1
- package/core/lib/dependency-graph/network-node.js +0 -99
- /package/core/lib/{dependency-graph → lantern}/simulator/simulator-timing-map.d.ts +0 -0
- /package/core/lib/{dependency-graph → lantern}/simulator/simulator-timing-map.js +0 -0
- /package/core/lib/{dependency-graph → lantern}/simulator/tcp-connection.d.ts +0 -0
- /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 {
|
|
36
|
-
* @return {Map<string,
|
|
35
|
+
* @param {Lantern.NetworkRequest[]} records
|
|
36
|
+
* @return {Map<string, Lantern.NetworkRequest[]>}
|
|
37
37
|
*/
|
|
38
|
-
static groupByOrigin(records:
|
|
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:
|
|
49
|
+
/** @typedef {{record: Lantern.NetworkRequest, timing: LH.Crdp.Network.ResourceTiming, connectionReused?: boolean}} RequestInfo */
|
|
50
50
|
/**
|
|
51
|
-
* @param {
|
|
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:
|
|
56
|
-
record:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 {
|
|
120
|
+
* @param {Lantern.NetworkRequest[]} records
|
|
121
121
|
* @param {Map<string, number>} rttByOrigin
|
|
122
122
|
* @return {Map<string, number[]>}
|
|
123
123
|
*/
|
|
124
|
-
static _estimateResponseTimeByOrigin(records:
|
|
124
|
+
static _estimateResponseTimeByOrigin(records: Lantern.NetworkRequest[], rttByOrigin: Map<string, number>): Map<string, number[]>;
|
|
125
125
|
/**
|
|
126
|
-
* @param {
|
|
126
|
+
* @param {Lantern.NetworkRequest[]} records
|
|
127
127
|
* @return {boolean}
|
|
128
128
|
*/
|
|
129
|
-
static canTrustConnectionInformation(records:
|
|
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 {
|
|
134
|
+
* @param {Lantern.NetworkRequest[]} records
|
|
135
135
|
* @param {{forceCoarseEstimates: boolean}} [options]
|
|
136
136
|
* @return {Map<string, boolean>}
|
|
137
137
|
*/
|
|
138
|
-
static estimateIfConnectionWasReused(records:
|
|
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 {
|
|
146
|
+
* @param {Lantern.NetworkRequest[]} records
|
|
147
147
|
* @param {RTTEstimateOptions} [options]
|
|
148
148
|
* @return {Map<string, Summary>}
|
|
149
149
|
*/
|
|
150
|
-
static estimateRTTByOrigin(records:
|
|
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 {
|
|
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:
|
|
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<
|
|
167
|
+
* @param {Array<Lantern.NetworkRequest>} networkRecords
|
|
168
168
|
* @return {number}
|
|
169
169
|
*/
|
|
170
|
-
static estimateThroughput(networkRecords: Array<
|
|
170
|
+
static estimateThroughput(networkRecords: Array<Lantern.NetworkRequest>): number;
|
|
171
171
|
/**
|
|
172
|
-
* @
|
|
172
|
+
* @template {Lantern.NetworkRequest} T
|
|
173
|
+
* @param {Array<T>} records
|
|
173
174
|
* @param {string} resourceUrl
|
|
174
|
-
* @return {
|
|
175
|
+
* @return {T|undefined}
|
|
175
176
|
*/
|
|
176
|
-
static findResourceForUrl(records:
|
|
177
|
+
static findResourceForUrl<T extends Lantern.NetworkRequest<any>>(records: T[], resourceUrl: string): T | undefined;
|
|
177
178
|
/**
|
|
178
|
-
* @
|
|
179
|
+
* @template {Lantern.NetworkRequest} T
|
|
180
|
+
* @param {Array<T>} records
|
|
179
181
|
* @param {string} resourceUrl
|
|
180
|
-
* @return {
|
|
182
|
+
* @return {T|undefined}
|
|
181
183
|
*/
|
|
182
|
-
static findLastDocumentForUrl(records:
|
|
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
|
-
* @
|
|
188
|
-
* @
|
|
189
|
+
* @template {Lantern.NetworkRequest} T
|
|
190
|
+
* @param {T} request
|
|
191
|
+
* @return {T}
|
|
189
192
|
*/
|
|
190
|
-
static resolveRedirects(request:
|
|
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 {
|
|
35
|
-
* @return {Map<string,
|
|
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:
|
|
91
|
+
/** @typedef {{record: Lantern.NetworkRequest, timing: LH.Crdp.Network.ResourceTiming, connectionReused?: boolean}} RequestInfo */
|
|
91
92
|
|
|
92
93
|
/**
|
|
93
|
-
* @param {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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<
|
|
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
|
-
* @
|
|
498
|
+
* @template {Lantern.NetworkRequest} T
|
|
499
|
+
* @param {Array<T>} records
|
|
498
500
|
* @param {string} resourceUrl
|
|
499
|
-
* @return {
|
|
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
|
-
* @
|
|
512
|
+
* @template {Lantern.NetworkRequest} T
|
|
513
|
+
* @param {Array<T>} records
|
|
511
514
|
* @param {string} resourceUrl
|
|
512
|
-
* @return {
|
|
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
|
-
* @
|
|
530
|
-
* @
|
|
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
|
-
|
|
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<
|
|
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 {
|
|
20
|
+
* @param {Lantern.Simulation.Options} [options]
|
|
18
21
|
*/
|
|
19
|
-
constructor(options?:
|
|
20
|
-
/** @type {Required<
|
|
21
|
-
_options: Required<
|
|
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 {
|
|
73
|
+
* @param {Lantern.NetworkRequest} record
|
|
71
74
|
* @return {?TcpConnection}
|
|
72
75
|
*/
|
|
73
|
-
_acquireConnection(record:
|
|
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,
|
|
120
|
+
* @return {{nodeTimings: Map<Node, Lantern.Simulation.NodeTiming>, completeNodeTimings: Map<Node, CompleteNodeTiming>}}
|
|
118
121
|
*/
|
|
119
122
|
_computeFinalNodeTimings(): {
|
|
120
|
-
nodeTimings: Map<Node,
|
|
123
|
+
nodeTimings: Map<Node, Lantern.Simulation.NodeTiming>;
|
|
121
124
|
completeNodeTimings: Map<Node, CompleteNodeTiming>;
|
|
122
125
|
};
|
|
123
126
|
/**
|
|
124
|
-
* @return {Required<
|
|
127
|
+
* @return {Required<Lantern.Simulation.Options>}
|
|
125
128
|
*/
|
|
126
|
-
getOptions(): Required<
|
|
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 {
|
|
141
|
+
* @return {Lantern.Simulation.Result<T>}
|
|
139
142
|
*/
|
|
140
143
|
simulate(graph: Node, options?: {
|
|
141
144
|
flexibleOrdering?: boolean;
|
|
142
145
|
label?: string;
|
|
143
|
-
} | undefined):
|
|
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
|
|
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
|
|
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 {
|
|
54
|
+
* @param {Lantern.Simulation.Options} [options]
|
|
52
55
|
*/
|
|
53
56
|
constructor(options) {
|
|
54
|
-
/** @type {Required<
|
|
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 {
|
|
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.
|
|
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 {
|
|
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.
|
|
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.
|
|
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.
|
|
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,
|
|
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 `
|
|
399
|
-
/** @type {Array<[Node,
|
|
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<
|
|
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 {
|
|
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.
|
|
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
|
+
}
|
|
@@ -3,15 +3,15 @@ declare namespace _default {
|
|
|
3
3
|
export { convertNodeTimingsToTrace };
|
|
4
4
|
}
|
|
5
5
|
export default _default;
|
|
6
|
-
export type Node = import('./
|
|
7
|
-
export type CompleteNodeTiming = import('./
|
|
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('./
|
|
14
|
-
/** @typedef {import('./
|
|
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}
|