lighthouse 12.0.0 → 12.1.0-dev.20240619
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/run.js +5 -38
- package/cli/test/smokehouse/lighthouse-runners/bundle.js +1 -1
- package/cli/test/smokehouse/smokehouse.js +11 -1
- package/core/audits/accessibility/aria-allowed-role.js +7 -9
- package/core/audits/byte-efficiency/byte-efficiency-audit.d.ts +2 -2
- package/core/audits/byte-efficiency/byte-efficiency-audit.js +3 -3
- package/core/audits/byte-efficiency/offscreen-images.js +1 -1
- package/core/audits/byte-efficiency/render-blocking-resources.d.ts +3 -3
- package/core/audits/byte-efficiency/render-blocking-resources.js +10 -10
- package/core/audits/dobetterweb/uses-http2.d.ts +2 -2
- package/core/audits/dobetterweb/uses-http2.js +5 -5
- package/core/audits/long-tasks.d.ts +7 -6
- package/core/audits/long-tasks.js +5 -4
- package/core/audits/metrics/first-meaningful-paint.d.ts +1 -17
- package/core/audits/metrics/first-meaningful-paint.js +5 -47
- package/core/audits/metrics/interactive.d.ts +1 -1
- package/core/audits/metrics/interactive.js +1 -1
- package/core/audits/predictive-perf.js +0 -6
- package/core/audits/prioritize-lcp-image.d.ts +1 -1
- package/core/audits/prioritize-lcp-image.js +2 -2
- package/core/audits/redirects.js +2 -3
- package/core/audits/third-party-facades.js +1 -1
- package/core/audits/third-party-summary.js +1 -1
- package/core/audits/uses-rel-preconnect.js +2 -2
- package/core/audits/uses-rel-preload.js +9 -9
- package/core/computed/critical-request-chains.js +3 -3
- package/core/computed/document-urls.js +3 -2
- package/core/computed/load-simulator.d.ts +4 -4
- package/core/computed/load-simulator.js +3 -54
- package/core/computed/main-resource.js +3 -2
- package/core/computed/metrics/interactive.d.ts +6 -0
- package/core/computed/metrics/interactive.js +2 -2
- package/core/computed/metrics/lantern-first-contentful-paint.d.ts +4 -4
- package/core/computed/metrics/lantern-first-contentful-paint.js +3 -3
- package/core/computed/metrics/lantern-interactive.d.ts +4 -4
- package/core/computed/metrics/lantern-interactive.js +6 -6
- package/core/computed/metrics/lantern-largest-contentful-paint.d.ts +4 -4
- package/core/computed/metrics/lantern-largest-contentful-paint.js +3 -3
- package/core/computed/metrics/lantern-max-potential-fid.d.ts +4 -4
- package/core/computed/metrics/lantern-max-potential-fid.js +3 -3
- package/core/computed/metrics/lantern-metric.d.ts +21 -2
- package/core/computed/metrics/lantern-metric.js +39 -4
- package/core/computed/metrics/lantern-speed-index.d.ts +4 -4
- package/core/computed/metrics/lantern-speed-index.js +4 -4
- package/core/computed/metrics/lantern-total-blocking-time.d.ts +4 -4
- package/core/computed/metrics/lantern-total-blocking-time.js +3 -3
- package/core/computed/metrics/timing-summary.js +0 -6
- package/core/computed/metrics/total-blocking-time.js +3 -1
- package/core/computed/navigation-insights.d.ts +2 -20
- package/core/computed/network-analysis.d.ts +0 -5
- package/core/computed/network-analysis.js +2 -42
- package/core/computed/page-dependency-graph.d.ts +5 -3
- package/core/computed/page-dependency-graph.js +17 -7
- package/core/computed/processed-navigation.d.ts +1 -1
- package/core/computed/tbt-impact-tasks.js +4 -2
- package/core/computed/trace-engine-result.d.ts +0 -11
- package/core/computed/trace-engine-result.js +5 -19
- package/core/config/constants.d.ts +28 -53
- package/core/config/constants.js +2 -43
- package/core/gather/driver/navigation.js +1 -1
- package/core/gather/driver/network-monitor.d.ts +2 -1
- package/core/gather/driver/network-monitor.js +4 -4
- package/core/gather/driver/target-manager.d.ts +1 -1
- package/core/gather/driver.d.ts +0 -12
- package/core/gather/driver.js +1 -26
- package/core/gather/gatherers/inspector-issues.js +1 -0
- package/core/gather/gatherers/root-causes.js +0 -1
- package/core/gather/session.d.ts +5 -3
- package/core/gather/session.js +22 -1
- package/core/lib/asset-saver.d.ts +13 -9
- package/core/lib/asset-saver.js +77 -30
- package/core/lib/bf-cache-strings.js +2 -2
- package/core/lib/lantern/{base-node.d.ts → BaseNode.d.ts} +7 -9
- package/core/lib/lantern/{base-node.js → BaseNode.js} +6 -6
- package/core/lib/lantern/BaseNode.test.js +385 -0
- package/core/lib/lantern/CpuNode.d.ts +43 -0
- package/core/lib/lantern/{cpu-node.js → CpuNode.js} +8 -9
- package/core/lib/lantern/{lantern-error.d.ts → LanternError.d.ts} +1 -1
- package/core/lib/lantern/{metric.d.ts → Metric.d.ts} +23 -25
- package/core/lib/lantern/{metric.js → Metric.js} +14 -16
- package/core/lib/lantern/{network-node.d.ts → NetworkNode.d.ts} +6 -7
- package/core/lib/lantern/{network-node.js → NetworkNode.js} +7 -9
- package/core/lib/lantern/PageDependencyGraph.d.ts +82 -0
- package/core/lib/lantern/{page-dependency-graph.js → PageDependencyGraph.js} +185 -50
- package/core/lib/lantern/PageDependencyGraph.test.js +654 -0
- package/core/{computed/metrics/tbt-utils.d.ts → lib/lantern/TBTUtils.d.ts} +1 -1
- package/core/lib/lantern/TBTUtils.test.d.ts +2 -0
- package/core/lib/lantern/TBTUtils.test.js +130 -0
- package/core/lib/lantern/TraceEngineComputationData.d.ts +25 -0
- package/core/lib/lantern/TraceEngineComputationData.js +466 -0
- package/core/lib/lantern/lantern.d.ts +19 -7
- package/core/lib/lantern/lantern.js +21 -1
- package/core/lib/lantern/metrics/{first-contentful-paint.d.ts → FirstContentfulPaint.d.ts} +11 -11
- package/core/lib/lantern/metrics/{first-contentful-paint.js → FirstContentfulPaint.js} +11 -13
- package/core/lib/lantern/metrics/FirstContentfulPaint.test.js +54 -0
- package/core/lib/lantern/metrics/Interactive.d.ts +20 -0
- package/core/lib/lantern/metrics/{interactive.js → Interactive.js} +23 -26
- package/core/lib/lantern/metrics/Interactive.test.js +56 -0
- package/core/lib/lantern/metrics/LargestContentfulPaint.d.ts +19 -0
- package/core/lib/lantern/metrics/{largest-contentful-paint.js → LargestContentfulPaint.js} +16 -19
- package/core/lib/lantern/metrics/LargestContentfulPaint.test.js +42 -0
- package/core/lib/lantern/metrics/MaxPotentialFID.d.ts +24 -0
- package/core/lib/lantern/metrics/{max-potential-fid.js → MaxPotentialFID.js} +12 -13
- package/core/lib/lantern/metrics/MetricTestUtils.d.ts +19 -0
- package/core/lib/lantern/metrics/MetricTestUtils.js +48 -0
- package/core/lib/lantern/metrics/{speed-index.d.ts → SpeedIndex.d.ts} +7 -13
- package/core/lib/lantern/metrics/{speed-index.js → SpeedIndex.js} +14 -16
- package/core/lib/lantern/metrics/SpeedIndex.test.js +83 -0
- package/core/lib/lantern/metrics/TotalBlockingTime.d.ts +25 -0
- package/core/lib/lantern/metrics/{total-blocking-time.js → TotalBlockingTime.js} +13 -16
- package/core/lib/lantern/metrics/__snapshots__/FirstContentfulPaint.test.js.snap +11 -0
- package/core/lib/lantern/metrics/__snapshots__/Interactive.test.js.snap +17 -0
- package/core/lib/lantern/metrics/metrics.d.ts +9 -0
- package/core/lib/lantern/metrics/metrics.js +16 -0
- package/core/lib/lantern/{simulator/connection-pool.d.ts → simulation/ConnectionPool.d.ts} +15 -15
- package/core/lib/lantern/{simulator/connection-pool.js → simulation/ConnectionPool.js} +25 -25
- package/core/lib/lantern/simulation/ConnectionPool.test.js +195 -0
- package/core/lib/lantern/simulation/Constants.d.ts +52 -0
- package/core/lib/lantern/simulation/Constants.js +48 -0
- package/core/lib/lantern/{simulator/dns-cache.d.ts → simulation/DNSCache.d.ts} +3 -3
- package/core/lib/lantern/{simulator/dns-cache.js → simulation/DNSCache.js} +2 -2
- package/core/lib/lantern/simulation/DNSCache.test.js +72 -0
- package/core/lib/lantern/{simulator/network-analyzer.d.ts → simulation/NetworkAnalyzer.d.ts} +34 -21
- package/core/lib/lantern/{simulator/network-analyzer.js → simulation/NetworkAnalyzer.js} +106 -57
- package/core/lib/lantern/simulation/NetworkAnalyzer.test.js +475 -0
- package/core/lib/lantern/{simulator/simulator-timing-map.d.ts → simulation/SimulationTimingMap.d.ts} +7 -7
- package/core/lib/lantern/{simulator/simulator-timing-map.js → simulation/SimulationTimingMap.js} +5 -6
- package/core/lib/lantern/{simulator/simulator.d.ts → simulation/Simulator.d.ts} +21 -19
- package/core/lib/lantern/{simulator/simulator.js → simulation/Simulator.js} +100 -45
- package/core/lib/lantern/simulation/Simulator.test.js +434 -0
- package/core/lib/lantern/simulation/TCPConnection.test.d.ts +2 -0
- package/core/lib/lantern/simulation/TCPConnection.test.js +374 -0
- package/core/lib/lantern/{simulator/tcp-connection.d.ts → simulation/TcpConnection.d.ts} +2 -2
- package/core/lib/lantern/{simulator/tcp-connection.js → simulation/TcpConnection.js} +1 -1
- package/core/lib/lantern/simulation/simulation.d.ts +21 -0
- package/core/lib/lantern/simulation/simulation.js +28 -0
- package/core/lib/lantern/types/lantern.d.ts +145 -20
- package/core/lib/lantern-trace-saver.d.ts +4 -4
- package/core/lib/lantern-trace-saver.js +4 -4
- package/core/lib/navigation-error.js +3 -3
- package/core/lib/network-recorder.js +2 -2
- package/core/lib/network-request.d.ts +29 -3
- package/core/lib/network-request.js +20 -13
- package/core/lib/tracehouse/trace-processor.d.ts +0 -2
- package/core/lib/tracehouse/trace-processor.js +1 -31
- package/core/lib/traces/metric-trace-events.js +0 -5
- package/dist/report/bundle.esm.js +1 -1
- package/dist/report/flow.js +1 -1
- package/dist/report/standalone.js +1 -1
- package/package.json +14 -13
- package/report/renderer/performance-category-renderer.js +1 -1
- package/shared/localization/locales/ar-XB.json +43 -4
- package/shared/localization/locales/ar.json +43 -4
- package/shared/localization/locales/bg.json +43 -4
- package/shared/localization/locales/ca.json +44 -5
- package/shared/localization/locales/cs.json +43 -4
- package/shared/localization/locales/da.json +43 -4
- package/shared/localization/locales/de.json +43 -4
- package/shared/localization/locales/el.json +43 -4
- package/shared/localization/locales/en-GB.json +42 -3
- package/shared/localization/locales/en-US.json +4 -4
- package/shared/localization/locales/en-XA.json +43 -4
- package/shared/localization/locales/en-XL.json +4 -4
- package/shared/localization/locales/es-419.json +43 -4
- package/shared/localization/locales/es.json +42 -3
- package/shared/localization/locales/fi.json +43 -4
- package/shared/localization/locales/fil.json +42 -3
- package/shared/localization/locales/fr.json +42 -3
- package/shared/localization/locales/he.json +48 -9
- package/shared/localization/locales/hi.json +43 -4
- package/shared/localization/locales/hr.json +43 -4
- package/shared/localization/locales/hu.json +42 -3
- package/shared/localization/locales/id.json +42 -3
- package/shared/localization/locales/it.json +43 -4
- package/shared/localization/locales/ja.json +42 -3
- package/shared/localization/locales/ko.json +43 -4
- package/shared/localization/locales/lt.json +42 -3
- package/shared/localization/locales/lv.json +43 -4
- package/shared/localization/locales/nl.json +44 -5
- package/shared/localization/locales/no.json +42 -3
- package/shared/localization/locales/pl.json +43 -4
- package/shared/localization/locales/pt-PT.json +43 -4
- package/shared/localization/locales/pt.json +43 -4
- package/shared/localization/locales/ro.json +43 -4
- package/shared/localization/locales/ru.json +43 -4
- package/shared/localization/locales/sk.json +43 -4
- package/shared/localization/locales/sl.json +42 -3
- package/shared/localization/locales/sr-Latn.json +43 -4
- package/shared/localization/locales/sr.json +43 -4
- package/shared/localization/locales/sv.json +42 -3
- package/shared/localization/locales/ta.json +42 -3
- package/shared/localization/locales/te.json +43 -4
- package/shared/localization/locales/th.json +44 -5
- package/shared/localization/locales/tr.json +43 -4
- package/shared/localization/locales/uk.json +43 -4
- package/shared/localization/locales/vi.json +43 -4
- package/shared/localization/locales/zh-HK.json +43 -4
- package/shared/localization/locales/zh-TW.json +43 -4
- package/shared/localization/locales/zh.json +43 -4
- package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +1 -0
- package/tsconfig-all.json +1 -0
- package/tsconfig.json +11 -7
- package/types/artifacts.d.ts +23 -25
- package/types/gatherer.d.ts +2 -3
- package/types/lhr/lhr.d.ts +2 -0
- package/core/computed/metrics/first-meaningful-paint.d.ts +0 -21
- package/core/computed/metrics/first-meaningful-paint.js +0 -44
- package/core/computed/metrics/lantern-first-meaningful-paint.d.ts +0 -25
- package/core/computed/metrics/lantern-first-meaningful-paint.js +0 -43
- package/core/lib/lantern/cpu-node.d.ts +0 -44
- package/core/lib/lantern/metrics/first-meaningful-paint.d.ts +0 -6
- package/core/lib/lantern/metrics/first-meaningful-paint.js +0 -64
- package/core/lib/lantern/metrics/interactive.d.ts +0 -26
- package/core/lib/lantern/metrics/largest-contentful-paint.d.ts +0 -19
- package/core/lib/lantern/metrics/max-potential-fid.d.ts +0 -30
- package/core/lib/lantern/metrics/total-blocking-time.d.ts +0 -31
- package/core/lib/lantern/page-dependency-graph.d.ts +0 -58
- /package/core/lib/lantern/{lantern-error.js → LanternError.js} +0 -0
- /package/core/{computed/metrics/tbt-utils.js → lib/lantern/TBTUtils.js} +0 -0
|
@@ -3,15 +3,15 @@ declare namespace _default {
|
|
|
3
3
|
export { convertNodeTimingsToTrace };
|
|
4
4
|
}
|
|
5
5
|
export default _default;
|
|
6
|
-
export type Node = import('./lantern/
|
|
7
|
-
export type CompleteNodeTiming = import('./lantern/
|
|
6
|
+
export type Node = import('./lantern/BaseNode.js').Node<LH.Artifacts.NetworkRequest>;
|
|
7
|
+
export type CompleteNodeTiming = import('./lantern/simulation/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('./lantern/
|
|
14
|
-
/** @typedef {import('./lantern/
|
|
13
|
+
/** @typedef {import('./lantern/BaseNode.js').Node<LH.Artifacts.NetworkRequest>} Node */
|
|
14
|
+
/** @typedef {import('./lantern/simulation/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('./lantern/
|
|
8
|
-
/** @typedef {import('./lantern/
|
|
7
|
+
/** @typedef {import('./lantern/BaseNode.js').Node<LH.Artifacts.NetworkRequest>} Node */
|
|
8
|
+
/** @typedef {import('./lantern/simulation/Simulator.js').CompleteNodeTiming} CompleteNodeTiming */
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @param {Map<Node, CompleteNodeTiming>} nodeTimings
|
|
@@ -33,7 +33,7 @@ function convertNodeTimingsToTrace(nodeTimings) {
|
|
|
33
33
|
traceEvents.push(...createFakeTaskEvents(node, timing));
|
|
34
34
|
} else {
|
|
35
35
|
/** @type {LH.Artifacts.NetworkRequest} */
|
|
36
|
-
const record = node.
|
|
36
|
+
const record = node.rawRequest;
|
|
37
37
|
// Ignore data URIs as they don't really add much value
|
|
38
38
|
if (/^data/.test(record.url)) continue;
|
|
39
39
|
traceEvents.push(...createFakeNetworkEvents(requestId, record, timing));
|
|
@@ -116,7 +116,7 @@ function convertNodeTimingsToTrace(nodeTimings) {
|
|
|
116
116
|
const ts = eventTs + (event.ts - nestedBaseTs) * multiplier;
|
|
117
117
|
const newEvent = {...event, ...{pid: baseEvent.pid, tid: baseEvent.tid}, ts};
|
|
118
118
|
if (event.dur) newEvent.dur = event.dur * multiplier;
|
|
119
|
-
events.push(newEvent);
|
|
119
|
+
events.push(/** @type {LH.TraceEvent} */(newEvent));
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
return events;
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import * as Lantern from './lantern/lantern.js';
|
|
7
8
|
import {LighthouseError} from './lh-error.js';
|
|
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
|
|
|
@@ -131,7 +131,7 @@ function getNonHtmlError(finalRecord) {
|
|
|
131
131
|
function getPageLoadError(navigationError, context) {
|
|
132
132
|
const {url, networkRecords} = context;
|
|
133
133
|
/** @type {LH.Artifacts.NetworkRequest|undefined} */
|
|
134
|
-
let mainRecord = NetworkAnalyzer.findResourceForUrl(networkRecords, url);
|
|
134
|
+
let mainRecord = Lantern.Simulation.NetworkAnalyzer.findResourceForUrl(networkRecords, url);
|
|
135
135
|
|
|
136
136
|
// If the url doesn't give us a network request, it's possible we landed on a chrome-error:// page
|
|
137
137
|
// In this case, just get the first document request.
|
|
@@ -149,7 +149,7 @@ function getPageLoadError(navigationError, context) {
|
|
|
149
149
|
// MIME Type is only set on the final redirected document request. Use this for the HTML check instead of root.
|
|
150
150
|
let finalRecord;
|
|
151
151
|
if (mainRecord) {
|
|
152
|
-
finalRecord = NetworkAnalyzer.resolveRedirects(mainRecord);
|
|
152
|
+
finalRecord = Lantern.Simulation.NetworkAnalyzer.resolveRedirects(mainRecord);
|
|
153
153
|
} else {
|
|
154
154
|
// We have no network requests to process, use the navError
|
|
155
155
|
return navigationError;
|
|
@@ -9,8 +9,8 @@ import {EventEmitter} from 'events';
|
|
|
9
9
|
import log from 'lighthouse-logger';
|
|
10
10
|
|
|
11
11
|
import * as LH from '../../types/lh.js';
|
|
12
|
+
import * as Lantern from './lantern/lantern.js';
|
|
12
13
|
import {NetworkRequest} from './network-request.js';
|
|
13
|
-
import {PageDependencyGraph} from '../lib/lantern/page-dependency-graph.js';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* @typedef {{
|
|
@@ -253,7 +253,7 @@ class NetworkRecorder extends RequestEventEmitter {
|
|
|
253
253
|
return record.redirectSource;
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
const initiatorURL = PageDependencyGraph.getNetworkInitiators(record)[0];
|
|
256
|
+
const initiatorURL = Lantern.PageDependencyGraph.getNetworkInitiators(record)[0];
|
|
257
257
|
let candidates = recordsByURL.get(initiatorURL) || [];
|
|
258
258
|
// The (valid) initiator must come before the initiated request.
|
|
259
259
|
candidates = candidates.filter(c => {
|
|
@@ -89,7 +89,7 @@ export class NetworkRequest {
|
|
|
89
89
|
*/
|
|
90
90
|
static getResourceSizeOnNetwork(networkRecord: NetworkRequest): number;
|
|
91
91
|
requestId: string;
|
|
92
|
-
connectionId:
|
|
92
|
+
connectionId: number;
|
|
93
93
|
connectionReused: boolean;
|
|
94
94
|
url: string;
|
|
95
95
|
protocol: string;
|
|
@@ -104,7 +104,11 @@ export class NetworkRequest {
|
|
|
104
104
|
* HTTP cache or going to the network for DNS/connection setup, in milliseconds.
|
|
105
105
|
*/
|
|
106
106
|
networkRequestTime: number;
|
|
107
|
-
/**
|
|
107
|
+
/**
|
|
108
|
+
* When the last byte of the response headers is received, in milliseconds.
|
|
109
|
+
* Equal to networkRequestTime if no data is recieved over the
|
|
110
|
+
* network (ex: cached requests or data urls).
|
|
111
|
+
*/
|
|
108
112
|
responseHeadersEndTime: number;
|
|
109
113
|
/** When the last byte of the response body is received, in milliseconds. */
|
|
110
114
|
networkEndTime: number;
|
|
@@ -149,6 +153,7 @@ export class NetworkRequest {
|
|
|
149
153
|
sessionId: string | undefined;
|
|
150
154
|
/** @type {LH.Protocol.TargetType|undefined} */
|
|
151
155
|
sessionTargetType: LH.Protocol.TargetType | undefined;
|
|
156
|
+
fromWorker: boolean;
|
|
152
157
|
isLinkPreload: boolean;
|
|
153
158
|
/**
|
|
154
159
|
* @return {boolean}
|
|
@@ -202,6 +207,7 @@ export class NetworkRequest {
|
|
|
202
207
|
* @param {LH.Crdp.Network.ResponseReceivedEvent['type']=} resourceType
|
|
203
208
|
*/
|
|
204
209
|
_onResponse(response: LH.Crdp.Network.Response, timestamp: number, resourceType?: LH.Crdp.Network.ResponseReceivedEvent['type'] | undefined): void;
|
|
210
|
+
responseTimestamp: number | undefined;
|
|
205
211
|
/**
|
|
206
212
|
* Resolve differences between conflicting timing signals. Based on the property setters in DevTools.
|
|
207
213
|
* @see https://github.com/ChromeDevTools/devtools-frontend/blob/56a99365197b85c24b732ac92b0ac70feed80179/front_end/sdk/NetworkRequest.js#L485-L502
|
|
@@ -258,8 +264,28 @@ export namespace NetworkRequest {
|
|
|
258
264
|
export { HEADER_FETCHED_SIZE };
|
|
259
265
|
export { HEADER_PROTOCOL_IS_H2 };
|
|
260
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* @typedef HeaderEntry
|
|
269
|
+
* @property {string} name
|
|
270
|
+
* @property {string} value
|
|
271
|
+
*/
|
|
272
|
+
/**
|
|
273
|
+
* @typedef ParsedURL
|
|
274
|
+
* @property {string} scheme Equivalent to a `new URL(url).protocol` BUT w/o the trailing colon (:)
|
|
275
|
+
* @property {string} host Equivalent to a `new URL(url).hostname`
|
|
276
|
+
* @property {string} securityOrigin
|
|
277
|
+
*/
|
|
278
|
+
/**
|
|
279
|
+
* @typedef LightriderStatistics
|
|
280
|
+
* @property {number} endTimeDeltaMs The difference in networkEndTime between the observed Lighthouse networkEndTime and Lightrider's derived networkEndTime.
|
|
281
|
+
* @property {number} TCPMs The time spent making a TCP connection (connect + SSL). Note: this is poorly named.
|
|
282
|
+
* @property {number} requestMs 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".
|
|
283
|
+
* @property {number} responseMs Time to receive the entire response payload starting the clock on receiving the first fragment (first non-header byte).
|
|
284
|
+
*/
|
|
285
|
+
/** @type {LH.Util.SelfMap<LH.Crdp.Network.ResourceType>} */
|
|
286
|
+
export const RESOURCE_TYPES: LH.Util.SelfMap<LH.Crdp.Network.ResourceType>;
|
|
261
287
|
import * as LH from '../../types/lh.js';
|
|
262
|
-
import * as Lantern from './lantern/
|
|
288
|
+
import * as Lantern from './lantern/lantern.js';
|
|
263
289
|
declare const HEADER_TCP: "X-TCPMs";
|
|
264
290
|
declare const HEADER_SSL: "X-SSLMs";
|
|
265
291
|
declare const HEADER_REQ: "X-RequestMs";
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
*/
|
|
54
54
|
|
|
55
55
|
import * as LH from '../../types/lh.js';
|
|
56
|
-
import * as Lantern from './lantern/
|
|
56
|
+
import * as Lantern from './lantern/lantern.js';
|
|
57
57
|
import UrlUtils from './url-utils.js';
|
|
58
58
|
|
|
59
59
|
// Lightrider X-Header names for timing information.
|
|
@@ -112,7 +112,7 @@ const RESOURCE_TYPES = {
|
|
|
112
112
|
class NetworkRequest {
|
|
113
113
|
constructor() {
|
|
114
114
|
this.requestId = '';
|
|
115
|
-
this.connectionId =
|
|
115
|
+
this.connectionId = 0;
|
|
116
116
|
this.connectionReused = false;
|
|
117
117
|
|
|
118
118
|
this.url = '';
|
|
@@ -129,7 +129,11 @@ class NetworkRequest {
|
|
|
129
129
|
* HTTP cache or going to the network for DNS/connection setup, in milliseconds.
|
|
130
130
|
*/
|
|
131
131
|
this.networkRequestTime = -1;
|
|
132
|
-
/**
|
|
132
|
+
/**
|
|
133
|
+
* When the last byte of the response headers is received, in milliseconds.
|
|
134
|
+
* Equal to networkRequestTime if no data is recieved over the
|
|
135
|
+
* network (ex: cached requests or data urls).
|
|
136
|
+
*/
|
|
133
137
|
this.responseHeadersEndTime = -1;
|
|
134
138
|
/** When the last byte of the response body is received, in milliseconds. */
|
|
135
139
|
this.networkEndTime = -1;
|
|
@@ -180,6 +184,7 @@ class NetworkRequest {
|
|
|
180
184
|
this.sessionId = undefined;
|
|
181
185
|
/** @type {LH.Protocol.TargetType|undefined} */
|
|
182
186
|
this.sessionTargetType = undefined;
|
|
187
|
+
this.fromWorker = false;
|
|
183
188
|
this.isLinkPreload = false;
|
|
184
189
|
}
|
|
185
190
|
|
|
@@ -221,8 +226,9 @@ class NetworkRequest {
|
|
|
221
226
|
this.isSecure = UrlUtils.isSecureScheme(this.parsedURL.scheme);
|
|
222
227
|
|
|
223
228
|
this.rendererStartTime = data.timestamp * 1000;
|
|
224
|
-
//
|
|
229
|
+
// These are expected to be overridden with better value in `_recomputeTimesWithResourceTiming`.
|
|
225
230
|
this.networkRequestTime = this.rendererStartTime;
|
|
231
|
+
this.responseHeadersEndTime = this.rendererStartTime;
|
|
226
232
|
|
|
227
233
|
this.requestMethod = data.request.method;
|
|
228
234
|
|
|
@@ -344,13 +350,12 @@ class NetworkRequest {
|
|
|
344
350
|
_onResponse(response, timestamp, resourceType) {
|
|
345
351
|
this.url = response.url;
|
|
346
352
|
|
|
347
|
-
this.connectionId =
|
|
353
|
+
this.connectionId = response.connectionId;
|
|
348
354
|
this.connectionReused = response.connectionReused;
|
|
349
355
|
|
|
350
356
|
if (response.protocol) this.protocol = response.protocol;
|
|
351
357
|
|
|
352
|
-
|
|
353
|
-
this.responseHeadersEndTime = timestamp * 1000;
|
|
358
|
+
this.responseTimestamp = timestamp * 1000;
|
|
354
359
|
|
|
355
360
|
this.transferSize = response.encodedDataLength;
|
|
356
361
|
this.responseHeadersTransferSize = response.encodedDataLength;
|
|
@@ -380,7 +385,7 @@ class NetworkRequest {
|
|
|
380
385
|
_recomputeTimesWithResourceTiming(timing) {
|
|
381
386
|
// Don't recompute times if the data is invalid. RequestTime should always be a thread timestamp.
|
|
382
387
|
// If we don't have receiveHeadersEnd, we really don't have more accurate data.
|
|
383
|
-
if (timing.requestTime ===
|
|
388
|
+
if (timing.requestTime === -1 || timing.receiveHeadersEnd === -1) return;
|
|
384
389
|
|
|
385
390
|
// Take networkRequestTime and responseHeadersEndTime from timing data for better accuracy.
|
|
386
391
|
// Before this, networkRequestTime and responseHeadersEndTime were set to bogus values based on
|
|
@@ -391,15 +396,15 @@ class NetworkRequest {
|
|
|
391
396
|
// See https://raw.githubusercontent.com/GoogleChrome/lighthouse/main/docs/Network-Timings.svg
|
|
392
397
|
this.networkRequestTime = timing.requestTime * 1000;
|
|
393
398
|
const headersReceivedTime = this.networkRequestTime + timing.receiveHeadersEnd;
|
|
394
|
-
// This was set in `_onResponse` as that event's timestamp.
|
|
395
|
-
const responseTimestamp = this.responseHeadersEndTime;
|
|
396
399
|
|
|
397
400
|
// Update this.responseHeadersEndTime. All timing values from the netstack (timing) are well-ordered, and
|
|
398
401
|
// so are the timestamps from CDP (which this.responseHeadersEndTime belongs to). It shouldn't be possible
|
|
399
402
|
// that this timing from the netstack is greater than the onResponse timestamp, but just to ensure proper order
|
|
400
403
|
// is maintained we bound the new timing by the network request time and the response timestamp.
|
|
401
404
|
this.responseHeadersEndTime = headersReceivedTime;
|
|
402
|
-
|
|
405
|
+
if (this.responseTimestamp !== undefined) {
|
|
406
|
+
this.responseHeadersEndTime = Math.min(this.responseHeadersEndTime, this.responseTimestamp);
|
|
407
|
+
}
|
|
403
408
|
this.responseHeadersEndTime = Math.max(this.responseHeadersEndTime, this.networkRequestTime);
|
|
404
409
|
|
|
405
410
|
// We're only at responseReceived (_onResponse) at this point.
|
|
@@ -600,11 +605,13 @@ class NetworkRequest {
|
|
|
600
605
|
}
|
|
601
606
|
}
|
|
602
607
|
|
|
608
|
+
record.fromWorker = record.sessionTargetType === 'worker';
|
|
609
|
+
|
|
603
610
|
return {
|
|
611
|
+
rawRequest: record,
|
|
604
612
|
...record,
|
|
605
613
|
timing,
|
|
606
614
|
serverResponseTime,
|
|
607
|
-
record,
|
|
608
615
|
};
|
|
609
616
|
}
|
|
610
617
|
|
|
@@ -691,4 +698,4 @@ NetworkRequest.HEADER_TOTAL = HEADER_TOTAL;
|
|
|
691
698
|
NetworkRequest.HEADER_FETCHED_SIZE = HEADER_FETCHED_SIZE;
|
|
692
699
|
NetworkRequest.HEADER_PROTOCOL_IS_H2 = HEADER_PROTOCOL_IS_H2;
|
|
693
700
|
|
|
694
|
-
export {NetworkRequest};
|
|
701
|
+
export {NetworkRequest, RESOURCE_TYPES};
|
|
@@ -281,11 +281,9 @@ export class TraceProcessor {
|
|
|
281
281
|
timeOriginEvt: import("../..").TraceEvent;
|
|
282
282
|
firstPaintEvt: import("../..").TraceEvent | undefined;
|
|
283
283
|
firstContentfulPaintEvt: import("../..").TraceEvent;
|
|
284
|
-
firstMeaningfulPaintEvt: import("../..").TraceEvent | undefined;
|
|
285
284
|
largestContentfulPaintEvt: LCPEvent | undefined;
|
|
286
285
|
loadEvt: import("../..").TraceEvent | undefined;
|
|
287
286
|
domContentLoadedEvt: import("../..").TraceEvent | undefined;
|
|
288
|
-
fmpFellBack: boolean;
|
|
289
287
|
lcpInvalidated: boolean;
|
|
290
288
|
};
|
|
291
289
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* various tools. This artifact will take a trace and then:
|
|
10
10
|
*
|
|
11
11
|
* 1. Find the TracingStartedInPage and navigationStart events of our intended tab & frame.
|
|
12
|
-
* 2. Find the firstContentfulPaint and marked
|
|
12
|
+
* 2. Find the firstContentfulPaint and marked largestContentfulPaint events
|
|
13
13
|
* 3. Isolate only the trace events from the tab's process (including all threads like compositor)
|
|
14
14
|
* * Sort those trace events in chronological order (as order isn't guaranteed)
|
|
15
15
|
* 4. Return all those items in one handy bundle.
|
|
@@ -835,7 +835,6 @@ class TraceProcessor {
|
|
|
835
835
|
firstPaint: frameTimings.timings.firstPaint,
|
|
836
836
|
firstContentfulPaint: frameTimings.timings.firstContentfulPaint,
|
|
837
837
|
firstContentfulPaintAllFrames: getTiming(fcpAllFramesEvt.ts),
|
|
838
|
-
firstMeaningfulPaint: frameTimings.timings.firstMeaningfulPaint,
|
|
839
838
|
largestContentfulPaint: frameTimings.timings.largestContentfulPaint,
|
|
840
839
|
largestContentfulPaintAllFrames: maybeGetTiming(lcpAllFramesEvt?.ts),
|
|
841
840
|
load: frameTimings.timings.load,
|
|
@@ -847,7 +846,6 @@ class TraceProcessor {
|
|
|
847
846
|
firstPaint: frameTimings.timestamps.firstPaint,
|
|
848
847
|
firstContentfulPaint: frameTimings.timestamps.firstContentfulPaint,
|
|
849
848
|
firstContentfulPaintAllFrames: fcpAllFramesEvt.ts,
|
|
850
|
-
firstMeaningfulPaint: frameTimings.timestamps.firstMeaningfulPaint,
|
|
851
849
|
largestContentfulPaint: frameTimings.timestamps.largestContentfulPaint,
|
|
852
850
|
largestContentfulPaintAllFrames: lcpAllFramesEvt?.ts,
|
|
853
851
|
load: frameTimings.timestamps.load,
|
|
@@ -857,12 +855,10 @@ class TraceProcessor {
|
|
|
857
855
|
firstPaintEvt: frameTimings.firstPaintEvt,
|
|
858
856
|
firstContentfulPaintEvt: frameTimings.firstContentfulPaintEvt,
|
|
859
857
|
firstContentfulPaintAllFramesEvt: fcpAllFramesEvt,
|
|
860
|
-
firstMeaningfulPaintEvt: frameTimings.firstMeaningfulPaintEvt,
|
|
861
858
|
largestContentfulPaintEvt: frameTimings.largestContentfulPaintEvt,
|
|
862
859
|
largestContentfulPaintAllFramesEvt: lcpAllFramesEvt,
|
|
863
860
|
loadEvt: frameTimings.loadEvt,
|
|
864
861
|
domContentLoadedEvt: frameTimings.domContentLoadedEvt,
|
|
865
|
-
fmpFellBack: frameTimings.fmpFellBack,
|
|
866
862
|
lcpInvalidated: frameTimings.lcpInvalidated,
|
|
867
863
|
};
|
|
868
864
|
}
|
|
@@ -970,28 +966,6 @@ class TraceProcessor {
|
|
|
970
966
|
throw this.createNoFirstContentfulPaintError();
|
|
971
967
|
}
|
|
972
968
|
|
|
973
|
-
// fMP will follow at/after the FP
|
|
974
|
-
let firstMeaningfulPaint = frameEvents.find(
|
|
975
|
-
e => e.name === 'firstMeaningfulPaint' && e.ts > timeOriginEvt.ts
|
|
976
|
-
);
|
|
977
|
-
let fmpFellBack = false;
|
|
978
|
-
|
|
979
|
-
// If there was no firstMeaningfulPaint event found in the trace, the network idle detection
|
|
980
|
-
// may have not been triggered before Lighthouse finished tracing.
|
|
981
|
-
// In this case, we'll use the last firstMeaningfulPaintCandidate we can find.
|
|
982
|
-
// However, if no candidates were found (a bogus trace, likely), we fail.
|
|
983
|
-
if (!firstMeaningfulPaint) {
|
|
984
|
-
const fmpCand = 'firstMeaningfulPaintCandidate';
|
|
985
|
-
fmpFellBack = true;
|
|
986
|
-
log.verbose('TraceProcessor',
|
|
987
|
-
`No firstMeaningfulPaint found, falling back to last ${fmpCand}`);
|
|
988
|
-
const lastCandidate = frameEvents.filter(e => e.name === fmpCand).pop();
|
|
989
|
-
if (!lastCandidate) {
|
|
990
|
-
log.verbose('TraceProcessor', 'No `firstMeaningfulPaintCandidate` events found in trace');
|
|
991
|
-
}
|
|
992
|
-
firstMeaningfulPaint = lastCandidate;
|
|
993
|
-
}
|
|
994
|
-
|
|
995
969
|
// This function accepts events spanning multiple frames, but this usage will only provide events from the main frame.
|
|
996
970
|
const lcpResult = this.computeValidLCPAllFrames(frameEvents, timeOriginEvt);
|
|
997
971
|
|
|
@@ -1007,7 +981,6 @@ class TraceProcessor {
|
|
|
1007
981
|
timeOrigin: timeOriginEvt.ts,
|
|
1008
982
|
firstPaint: getTimestamp(firstPaint),
|
|
1009
983
|
firstContentfulPaint: firstContentfulPaint.ts,
|
|
1010
|
-
firstMeaningfulPaint: getTimestamp(firstMeaningfulPaint),
|
|
1011
984
|
largestContentfulPaint: getTimestamp(lcpResult.lcp),
|
|
1012
985
|
load: getTimestamp(load),
|
|
1013
986
|
domContentLoaded: getTimestamp(domContentLoaded),
|
|
@@ -1022,7 +995,6 @@ class TraceProcessor {
|
|
|
1022
995
|
timeOrigin: 0,
|
|
1023
996
|
firstPaint: maybeGetTiming(timestamps.firstPaint),
|
|
1024
997
|
firstContentfulPaint: getTiming(timestamps.firstContentfulPaint),
|
|
1025
|
-
firstMeaningfulPaint: maybeGetTiming(timestamps.firstMeaningfulPaint),
|
|
1026
998
|
largestContentfulPaint: maybeGetTiming(timestamps.largestContentfulPaint),
|
|
1027
999
|
load: maybeGetTiming(timestamps.load),
|
|
1028
1000
|
domContentLoaded: maybeGetTiming(timestamps.domContentLoaded),
|
|
@@ -1034,11 +1006,9 @@ class TraceProcessor {
|
|
|
1034
1006
|
timeOriginEvt: timeOriginEvt,
|
|
1035
1007
|
firstPaintEvt: firstPaint,
|
|
1036
1008
|
firstContentfulPaintEvt: firstContentfulPaint,
|
|
1037
|
-
firstMeaningfulPaintEvt: firstMeaningfulPaint,
|
|
1038
1009
|
largestContentfulPaintEvt: lcpResult.lcp,
|
|
1039
1010
|
loadEvt: load,
|
|
1040
1011
|
domContentLoadedEvt: domContentLoaded,
|
|
1041
|
-
fmpFellBack,
|
|
1042
1012
|
lcpInvalidated: lcpResult.invalidated,
|
|
1043
1013
|
};
|
|
1044
1014
|
}
|