lighthouse 11.6.0-dev.20240303 → 11.6.0-dev.20240305
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/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/prioritize-lcp-image.d.ts +1 -1
- package/core/computed/document-urls.js +1 -1
- package/core/computed/load-simulator.d.ts +4 -2
- package/core/computed/load-simulator.js +4 -2
- package/core/computed/main-resource.js +1 -1
- package/core/computed/metrics/lantern-first-contentful-paint.d.ts +6 -6
- package/core/computed/metrics/lantern-first-contentful-paint.js +4 -4
- package/core/computed/metrics/lantern-first-meaningful-paint.d.ts +2 -2
- package/core/computed/metrics/lantern-first-meaningful-paint.js +1 -1
- package/core/computed/metrics/lantern-interactive.d.ts +2 -6
- package/core/computed/metrics/lantern-interactive.js +2 -2
- package/core/computed/metrics/lantern-largest-contentful-paint.d.ts +2 -2
- package/core/computed/metrics/lantern-largest-contentful-paint.js +1 -1
- package/core/computed/metrics/lantern-max-potential-fid.d.ts +2 -2
- package/core/computed/metrics/lantern-max-potential-fid.js +2 -2
- package/core/computed/metrics/lantern-metric.d.ts +8 -7
- package/core/computed/metrics/lantern-metric.js +4 -4
- package/core/computed/metrics/lantern-speed-index.d.ts +2 -2
- package/core/computed/metrics/lantern-speed-index.js +2 -2
- package/core/computed/metrics/lantern-total-blocking-time.d.ts +2 -2
- package/core/computed/metrics/lantern-total-blocking-time.js +2 -2
- 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/lib/asset-saver.js +1 -1
- 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/{dependency-graph → lantern}/network-node.d.ts +17 -10
- package/core/lib/lantern/network-node.js +115 -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 +15 -14
- package/core/lib/{dependency-graph → lantern}/simulator/connection-pool.js +9 -7
- package/core/lib/{dependency-graph → lantern}/simulator/dns-cache.d.ts +11 -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 +22 -17
- package/core/lib/{dependency-graph → lantern}/simulator/simulator.d.ts +21 -15
- package/core/lib/{dependency-graph → lantern}/simulator/simulator.js +24 -15
- 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 +1 -1
- package/core/lib/network-request.d.ts +7 -0
- package/core/lib/network-request.js +13 -0
- package/package.json +1 -1
- package/shared/localization/locales/en-US.json +3 -0
- package/shared/localization/locales/en-XL.json +3 -0
- package/third-party/chromium-synchronization/installability-errors-test.js +1 -1
- package/tsconfig.json +6 -5
- package/types/artifacts.d.ts +1 -1
- package/types/gatherer.d.ts +8 -35
- package/types/internal/lantern.d.ts +124 -0
- 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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type NetworkRequest = import('../../../../types/internal/lantern.js').Lantern.NetworkRequest;
|
|
1
2
|
export type Summary = {
|
|
2
3
|
min: number;
|
|
3
4
|
max: number;
|
|
@@ -32,10 +33,10 @@ export class NetworkAnalyzer {
|
|
|
32
33
|
*/
|
|
33
34
|
static get SUMMARY(): string;
|
|
34
35
|
/**
|
|
35
|
-
* @param {
|
|
36
|
-
* @return {Map<string,
|
|
36
|
+
* @param {NetworkRequest[]} records
|
|
37
|
+
* @return {Map<string, NetworkRequest[]>}
|
|
37
38
|
*/
|
|
38
|
-
static groupByOrigin(records:
|
|
39
|
+
static groupByOrigin(records: NetworkRequest[]): Map<string, NetworkRequest[]>;
|
|
39
40
|
/**
|
|
40
41
|
* @param {number[]} values
|
|
41
42
|
* @return {Summary}
|
|
@@ -46,14 +47,14 @@ export class NetworkAnalyzer {
|
|
|
46
47
|
* @return {Map<string, Summary>}
|
|
47
48
|
*/
|
|
48
49
|
static summarize(values: Map<string, number[]>): Map<string, Summary>;
|
|
49
|
-
/** @typedef {{record:
|
|
50
|
+
/** @typedef {{record: NetworkRequest, timing: LH.Crdp.Network.ResourceTiming, connectionReused?: boolean}} RequestInfo */
|
|
50
51
|
/**
|
|
51
|
-
* @param {
|
|
52
|
+
* @param {NetworkRequest[]} records
|
|
52
53
|
* @param {(e: RequestInfo) => number | number[] | undefined} iteratee
|
|
53
54
|
* @return {Map<string, number[]>}
|
|
54
55
|
*/
|
|
55
|
-
static _estimateValueByOrigin(records:
|
|
56
|
-
record:
|
|
56
|
+
static _estimateValueByOrigin(records: NetworkRequest[], iteratee: (e: {
|
|
57
|
+
record: NetworkRequest;
|
|
57
58
|
timing: LH.Crdp.Network.ResourceTiming;
|
|
58
59
|
connectionReused?: boolean | undefined;
|
|
59
60
|
}) => number | number[] | undefined): Map<string, number[]>;
|
|
@@ -69,7 +70,7 @@ export class NetworkAnalyzer {
|
|
|
69
70
|
* @return {number[]|number|undefined}
|
|
70
71
|
*/
|
|
71
72
|
static _estimateRTTViaConnectionTiming(info: {
|
|
72
|
-
record:
|
|
73
|
+
record: NetworkRequest;
|
|
73
74
|
timing: LH.Crdp.Network.ResourceTiming;
|
|
74
75
|
connectionReused?: boolean | undefined;
|
|
75
76
|
}): number[] | number | undefined;
|
|
@@ -82,7 +83,7 @@ export class NetworkAnalyzer {
|
|
|
82
83
|
* @return {number|undefined}
|
|
83
84
|
*/
|
|
84
85
|
static _estimateRTTViaDownloadTiming(info: {
|
|
85
|
-
record:
|
|
86
|
+
record: NetworkRequest;
|
|
86
87
|
timing: LH.Crdp.Network.ResourceTiming;
|
|
87
88
|
connectionReused?: boolean | undefined;
|
|
88
89
|
}): number | undefined;
|
|
@@ -96,7 +97,7 @@ export class NetworkAnalyzer {
|
|
|
96
97
|
* @return {number|undefined}
|
|
97
98
|
*/
|
|
98
99
|
static _estimateRTTViaSendStartTiming(info: {
|
|
99
|
-
record:
|
|
100
|
+
record: NetworkRequest;
|
|
100
101
|
timing: LH.Crdp.Network.ResourceTiming;
|
|
101
102
|
connectionReused?: boolean | undefined;
|
|
102
103
|
}): number | undefined;
|
|
@@ -110,32 +111,32 @@ export class NetworkAnalyzer {
|
|
|
110
111
|
* @return {number|undefined}
|
|
111
112
|
*/
|
|
112
113
|
static _estimateRTTViaHeadersEndTiming(info: {
|
|
113
|
-
record:
|
|
114
|
+
record: NetworkRequest;
|
|
114
115
|
timing: LH.Crdp.Network.ResourceTiming;
|
|
115
116
|
connectionReused?: boolean | undefined;
|
|
116
117
|
}): number | undefined;
|
|
117
118
|
/**
|
|
118
119
|
* Given the RTT to each origin, estimates the observed server response times.
|
|
119
120
|
*
|
|
120
|
-
* @param {
|
|
121
|
+
* @param {NetworkRequest[]} records
|
|
121
122
|
* @param {Map<string, number>} rttByOrigin
|
|
122
123
|
* @return {Map<string, number[]>}
|
|
123
124
|
*/
|
|
124
|
-
static _estimateResponseTimeByOrigin(records:
|
|
125
|
+
static _estimateResponseTimeByOrigin(records: NetworkRequest[], rttByOrigin: Map<string, number>): Map<string, number[]>;
|
|
125
126
|
/**
|
|
126
|
-
* @param {
|
|
127
|
+
* @param {NetworkRequest[]} records
|
|
127
128
|
* @return {boolean}
|
|
128
129
|
*/
|
|
129
|
-
static canTrustConnectionInformation(records:
|
|
130
|
+
static canTrustConnectionInformation(records: NetworkRequest[]): boolean;
|
|
130
131
|
/**
|
|
131
132
|
* Returns a map of requestId -> connectionReused, estimating the information if the information
|
|
132
133
|
* available in the records themselves appears untrustworthy.
|
|
133
134
|
*
|
|
134
|
-
* @param {
|
|
135
|
+
* @param {NetworkRequest[]} records
|
|
135
136
|
* @param {{forceCoarseEstimates: boolean}} [options]
|
|
136
137
|
* @return {Map<string, boolean>}
|
|
137
138
|
*/
|
|
138
|
-
static estimateIfConnectionWasReused(records:
|
|
139
|
+
static estimateIfConnectionWasReused(records: NetworkRequest[], options?: {
|
|
139
140
|
forceCoarseEstimates: boolean;
|
|
140
141
|
} | undefined): Map<string, boolean>;
|
|
141
142
|
/**
|
|
@@ -143,20 +144,20 @@ export class NetworkAnalyzer {
|
|
|
143
144
|
* Attempts to use the most accurate information first and falls back to coarser estimates when it
|
|
144
145
|
* is unavailable.
|
|
145
146
|
*
|
|
146
|
-
* @param {
|
|
147
|
+
* @param {NetworkRequest[]} records
|
|
147
148
|
* @param {RTTEstimateOptions} [options]
|
|
148
149
|
* @return {Map<string, Summary>}
|
|
149
150
|
*/
|
|
150
|
-
static estimateRTTByOrigin(records:
|
|
151
|
+
static estimateRTTByOrigin(records: NetworkRequest[], options?: RTTEstimateOptions | undefined): Map<string, Summary>;
|
|
151
152
|
/**
|
|
152
153
|
* Estimates the server response time of each origin. RTT times can be passed in or will be
|
|
153
154
|
* estimated automatically if not provided.
|
|
154
155
|
*
|
|
155
|
-
* @param {
|
|
156
|
+
* @param {NetworkRequest[]} records
|
|
156
157
|
* @param {RTTEstimateOptions & {rttByOrigin?: Map<string, number>}} [options]
|
|
157
158
|
* @return {Map<string, Summary>}
|
|
158
159
|
*/
|
|
159
|
-
static estimateServerResponseTimeByOrigin(records:
|
|
160
|
+
static estimateServerResponseTimeByOrigin(records: NetworkRequest[], options?: (RTTEstimateOptions & {
|
|
160
161
|
rttByOrigin?: Map<string, number> | undefined;
|
|
161
162
|
}) | undefined): Map<string, Summary>;
|
|
162
163
|
/**
|
|
@@ -164,29 +165,32 @@ export class NetworkAnalyzer {
|
|
|
164
165
|
* Excludes data URI, failed or otherwise incomplete, and cached requests.
|
|
165
166
|
* Returns Infinity if there were no analyzable network records.
|
|
166
167
|
*
|
|
167
|
-
* @param {Array<
|
|
168
|
+
* @param {Array<NetworkRequest>} networkRecords
|
|
168
169
|
* @return {number}
|
|
169
170
|
*/
|
|
170
|
-
static estimateThroughput(networkRecords: Array<
|
|
171
|
+
static estimateThroughput(networkRecords: Array<NetworkRequest>): number;
|
|
171
172
|
/**
|
|
172
|
-
* @
|
|
173
|
+
* @template {NetworkRequest} T
|
|
174
|
+
* @param {Array<T>} records
|
|
173
175
|
* @param {string} resourceUrl
|
|
174
|
-
* @return {
|
|
176
|
+
* @return {T|undefined}
|
|
175
177
|
*/
|
|
176
|
-
static findResourceForUrl(
|
|
178
|
+
static findResourceForUrl<T extends import("../../../../types/internal/lantern.js").Lantern.NetworkRequest<any>>(records: T[], resourceUrl: string): T | undefined;
|
|
177
179
|
/**
|
|
178
|
-
* @
|
|
180
|
+
* @template {NetworkRequest} T
|
|
181
|
+
* @param {Array<T>} records
|
|
179
182
|
* @param {string} resourceUrl
|
|
180
|
-
* @return {
|
|
183
|
+
* @return {T|undefined}
|
|
181
184
|
*/
|
|
182
|
-
static findLastDocumentForUrl(
|
|
185
|
+
static findLastDocumentForUrl<T_1 extends import("../../../../types/internal/lantern.js").Lantern.NetworkRequest<any>>(records: T_1[], resourceUrl: string): T_1 | undefined;
|
|
183
186
|
/**
|
|
184
187
|
* Resolves redirect chain given a main document.
|
|
185
188
|
* See: {@link NetworkAnalyzer.findLastDocumentForUrl}) for how to retrieve main document.
|
|
186
189
|
*
|
|
187
|
-
* @
|
|
188
|
-
* @
|
|
190
|
+
* @template {NetworkRequest} T
|
|
191
|
+
* @param {T} request
|
|
192
|
+
* @return {T}
|
|
189
193
|
*/
|
|
190
|
-
static resolveRedirects(request:
|
|
194
|
+
static resolveRedirects<T_2 extends import("../../../../types/internal/lantern.js").Lantern.NetworkRequest<any>>(request: T_2): T_2;
|
|
191
195
|
}
|
|
192
196
|
//# sourceMappingURL=network-analyzer.d.ts.map
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
/** @typedef {import('../../../../types/internal/lantern.js').Lantern.NetworkRequest} NetworkRequest */
|
|
8
|
+
|
|
7
9
|
import UrlUtils from '../../url-utils.js';
|
|
8
10
|
|
|
9
11
|
const INITIAL_CWD = 14 * 1024;
|
|
@@ -31,8 +33,8 @@ class NetworkAnalyzer {
|
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
/**
|
|
34
|
-
* @param {
|
|
35
|
-
* @return {Map<string,
|
|
36
|
+
* @param {NetworkRequest[]} records
|
|
37
|
+
* @return {Map<string, NetworkRequest[]>}
|
|
36
38
|
*/
|
|
37
39
|
static groupByOrigin(records) {
|
|
38
40
|
const grouped = new Map();
|
|
@@ -87,10 +89,10 @@ class NetworkAnalyzer {
|
|
|
87
89
|
return summaryByKey;
|
|
88
90
|
}
|
|
89
91
|
|
|
90
|
-
/** @typedef {{record:
|
|
92
|
+
/** @typedef {{record: NetworkRequest, timing: LH.Crdp.Network.ResourceTiming, connectionReused?: boolean}} RequestInfo */
|
|
91
93
|
|
|
92
94
|
/**
|
|
93
|
-
* @param {
|
|
95
|
+
* @param {NetworkRequest[]} records
|
|
94
96
|
* @param {(e: RequestInfo) => number | number[] | undefined} iteratee
|
|
95
97
|
* @return {Map<string, number[]>}
|
|
96
98
|
*/
|
|
@@ -249,7 +251,7 @@ class NetworkAnalyzer {
|
|
|
249
251
|
/**
|
|
250
252
|
* Given the RTT to each origin, estimates the observed server response times.
|
|
251
253
|
*
|
|
252
|
-
* @param {
|
|
254
|
+
* @param {NetworkRequest[]} records
|
|
253
255
|
* @param {Map<string, number>} rttByOrigin
|
|
254
256
|
* @return {Map<string, number[]>}
|
|
255
257
|
*/
|
|
@@ -270,7 +272,7 @@ class NetworkAnalyzer {
|
|
|
270
272
|
}
|
|
271
273
|
|
|
272
274
|
/**
|
|
273
|
-
* @param {
|
|
275
|
+
* @param {NetworkRequest[]} records
|
|
274
276
|
* @return {boolean}
|
|
275
277
|
*/
|
|
276
278
|
static canTrustConnectionInformation(records) {
|
|
@@ -290,7 +292,7 @@ class NetworkAnalyzer {
|
|
|
290
292
|
* Returns a map of requestId -> connectionReused, estimating the information if the information
|
|
291
293
|
* available in the records themselves appears untrustworthy.
|
|
292
294
|
*
|
|
293
|
-
* @param {
|
|
295
|
+
* @param {NetworkRequest[]} records
|
|
294
296
|
* @param {{forceCoarseEstimates: boolean}} [options]
|
|
295
297
|
* @return {Map<string, boolean>}
|
|
296
298
|
*/
|
|
@@ -334,7 +336,7 @@ class NetworkAnalyzer {
|
|
|
334
336
|
* Attempts to use the most accurate information first and falls back to coarser estimates when it
|
|
335
337
|
* is unavailable.
|
|
336
338
|
*
|
|
337
|
-
* @param {
|
|
339
|
+
* @param {NetworkRequest[]} records
|
|
338
340
|
* @param {RTTEstimateOptions} [options]
|
|
339
341
|
* @return {Map<string, Summary>}
|
|
340
342
|
*/
|
|
@@ -415,7 +417,7 @@ class NetworkAnalyzer {
|
|
|
415
417
|
* Estimates the server response time of each origin. RTT times can be passed in or will be
|
|
416
418
|
* estimated automatically if not provided.
|
|
417
419
|
*
|
|
418
|
-
* @param {
|
|
420
|
+
* @param {NetworkRequest[]} records
|
|
419
421
|
* @param {RTTEstimateOptions & {rttByOrigin?: Map<string, number>}} [options]
|
|
420
422
|
* @return {Map<string, Summary>}
|
|
421
423
|
*/
|
|
@@ -441,7 +443,7 @@ class NetworkAnalyzer {
|
|
|
441
443
|
* Excludes data URI, failed or otherwise incomplete, and cached requests.
|
|
442
444
|
* Returns Infinity if there were no analyzable network records.
|
|
443
445
|
*
|
|
444
|
-
* @param {Array<
|
|
446
|
+
* @param {Array<NetworkRequest>} networkRecords
|
|
445
447
|
* @return {number}
|
|
446
448
|
*/
|
|
447
449
|
static estimateThroughput(networkRecords) {
|
|
@@ -494,9 +496,10 @@ class NetworkAnalyzer {
|
|
|
494
496
|
}
|
|
495
497
|
|
|
496
498
|
/**
|
|
497
|
-
* @
|
|
499
|
+
* @template {NetworkRequest} T
|
|
500
|
+
* @param {Array<T>} records
|
|
498
501
|
* @param {string} resourceUrl
|
|
499
|
-
* @return {
|
|
502
|
+
* @return {T|undefined}
|
|
500
503
|
*/
|
|
501
504
|
static findResourceForUrl(records, resourceUrl) {
|
|
502
505
|
// equalWithExcludedFragments is expensive, so check that the resourceUrl starts with the request url first
|
|
@@ -507,9 +510,10 @@ class NetworkAnalyzer {
|
|
|
507
510
|
}
|
|
508
511
|
|
|
509
512
|
/**
|
|
510
|
-
* @
|
|
513
|
+
* @template {NetworkRequest} T
|
|
514
|
+
* @param {Array<T>} records
|
|
511
515
|
* @param {string} resourceUrl
|
|
512
|
-
* @return {
|
|
516
|
+
* @return {T|undefined}
|
|
513
517
|
*/
|
|
514
518
|
static findLastDocumentForUrl(records, resourceUrl) {
|
|
515
519
|
// equalWithExcludedFragments is expensive, so check that the resourceUrl starts with the request url first
|
|
@@ -526,11 +530,12 @@ class NetworkAnalyzer {
|
|
|
526
530
|
* Resolves redirect chain given a main document.
|
|
527
531
|
* See: {@link NetworkAnalyzer.findLastDocumentForUrl}) for how to retrieve main document.
|
|
528
532
|
*
|
|
529
|
-
* @
|
|
530
|
-
* @
|
|
533
|
+
* @template {NetworkRequest} T
|
|
534
|
+
* @param {T} request
|
|
535
|
+
* @return {T}
|
|
531
536
|
*/
|
|
532
537
|
static resolveRedirects(request) {
|
|
533
|
-
while (request.redirectDestination) request = request.redirectDestination;
|
|
538
|
+
while (request.redirectDestination) request = /** @type {T} */(request.redirectDestination);
|
|
534
539
|
return request;
|
|
535
540
|
}
|
|
536
541
|
}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
+
export type NetworkRequest = import('../../../../types/internal/lantern.js').Lantern.NetworkRequest;
|
|
2
|
+
export type SimulationOptions = import('../../../../types/internal/lantern.js').Lantern.Simulation.Options;
|
|
3
|
+
export type SimulationNodeTiming = import('../../../../types/internal/lantern.js').Lantern.Simulation.NodeTiming;
|
|
4
|
+
export type SimulationResult<T> = import('../../../../types/internal/lantern.js').Lantern.Simulation.Result<T>;
|
|
1
5
|
export type Node = import('../base-node.js').Node;
|
|
2
6
|
export type NetworkNode = import('../network-node.js').NetworkNode;
|
|
3
7
|
export type CpuNode = import('../cpu-node.js').CPUNode;
|
|
4
8
|
export type CompleteNodeTiming = import('./simulator-timing-map.js').CpuNodeTimingComplete | import('./simulator-timing-map.js').NetworkNodeTimingComplete;
|
|
5
9
|
export type ConnectionTiming = import('./simulator-timing-map.js').ConnectionTiming;
|
|
6
|
-
|
|
10
|
+
/**
|
|
11
|
+
* @template [T=any]
|
|
12
|
+
*/
|
|
13
|
+
export class Simulator<T = any> {
|
|
7
14
|
/** @return {Map<string, Map<Node, CompleteNodeTiming>>} */
|
|
8
|
-
static get ALL_NODE_TIMINGS(): Map<string, Map<
|
|
15
|
+
static get ALL_NODE_TIMINGS(): Map<string, Map<Node, CompleteNodeTiming>>;
|
|
9
16
|
/**
|
|
10
17
|
* We attempt to start nodes by their observed start time using the record priority as a tie breaker.
|
|
11
18
|
* When simulating, just because a low priority image started 5ms before a high priority image doesn't mean
|
|
@@ -14,11 +21,11 @@ export class Simulator {
|
|
|
14
21
|
*/
|
|
15
22
|
static _computeNodeStartPosition(node: Node): number;
|
|
16
23
|
/**
|
|
17
|
-
* @param {
|
|
24
|
+
* @param {SimulationOptions} [options]
|
|
18
25
|
*/
|
|
19
|
-
constructor(options?:
|
|
20
|
-
/** @type {Required<
|
|
21
|
-
_options: Required<
|
|
26
|
+
constructor(options?: import("../../../../types/internal/lantern.js").Lantern.Simulation.Options | undefined);
|
|
27
|
+
/** @type {Required<SimulationOptions>} */
|
|
28
|
+
_options: Required<SimulationOptions>;
|
|
22
29
|
_rtt: number;
|
|
23
30
|
_throughput: number;
|
|
24
31
|
_maximumConcurrentRequests: number;
|
|
@@ -67,10 +74,10 @@ export class Simulator {
|
|
|
67
74
|
*/
|
|
68
75
|
_markNodeAsComplete(node: Node, endTime: number, connectionTiming?: import("./simulator-timing-map.js").ConnectionTiming | undefined): void;
|
|
69
76
|
/**
|
|
70
|
-
* @param {
|
|
77
|
+
* @param {NetworkRequest} record
|
|
71
78
|
* @return {?TcpConnection}
|
|
72
79
|
*/
|
|
73
|
-
_acquireConnection(record:
|
|
80
|
+
_acquireConnection(record: NetworkRequest): TcpConnection | null;
|
|
74
81
|
/**
|
|
75
82
|
* @return {Node[]}
|
|
76
83
|
*/
|
|
@@ -114,16 +121,16 @@ export class Simulator {
|
|
|
114
121
|
*/
|
|
115
122
|
_updateProgressMadeInTimePeriod(node: Node, timePeriodLength: number, totalElapsedTime: number): number | void;
|
|
116
123
|
/**
|
|
117
|
-
* @return {{nodeTimings: Map<Node,
|
|
124
|
+
* @return {{nodeTimings: Map<Node, SimulationNodeTiming>, completeNodeTimings: Map<Node, CompleteNodeTiming>}}
|
|
118
125
|
*/
|
|
119
126
|
_computeFinalNodeTimings(): {
|
|
120
|
-
nodeTimings: Map<Node,
|
|
127
|
+
nodeTimings: Map<Node, SimulationNodeTiming>;
|
|
121
128
|
completeNodeTimings: Map<Node, CompleteNodeTiming>;
|
|
122
129
|
};
|
|
123
130
|
/**
|
|
124
|
-
* @return {Required<
|
|
131
|
+
* @return {Required<SimulationOptions>}
|
|
125
132
|
*/
|
|
126
|
-
getOptions(): Required<
|
|
133
|
+
getOptions(): Required<SimulationOptions>;
|
|
127
134
|
/**
|
|
128
135
|
* Estimates the time taken to process all of the graph's nodes, returns the overall time along with
|
|
129
136
|
* each node annotated by start/end times.
|
|
@@ -135,18 +142,17 @@ export class Simulator {
|
|
|
135
142
|
*
|
|
136
143
|
* @param {Node} graph
|
|
137
144
|
* @param {{flexibleOrdering?: boolean, label?: string}=} options
|
|
138
|
-
* @return {
|
|
145
|
+
* @return {SimulationResult<T>}
|
|
139
146
|
*/
|
|
140
147
|
simulate(graph: Node, options?: {
|
|
141
148
|
flexibleOrdering?: boolean;
|
|
142
149
|
label?: string;
|
|
143
|
-
} | undefined):
|
|
150
|
+
} | undefined): SimulationResult<T>;
|
|
144
151
|
/**
|
|
145
152
|
* @param {number} wastedBytes
|
|
146
153
|
*/
|
|
147
154
|
computeWastedMsFromWastedBytes(wastedBytes: number): number;
|
|
148
155
|
}
|
|
149
|
-
import * as LH from '../../../../types/lh.js';
|
|
150
156
|
import { SimulatorTimingMap } from './simulator-timing-map.js';
|
|
151
157
|
import { DNSCache } from './dns-cache.js';
|
|
152
158
|
import { ConnectionPool } from './connection-pool.js';
|
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
// This could be replaced by jsdoc namespace import, when ready.
|
|
8
|
+
// https://github.com/microsoft/TypeScript/issues/41825
|
|
9
|
+
/** @typedef {import('../../../../types/internal/lantern.js').Lantern.NetworkRequest} NetworkRequest */
|
|
10
|
+
/** @typedef {import('../../../../types/internal/lantern.js').Lantern.Simulation.Options} SimulationOptions */
|
|
11
|
+
/** @typedef {import('../../../../types/internal/lantern.js').Lantern.Simulation.NodeTiming} SimulationNodeTiming */
|
|
12
|
+
/** @template T @typedef {import('../../../../types/internal/lantern.js').Lantern.Simulation.Result<T>} SimulationResult */
|
|
13
|
+
|
|
8
14
|
import {BaseNode} from '../base-node.js';
|
|
9
15
|
import {TcpConnection} from './tcp-connection.js';
|
|
10
16
|
import {ConnectionPool} from './connection-pool.js';
|
|
@@ -46,12 +52,15 @@ const PriorityStartTimePenalty = {
|
|
|
46
52
|
/** @type {Map<string, Map<Node, CompleteNodeTiming>>} */
|
|
47
53
|
const ALL_SIMULATION_NODE_TIMINGS = new Map();
|
|
48
54
|
|
|
55
|
+
/**
|
|
56
|
+
* @template [T=any]
|
|
57
|
+
*/
|
|
49
58
|
class Simulator {
|
|
50
59
|
/**
|
|
51
|
-
* @param {
|
|
60
|
+
* @param {SimulationOptions} [options]
|
|
52
61
|
*/
|
|
53
62
|
constructor(options) {
|
|
54
|
-
/** @type {Required<
|
|
63
|
+
/** @type {Required<SimulationOptions>} */
|
|
55
64
|
this._options = Object.assign(
|
|
56
65
|
{
|
|
57
66
|
rtt: mobileSlow4G.rttMs,
|
|
@@ -101,11 +110,11 @@ class Simulator {
|
|
|
101
110
|
* @param {Node} graph
|
|
102
111
|
*/
|
|
103
112
|
_initializeConnectionPool(graph) {
|
|
104
|
-
/** @type {
|
|
113
|
+
/** @type {NetworkRequest[]} */
|
|
105
114
|
const records = [];
|
|
106
115
|
graph.getRootNode().traverse(node => {
|
|
107
116
|
if (node.type === BaseNode.TYPES.NETWORK) {
|
|
108
|
-
records.push(node.
|
|
117
|
+
records.push(node.request);
|
|
109
118
|
}
|
|
110
119
|
});
|
|
111
120
|
|
|
@@ -190,7 +199,7 @@ class Simulator {
|
|
|
190
199
|
}
|
|
191
200
|
|
|
192
201
|
/**
|
|
193
|
-
* @param {
|
|
202
|
+
* @param {NetworkRequest} record
|
|
194
203
|
* @return {?TcpConnection}
|
|
195
204
|
*/
|
|
196
205
|
_acquireConnection(record) {
|
|
@@ -228,7 +237,7 @@ class Simulator {
|
|
|
228
237
|
// Start a network request if we're not at max requests and a connection is available
|
|
229
238
|
const numberOfActiveRequests = this._numberInProgress(node.type);
|
|
230
239
|
if (numberOfActiveRequests >= this._maximumConcurrentRequests) return;
|
|
231
|
-
const connection = this._acquireConnection(node.
|
|
240
|
+
const connection = this._acquireConnection(node.request);
|
|
232
241
|
if (!connection) return;
|
|
233
242
|
}
|
|
234
243
|
|
|
@@ -286,7 +295,7 @@ class Simulator {
|
|
|
286
295
|
* @return {number}
|
|
287
296
|
*/
|
|
288
297
|
_estimateNetworkTimeRemaining(networkNode) {
|
|
289
|
-
const record = networkNode.
|
|
298
|
+
const record = networkNode.request;
|
|
290
299
|
const timingData = this._nodeTimings.getNetworkStarted(networkNode);
|
|
291
300
|
|
|
292
301
|
let timeElapsed = 0;
|
|
@@ -354,7 +363,7 @@ class Simulator {
|
|
|
354
363
|
if (node.type !== BaseNode.TYPES.NETWORK) throw new Error('Unsupported');
|
|
355
364
|
if (!('bytesDownloaded' in timingData)) throw new Error('Invalid timing data');
|
|
356
365
|
|
|
357
|
-
const record = node.
|
|
366
|
+
const record = node.request;
|
|
358
367
|
const connection = this._connectionPool.acquireActiveConnectionFromRecord(record);
|
|
359
368
|
const dnsResolutionTime = this._dns.getTimeUntilResolution(record, {
|
|
360
369
|
requestedAt: timingData.startTime,
|
|
@@ -384,7 +393,7 @@ class Simulator {
|
|
|
384
393
|
}
|
|
385
394
|
|
|
386
395
|
/**
|
|
387
|
-
* @return {{nodeTimings: Map<Node,
|
|
396
|
+
* @return {{nodeTimings: Map<Node, SimulationNodeTiming>, completeNodeTimings: Map<Node, CompleteNodeTiming>}}
|
|
388
397
|
*/
|
|
389
398
|
_computeFinalNodeTimings() {
|
|
390
399
|
/** @type {Array<[Node, CompleteNodeTiming]>} */
|
|
@@ -395,8 +404,8 @@ class Simulator {
|
|
|
395
404
|
// Most consumers will want the entries sorted by startTime, so insert them in that order
|
|
396
405
|
completeNodeTimingEntries.sort((a, b) => a[1].startTime - b[1].startTime);
|
|
397
406
|
|
|
398
|
-
// Trimmed version of type `
|
|
399
|
-
/** @type {Array<[Node,
|
|
407
|
+
// Trimmed version of type `SimulationNodeTiming`.
|
|
408
|
+
/** @type {Array<[Node, SimulationNodeTiming]>} */
|
|
400
409
|
const nodeTimingEntries = completeNodeTimingEntries.map(([node, timing]) => {
|
|
401
410
|
return [node, {
|
|
402
411
|
startTime: timing.startTime,
|
|
@@ -412,7 +421,7 @@ class Simulator {
|
|
|
412
421
|
}
|
|
413
422
|
|
|
414
423
|
/**
|
|
415
|
-
* @return {Required<
|
|
424
|
+
* @return {Required<SimulationOptions>}
|
|
416
425
|
*/
|
|
417
426
|
getOptions() {
|
|
418
427
|
return this._options;
|
|
@@ -429,7 +438,7 @@ class Simulator {
|
|
|
429
438
|
*
|
|
430
439
|
* @param {Node} graph
|
|
431
440
|
* @param {{flexibleOrdering?: boolean, label?: string}=} options
|
|
432
|
-
* @return {
|
|
441
|
+
* @return {SimulationResult<T>}
|
|
433
442
|
*/
|
|
434
443
|
simulate(graph, options) {
|
|
435
444
|
if (BaseNode.hasCycle(graph)) {
|
|
@@ -535,7 +544,7 @@ class Simulator {
|
|
|
535
544
|
*/
|
|
536
545
|
static _computeNodeStartPosition(node) {
|
|
537
546
|
if (node.type === 'cpu') return node.startTime;
|
|
538
|
-
return node.startTime + (PriorityStartTimePenalty[node.
|
|
547
|
+
return node.startTime + (PriorityStartTimePenalty[node.request.priority] * 1000 * 1000 || 0);
|
|
539
548
|
}
|
|
540
549
|
}
|
|
541
550
|
|
|
@@ -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}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
/** @typedef {import('./
|
|
8
|
-
/** @typedef {import('./
|
|
7
|
+
/** @typedef {import('./lantern/base-node.js').Node<LH.Artifacts.NetworkRequest>} Node */
|
|
8
|
+
/** @typedef {import('./lantern/simulator/simulator.js').CompleteNodeTiming} CompleteNodeTiming */
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @param {Map<Node, CompleteNodeTiming>} nodeTimings
|
|
@@ -32,9 +32,11 @@ function convertNodeTimingsToTrace(nodeTimings) {
|
|
|
32
32
|
// Represent all CPU work that was bundled in a task as an EvaluateScript event
|
|
33
33
|
traceEvents.push(...createFakeTaskEvents(node, timing));
|
|
34
34
|
} else {
|
|
35
|
+
/** @type {LH.Artifacts.NetworkRequest} */
|
|
36
|
+
const record = node.record;
|
|
35
37
|
// Ignore data URIs as they don't really add much value
|
|
36
|
-
if (/^data/.test(
|
|
37
|
-
traceEvents.push(...createFakeNetworkEvents(requestId,
|
|
38
|
+
if (/^data/.test(record.url)) continue;
|
|
39
|
+
traceEvents.push(...createFakeNetworkEvents(requestId, record, timing));
|
|
38
40
|
requestId++;
|
|
39
41
|
}
|
|
40
42
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import {LighthouseError} from './lh-error.js';
|
|
8
|
-
import {NetworkAnalyzer} from './
|
|
8
|
+
import {NetworkAnalyzer} from './lantern/simulator/network-analyzer.js';
|
|
9
9
|
import {NetworkRequest} from './network-request.js';
|
|
10
10
|
import * as i18n from '../lib/i18n/i18n.js';
|
|
11
11
|
|
|
@@ -10,7 +10,7 @@ import log from 'lighthouse-logger';
|
|
|
10
10
|
|
|
11
11
|
import * as LH from '../../types/lh.js';
|
|
12
12
|
import {NetworkRequest} from './network-request.js';
|
|
13
|
-
import {PageDependencyGraph} from '../
|
|
13
|
+
import {PageDependencyGraph} from '../lib/lantern/page-dependency-graph.js';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* @typedef {{
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type LanternNetworkRequest<T> = import('../../types/internal/lantern.js').Lantern.NetworkRequest<T>;
|
|
1
2
|
export type HeaderEntry = {
|
|
2
3
|
name: string;
|
|
3
4
|
value: string;
|
|
@@ -47,6 +48,11 @@ export class NetworkRequest {
|
|
|
47
48
|
*/
|
|
48
49
|
static _headersDictToHeadersArray(headersDict: LH.Crdp.Network.Headers): Array<HeaderEntry>;
|
|
49
50
|
static get TYPES(): LH.Util.SelfMap<LH.Crdp.Network.ResourceType>;
|
|
51
|
+
/**
|
|
52
|
+
* @param {NetworkRequest} record
|
|
53
|
+
* @return {LanternNetworkRequest<NetworkRequest>}
|
|
54
|
+
*/
|
|
55
|
+
static asLanternNetworkRequest(record: NetworkRequest): LanternNetworkRequest<NetworkRequest>;
|
|
50
56
|
/**
|
|
51
57
|
* @param {NetworkRequest} record
|
|
52
58
|
* @return {boolean}
|
|
@@ -253,6 +259,7 @@ export namespace NetworkRequest {
|
|
|
253
259
|
export { HEADER_PROTOCOL_IS_H2 };
|
|
254
260
|
}
|
|
255
261
|
import * as LH from '../../types/lh.js';
|
|
262
|
+
/** @template T @typedef {import('../../types/internal/lantern.js').Lantern.NetworkRequest<T>} LanternNetworkRequest */
|
|
256
263
|
declare const HEADER_TCP: "X-TCPMs";
|
|
257
264
|
declare const HEADER_SSL: "X-SSLMs";
|
|
258
265
|
declare const HEADER_REQ: "X-RequestMs";
|
|
@@ -55,6 +55,8 @@
|
|
|
55
55
|
import * as LH from '../../types/lh.js';
|
|
56
56
|
import UrlUtils from './url-utils.js';
|
|
57
57
|
|
|
58
|
+
/** @template T @typedef {import('../../types/internal/lantern.js').Lantern.NetworkRequest<T>} LanternNetworkRequest */
|
|
59
|
+
|
|
58
60
|
// Lightrider X-Header names for timing information.
|
|
59
61
|
// See: _updateTransferSizeForLightrider and _updateTimingsForLightrider.
|
|
60
62
|
const HEADER_TCP = 'X-TCPMs'; // Note: this should have been called something like ConnectMs, as it includes SSL.
|
|
@@ -568,6 +570,17 @@ class NetworkRequest {
|
|
|
568
570
|
return RESOURCE_TYPES;
|
|
569
571
|
}
|
|
570
572
|
|
|
573
|
+
/**
|
|
574
|
+
* @param {NetworkRequest} record
|
|
575
|
+
* @return {LanternNetworkRequest<NetworkRequest>}
|
|
576
|
+
*/
|
|
577
|
+
static asLanternNetworkRequest(record) {
|
|
578
|
+
return {
|
|
579
|
+
...record,
|
|
580
|
+
record,
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
|
|
571
584
|
/**
|
|
572
585
|
* @param {NetworkRequest} record
|
|
573
586
|
* @return {boolean}
|
package/package.json
CHANGED
|
@@ -1046,6 +1046,9 @@
|
|
|
1046
1046
|
"core/audits/installable-manifest.js | manifest-missing-suitable-icon": {
|
|
1047
1047
|
"message": "Manifest does not contain a suitable icon - PNG, SVG or WebP format of at least {value0} px is required, the sizes attribute must be set, and the purpose attribute, if set, must include \"any\"."
|
|
1048
1048
|
},
|
|
1049
|
+
"core/audits/installable-manifest.js | manifest-parsing-or-network-error": {
|
|
1050
|
+
"message": "Manifest could not be fetched, is empty, or could not be parsed"
|
|
1051
|
+
},
|
|
1049
1052
|
"core/audits/installable-manifest.js | no-acceptable-icon": {
|
|
1050
1053
|
"message": "No supplied icon is at least {value0} px square in PNG, SVG or WebP format, with the purpose attribute unset or set to \"any\""
|
|
1051
1054
|
},
|