lighthouse 10.4.0-dev.20230720 → 10.4.0-dev.20230722

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.
@@ -1,6 +1,6 @@
1
1
  export { ProcessedNavigationComputed as ProcessedNavigation };
2
2
  declare const ProcessedNavigationComputed: typeof ProcessedNavigation & {
3
- request: (dependencies: import("../index.js").Trace | import("../index.js").Artifacts.ProcessedTrace, context: import("../../types/utility-types.js").default.ImmutableObject<{
3
+ request: (dependencies: import("../index.js").Artifacts.ProcessedTrace | import("../index.js").Trace, context: import("../../types/utility-types.js").default.ImmutableObject<{
4
4
  computedCache: Map<string, import("../lib/arbitrary-equality-map.js").ArbitraryEqualityMap>;
5
5
  }>) => Promise<import("../index.js").Artifacts.ProcessedNavigation>;
6
6
  };
@@ -6,7 +6,6 @@
6
6
 
7
7
  import log from 'lighthouse-logger';
8
8
 
9
- import {NetworkMonitor} from './network-monitor.js';
10
9
  import {waitForFullyLoaded, waitForFrameNavigated, waitForUserToContinue} from './wait-for-condition.js'; // eslint-disable-line max-len
11
10
  import * as constants from '../../config/constants.js';
12
11
  import * as i18n from '../../lib/i18n/i18n.js';
@@ -89,10 +88,9 @@ async function gotoURL(driver, requestor, options) {
89
88
  log.time(status);
90
89
 
91
90
  const session = driver.defaultSession;
92
- const networkMonitor = new NetworkMonitor(driver.targetManager);
91
+ const networkMonitor = driver.networkMonitor;
93
92
 
94
93
  // Enable the events and network monitor needed to track navigation progress.
95
- await networkMonitor.enable();
96
94
  await session.sendCommand('Page.enable');
97
95
  await session.sendCommand('Page.setLifecycleEventsEnabled', {enabled: true});
98
96
 
@@ -144,7 +142,6 @@ async function gotoURL(driver, requestor, options) {
144
142
 
145
143
  // Bring `Page.navigate` errors back into the promise chain. See https://github.com/GoogleChrome/lighthouse/pull/6739.
146
144
  await waitForNavigationTriggered;
147
- await networkMonitor.disable();
148
145
 
149
146
  if (options.debugNavigation) {
150
147
  await waitForUserToContinue(driver);
@@ -76,6 +76,7 @@ export class NetworkMonitor extends NetworkMonitor_base {
76
76
  */
77
77
  _emitNetworkStatus(): void;
78
78
  }
79
+ import * as LH from '../../../types/lh.js';
79
80
  import { NetworkRecorder } from '../../lib/network-recorder.js';
80
81
  import { NetworkRequest } from '../../lib/network-request.js';
81
82
  export {};
@@ -13,6 +13,7 @@ import {EventEmitter} from 'events';
13
13
 
14
14
  import log from 'lighthouse-logger';
15
15
 
16
+ import * as LH from '../../../types/lh.js';
16
17
  import {NetworkRecorder} from '../../lib/network-recorder.js';
17
18
  import {NetworkRequest} from '../../lib/network-request.js';
18
19
  import UrlUtils from '../../lib/url-utils.js';
@@ -7,6 +7,8 @@ export class Driver implements LH.Gatherer.Driver {
7
7
  _page: import("../../types/puppeteer.js").default.Page;
8
8
  /** @type {TargetManager|undefined} */
9
9
  _targetManager: TargetManager | undefined;
10
+ /** @type {NetworkMonitor|undefined} */
11
+ _networkMonitor: NetworkMonitor | undefined;
10
12
  /** @type {ExecutionContext|undefined} */
11
13
  _executionContext: ExecutionContext | undefined;
12
14
  /** @type {Fetcher|undefined} */
@@ -14,9 +16,9 @@ export class Driver implements LH.Gatherer.Driver {
14
16
  defaultSession: import("../../types/gatherer.js").default.ProtocolSession;
15
17
  /** @return {LH.Gatherer.Driver['executionContext']} */
16
18
  get executionContext(): ExecutionContext;
17
- /** @return {Fetcher} */
18
- get fetcher(): Fetcher;
19
+ get fetcher(): any;
19
20
  get targetManager(): any;
21
+ get networkMonitor(): any;
20
22
  /** @return {Promise<string>} */
21
23
  url(): Promise<string>;
22
24
  /** @return {Promise<void>} */
@@ -25,6 +27,7 @@ export class Driver implements LH.Gatherer.Driver {
25
27
  disconnect(): Promise<void>;
26
28
  }
27
29
  import { TargetManager } from './driver/target-manager.js';
30
+ import { NetworkMonitor } from './driver/network-monitor.js';
28
31
  import { ExecutionContext } from './driver/execution-context.js';
29
32
  import { Fetcher } from './fetcher.js';
30
33
  //# sourceMappingURL=driver.d.ts.map
@@ -9,6 +9,7 @@ import log from 'lighthouse-logger';
9
9
  import {ExecutionContext} from './driver/execution-context.js';
10
10
  import {TargetManager} from './driver/target-manager.js';
11
11
  import {Fetcher} from './fetcher.js';
12
+ import {NetworkMonitor} from './driver/network-monitor.js';
12
13
 
13
14
  /** @return {*} */
14
15
  const throwNotConnectedFn = () => {
@@ -37,6 +38,8 @@ class Driver {
37
38
  this._page = page;
38
39
  /** @type {TargetManager|undefined} */
39
40
  this._targetManager = undefined;
41
+ /** @type {NetworkMonitor|undefined} */
42
+ this._networkMonitor = undefined;
40
43
  /** @type {ExecutionContext|undefined} */
41
44
  this._executionContext = undefined;
42
45
  /** @type {Fetcher|undefined} */
@@ -51,7 +54,6 @@ class Driver {
51
54
  return this._executionContext;
52
55
  }
53
56
 
54
- /** @return {Fetcher} */
55
57
  get fetcher() {
56
58
  if (!this._fetcher) return throwNotConnectedFn();
57
59
  return this._fetcher;
@@ -62,6 +64,11 @@ class Driver {
62
64
  return this._targetManager;
63
65
  }
64
66
 
67
+ get networkMonitor() {
68
+ if (!this._networkMonitor) return throwNotConnectedFn();
69
+ return this._networkMonitor;
70
+ }
71
+
65
72
  /** @return {Promise<string>} */
66
73
  async url() {
67
74
  return this._page.url();
@@ -75,6 +82,8 @@ class Driver {
75
82
  const cdpSession = await this._page.target().createCDPSession();
76
83
  this._targetManager = new TargetManager(cdpSession);
77
84
  await this._targetManager.enable();
85
+ this._networkMonitor = new NetworkMonitor(this._targetManager);
86
+ await this._networkMonitor.enable();
78
87
  this.defaultSession = this._targetManager.rootSession();
79
88
  this._executionContext = new ExecutionContext(this.defaultSession);
80
89
  this._fetcher = new Fetcher(this.defaultSession);
@@ -85,6 +94,7 @@ class Driver {
85
94
  async disconnect() {
86
95
  if (this.defaultSession === throwingSession) return;
87
96
  await this._targetManager?.disable();
97
+ await this._networkMonitor?.disable();
88
98
  await this.defaultSession.dispose();
89
99
  }
90
100
  }
@@ -9,7 +9,6 @@
9
9
  import BaseGatherer from '../base-gatherer.js';
10
10
  import * as emulation from '../../lib/emulation.js';
11
11
  import {pageFunctions} from '../../lib/page-functions.js';
12
- import {NetworkMonitor} from '../driver/network-monitor.js';
13
12
  import {waitForNetworkIdle} from '../driver/wait-for-condition.js';
14
13
 
15
14
  // JPEG quality setting
@@ -89,7 +88,7 @@ class FullPageScreenshot extends BaseGatherer {
89
88
  const height = Math.min(fullHeight, MAX_WEBP_SIZE);
90
89
 
91
90
  // Setup network monitor before we change the viewport.
92
- const networkMonitor = new NetworkMonitor(context.driver.targetManager);
91
+ const networkMonitor = context.driver.networkMonitor;
93
92
  const waitForNetworkIdleResult = waitForNetworkIdle(session, networkMonitor, {
94
93
  pretendDCLAlreadyFired: true,
95
94
  networkQuietThresholdMs: 1000,
@@ -97,7 +96,6 @@ class FullPageScreenshot extends BaseGatherer {
97
96
  idleEvent: 'network-critical-idle',
98
97
  isIdle: recorder => recorder.isCriticalIdle(),
99
98
  });
100
- await networkMonitor.enable();
101
99
 
102
100
  await session.sendCommand('Emulation.setDeviceMetricsOverride', {
103
101
  mobile: deviceMetrics.mobile,
@@ -113,7 +111,6 @@ class FullPageScreenshot extends BaseGatherer {
113
111
  waitForNetworkIdleResult.promise,
114
112
  ]);
115
113
  waitForNetworkIdleResult.cancel();
116
- await networkMonitor.disable();
117
114
 
118
115
  // Now that new resources are (probably) fetched, wait long enough for a layout.
119
116
  await context.driver.executionContext.evaluate(waitForDoubleRaf, {args: []});
@@ -3,6 +3,7 @@ export default Scripts;
3
3
  * @fileoverview Gets JavaScript file contents.
4
4
  */
5
5
  declare class Scripts extends BaseGatherer {
6
+ static symbol: symbol;
6
7
  /** @type {LH.Crdp.Debugger.ScriptParsedEvent[]} */
7
8
  _scriptParsedEvents: LH.Crdp.Debugger.ScriptParsedEvent[];
8
9
  /** @type {Array<string | undefined>} */
@@ -48,8 +48,11 @@ function isLighthouseRuntimeEvaluateScript(script) {
48
48
  * @fileoverview Gets JavaScript file contents.
49
49
  */
50
50
  class Scripts extends BaseGatherer {
51
+ static symbol = Symbol('Scripts');
52
+
51
53
  /** @type {LH.Gatherer.GathererMeta} */
52
54
  meta = {
55
+ symbol: Scripts.symbol,
53
56
  supportedModes: ['timespan', 'navigation'],
54
57
  };
55
58
 
@@ -91,11 +94,6 @@ class Scripts extends BaseGatherer {
91
94
 
92
95
  session.off('Debugger.scriptParsed', this.onScriptParsed);
93
96
 
94
- // Without this line the Debugger domain will be off in FR runner,
95
- // because only the legacy gatherer has special handling for multiple,
96
- // overlapped enabled/disable calls.
97
- await session.sendCommand('Debugger.enable');
98
-
99
97
  // If run on a mobile device, be sensitive to memory limitations and only
100
98
  // request one at a time.
101
99
  this._scriptContents = await runInSeriesOrParallel(
@@ -3,12 +3,8 @@ export default SourceMaps;
3
3
  * @fileoverview Gets JavaScript source maps.
4
4
  */
5
5
  declare class SourceMaps extends BaseGatherer {
6
- /** @type {LH.Crdp.Debugger.ScriptParsedEvent[]} */
7
- _scriptParsedEvents: LH.Crdp.Debugger.ScriptParsedEvent[];
8
- /**
9
- * @param {LH.Crdp.Debugger.ScriptParsedEvent} event
10
- */
11
- onScriptParsed(event: LH.Crdp.Debugger.ScriptParsedEvent): void;
6
+ /** @type {LH.Gatherer.GathererMeta<'Scripts'>} */
7
+ meta: LH.Gatherer.GathererMeta<'Scripts'>;
12
8
  /**
13
9
  * @param {LH.Gatherer.Driver} driver
14
10
  * @param {string} sourceMapUrl
@@ -28,23 +24,15 @@ declare class SourceMaps extends BaseGatherer {
28
24
  _resolveUrl(url: string, base: string): string | undefined;
29
25
  /**
30
26
  * @param {LH.Gatherer.Driver} driver
31
- * @param {LH.Crdp.Debugger.ScriptParsedEvent} event
27
+ * @param {LH.Artifacts.Script} script
32
28
  * @return {Promise<LH.Artifacts.SourceMap>}
33
29
  */
34
- _retrieveMapFromScriptParsedEvent(driver: LH.Gatherer.Driver, event: LH.Crdp.Debugger.ScriptParsedEvent): Promise<LH.Artifacts.SourceMap>;
35
- /**
36
- * @param {LH.Gatherer.Context} context
37
- */
38
- startSensitiveInstrumentation(context: LH.Gatherer.Context): Promise<void>;
39
- /**
40
- * @param {LH.Gatherer.Context} context
41
- */
42
- stopSensitiveInstrumentation(context: LH.Gatherer.Context): Promise<void>;
30
+ _retrieveMapFromScript(driver: LH.Gatherer.Driver, script: LH.Artifacts.Script): Promise<LH.Artifacts.SourceMap>;
43
31
  /**
44
- * @param {LH.Gatherer.Context} context
32
+ * @param {LH.Gatherer.Context<'Scripts'>} context
45
33
  * @return {Promise<LH.Artifacts['SourceMaps']>}
46
34
  */
47
- getArtifact(context: LH.Gatherer.Context): Promise<LH.Artifacts['SourceMaps']>;
35
+ getArtifact(context: LH.Gatherer.Context<'Scripts'>): Promise<LH.Artifacts['SourceMaps']>;
48
36
  }
49
37
  import BaseGatherer from '../base-gatherer.js';
50
38
  //# sourceMappingURL=source-maps.d.ts.map
@@ -6,23 +6,18 @@
6
6
 
7
7
  import SDK from '../../lib/cdt/SDK.js';
8
8
  import BaseGatherer from '../base-gatherer.js';
9
+ import Scripts from './scripts.js';
9
10
 
10
11
  /**
11
12
  * @fileoverview Gets JavaScript source maps.
12
13
  */
13
14
  class SourceMaps extends BaseGatherer {
14
- /** @type {LH.Gatherer.GathererMeta} */
15
+ /** @type {LH.Gatherer.GathererMeta<'Scripts'>} */
15
16
  meta = {
16
17
  supportedModes: ['timespan', 'navigation'],
18
+ dependencies: {Scripts: Scripts.symbol},
17
19
  };
18
20
 
19
- constructor() {
20
- super();
21
- /** @type {LH.Crdp.Debugger.ScriptParsedEvent[]} */
22
- this._scriptParsedEvents = [];
23
- this.onScriptParsed = this.onScriptParsed.bind(this);
24
- }
25
-
26
21
  /**
27
22
  * @param {LH.Gatherer.Driver} driver
28
23
  * @param {string} sourceMapUrl
@@ -45,15 +40,6 @@ class SourceMaps extends BaseGatherer {
45
40
  return SDK.SourceMap.parseSourceMap(buffer.toString());
46
41
  }
47
42
 
48
- /**
49
- * @param {LH.Crdp.Debugger.ScriptParsedEvent} event
50
- */
51
- onScriptParsed(event) {
52
- if (event.sourceMapURL) {
53
- this._scriptParsedEvents.push(event);
54
- }
55
- }
56
-
57
43
  /**
58
44
  * @param {string} url
59
45
  * @param {string} base
@@ -69,27 +55,27 @@ class SourceMaps extends BaseGatherer {
69
55
 
70
56
  /**
71
57
  * @param {LH.Gatherer.Driver} driver
72
- * @param {LH.Crdp.Debugger.ScriptParsedEvent} event
58
+ * @param {LH.Artifacts.Script} script
73
59
  * @return {Promise<LH.Artifacts.SourceMap>}
74
60
  */
75
- async _retrieveMapFromScriptParsedEvent(driver, event) {
76
- if (!event.sourceMapURL) {
61
+ async _retrieveMapFromScript(driver, script) {
62
+ if (!script.sourceMapURL) {
77
63
  throw new Error('precondition failed: event.sourceMapURL should exist');
78
64
  }
79
65
 
80
66
  // `sourceMapURL` is simply the URL found in either a magic comment or an x-sourcemap header.
81
67
  // It has not been resolved to a base url.
82
- const isSourceMapADataUri = event.sourceMapURL.startsWith('data:');
83
- const scriptUrl = event.url;
68
+ const isSourceMapADataUri = script.sourceMapURL.startsWith('data:');
69
+ const scriptUrl = script.name;
84
70
  const rawSourceMapUrl = isSourceMapADataUri ?
85
- event.sourceMapURL :
86
- this._resolveUrl(event.sourceMapURL, event.url);
71
+ script.sourceMapURL :
72
+ this._resolveUrl(script.sourceMapURL, script.name);
87
73
 
88
74
  if (!rawSourceMapUrl) {
89
75
  return {
90
- scriptId: event.scriptId,
76
+ scriptId: script.scriptId,
91
77
  scriptUrl,
92
- errorMessage: `Could not resolve map url: ${event.sourceMapURL}`,
78
+ errorMessage: `Could not resolve map url: ${script.sourceMapURL}`,
93
79
  };
94
80
  }
95
81
 
@@ -109,14 +95,14 @@ class SourceMaps extends BaseGatherer {
109
95
  map.sections = map.sections.filter(section => section.map);
110
96
  }
111
97
  return {
112
- scriptId: event.scriptId,
98
+ scriptId: script.scriptId,
113
99
  scriptUrl,
114
100
  sourceMapUrl,
115
101
  map,
116
102
  };
117
103
  } catch (err) {
118
104
  return {
119
- scriptId: event.scriptId,
105
+ scriptId: script.scriptId,
120
106
  scriptUrl,
121
107
  sourceMapUrl,
122
108
  errorMessage: err.toString(),
@@ -125,30 +111,13 @@ class SourceMaps extends BaseGatherer {
125
111
  }
126
112
 
127
113
  /**
128
- * @param {LH.Gatherer.Context} context
129
- */
130
- async startSensitiveInstrumentation(context) {
131
- const session = context.driver.defaultSession;
132
- session.on('Debugger.scriptParsed', this.onScriptParsed);
133
- await session.sendCommand('Debugger.enable');
134
- }
135
-
136
- /**
137
- * @param {LH.Gatherer.Context} context
138
- */
139
- async stopSensitiveInstrumentation(context) {
140
- const session = context.driver.defaultSession;
141
- await session.sendCommand('Debugger.disable');
142
- session.off('Debugger.scriptParsed', this.onScriptParsed);
143
- }
144
-
145
- /**
146
- * @param {LH.Gatherer.Context} context
114
+ * @param {LH.Gatherer.Context<'Scripts'>} context
147
115
  * @return {Promise<LH.Artifacts['SourceMaps']>}
148
116
  */
149
117
  async getArtifact(context) {
150
- const eventProcessPromises = this._scriptParsedEvents
151
- .map((event) => this._retrieveMapFromScriptParsedEvent(context.driver, event));
118
+ const eventProcessPromises = context.dependencies.Scripts
119
+ .filter(script => script.sourceMapURL)
120
+ .map(script => this._retrieveMapFromScript(context.driver, script));
152
121
  return Promise.all(eventProcessPromises);
153
122
  }
154
123
  }
@@ -17,7 +17,7 @@ export class NetworkRecorder extends NetworkRecorder_base {
17
17
  * @param {LH.DevtoolsLog} devtoolsLog
18
18
  * @return {Array<LH.Artifacts.NetworkRequest>}
19
19
  */
20
- static recordsFromLogs(devtoolsLog: import("../index.js").DevtoolsLog): Array<LH.Artifacts.NetworkRequest>;
20
+ static recordsFromLogs(devtoolsLog: LH.DevtoolsLog): Array<LH.Artifacts.NetworkRequest>;
21
21
  /** @type {NetworkRequest[]} */
22
22
  _records: NetworkRequest[];
23
23
  /** @type {Map<string, NetworkRequest>} */
@@ -117,5 +117,6 @@ export class NetworkRecorder extends NetworkRecorder_base {
117
117
  _findRealRequestAndSetSession(requestId: string, targetType: LH.Protocol.TargetType, sessionId: string | undefined): NetworkRequest | undefined;
118
118
  }
119
119
  import { NetworkRequest } from './network-request.js';
120
+ import * as LH from '../../types/lh.js';
120
121
  export {};
121
122
  //# sourceMappingURL=network-recorder.d.ts.map
@@ -8,6 +8,7 @@ import {EventEmitter} from 'events';
8
8
 
9
9
  import log from 'lighthouse-logger';
10
10
 
11
+ import * as LH from '../../types/lh.js';
11
12
  import {NetworkRequest} from './network-request.js';
12
13
  import {PageDependencyGraph} from '../computed/page-dependency-graph.js';
13
14
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lighthouse",
3
3
  "type": "module",
4
- "version": "10.4.0-dev.20230720",
4
+ "version": "10.4.0-dev.20230722",
5
5
  "description": "Automated auditing, performance metrics, and best practices for the web.",
6
6
  "main": "./core/index.js",
7
7
  "bin": {
@@ -11,6 +11,7 @@ import {NetworkNode as _NetworkNode} from '../core/lib/dependency-graph/network-
11
11
  import {CPUNode as _CPUNode} from '../core/lib/dependency-graph/cpu-node.js';
12
12
  import {Simulator as _Simulator} from '../core/lib/dependency-graph/simulator/simulator.js';
13
13
  import {ExecutionContext} from '../core/gather/driver/execution-context.js';
14
+ import {NetworkMonitor} from '../core/gather/driver/network-monitor.js';
14
15
  import {Fetcher} from '../core/gather/fetcher.js';
15
16
  import {ArbitraryEqualityMap} from '../core/lib/arbitrary-equality-map.js';
16
17
 
@@ -48,6 +49,7 @@ declare module Gatherer {
48
49
  on(event: 'protocolevent', callback: (payload: Protocol.RawEventMessage) => void): void
49
50
  off(event: 'protocolevent', callback: (payload: Protocol.RawEventMessage) => void): void
50
51
  };
52
+ networkMonitor: NetworkMonitor;
51
53
  }
52
54
 
53
55
  interface Context<TDependencies extends DependencyKey = DefaultDependenciesKey> {