lighthouse 12.4.0-dev.20250312 → 12.4.0-dev.20250313
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/legacy-javascript.d.ts +5 -4
- package/core/audits/byte-efficiency/legacy-javascript.js +67 -17
- package/core/audits/byte-efficiency/render-blocking-resources.js +2 -1
- package/core/audits/critical-request-chains.js +2 -1
- package/core/audits/insights/insight-audit.js +2 -1
- package/core/audits/layout-shifts.js +2 -1
- package/core/audits/long-tasks.js +2 -1
- package/core/audits/script-treemap-data.js +6 -2
- package/core/audits/uses-rel-preconnect.js +1 -1
- package/core/audits/uses-rel-preload.js +2 -1
- package/core/computed/critical-request-chains.d.ts +3 -1
- package/core/computed/critical-request-chains.js +2 -2
- package/core/computed/navigation-insights.d.ts +9 -3
- package/core/computed/navigation-insights.js +5 -4
- package/core/computed/page-dependency-graph.d.ts +3 -1
- package/core/computed/page-dependency-graph.js +5 -5
- package/core/computed/trace-engine-result.d.ts +5 -2
- package/core/computed/trace-engine-result.js +27 -5
- package/core/gather/gatherers/trace-elements.js +2 -1
- package/package.json +2 -2
|
@@ -2,13 +2,12 @@ export default LegacyJavascript;
|
|
|
2
2
|
export type Pattern = {
|
|
3
3
|
name: string;
|
|
4
4
|
expression: string;
|
|
5
|
-
estimateBytes?: (
|
|
5
|
+
estimateBytes?: (content: string) => number;
|
|
6
6
|
};
|
|
7
7
|
export type PatternMatchResult = {
|
|
8
8
|
name: string;
|
|
9
9
|
line: number;
|
|
10
10
|
column: number;
|
|
11
|
-
count: number;
|
|
12
11
|
};
|
|
13
12
|
export type ByteEfficiencyProduct = import("./byte-efficiency-audit.js").ByteEfficiencyProduct;
|
|
14
13
|
export type Item = LH.Audit.ByteEfficiencyItem & {
|
|
@@ -50,10 +49,11 @@ declare class LegacyJavascript extends ByteEfficiencyAudit {
|
|
|
50
49
|
*/
|
|
51
50
|
static detectAcrossScripts(matcher: CodePatternMatcher, scripts: LH.Artifacts["Scripts"], bundles: LH.Artifacts.Bundle[]): Map<LH.Artifacts.Script, PatternMatchResult[]>;
|
|
52
51
|
/**
|
|
52
|
+
* @param {LH.Artifacts.Script} script
|
|
53
53
|
* @param {PatternMatchResult[]} matches
|
|
54
54
|
* @return {number}
|
|
55
55
|
*/
|
|
56
|
-
static estimateWastedBytes(matches: PatternMatchResult[]): number;
|
|
56
|
+
static estimateWastedBytes(script: LH.Artifacts.Script, matches: PatternMatchResult[]): number;
|
|
57
57
|
/**
|
|
58
58
|
* @param {LH.Artifacts} artifacts
|
|
59
59
|
* @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
|
|
@@ -70,7 +70,8 @@ export namespace UIStrings {
|
|
|
70
70
|
import { ByteEfficiencyAudit } from './byte-efficiency-audit.js';
|
|
71
71
|
/**
|
|
72
72
|
* Takes a list of patterns (consisting of a name identifier and a RegExp expression string)
|
|
73
|
-
* and returns match results with line / column information for a given code input.
|
|
73
|
+
* and via `match` returns match results with line / column information for a given code input.
|
|
74
|
+
* Only returns the first match per pattern given.
|
|
74
75
|
*/
|
|
75
76
|
declare class CodePatternMatcher {
|
|
76
77
|
/**
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
* ./core/scripts/legacy-javascript - verification tool.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
/** @typedef {{name: string, expression: string, estimateBytes?: (
|
|
15
|
-
/** @typedef {{name: string, line: number, column: number
|
|
14
|
+
/** @typedef {{name: string, expression: string, estimateBytes?: (content: string) => number}} Pattern */
|
|
15
|
+
/** @typedef {{name: string, line: number, column: number}} PatternMatchResult */
|
|
16
16
|
/** @typedef {import('./byte-efficiency-audit.js').ByteEfficiencyProduct} ByteEfficiencyProduct */
|
|
17
17
|
/** @typedef {LH.Audit.ByteEfficiencyItem & {subItems: {type: 'subitems', items: SubItem[]}}} Item */
|
|
18
18
|
/** @typedef {{signal: string, location: LH.Audit.Details.SourceLocationValue}} SubItem */
|
|
@@ -55,7 +55,8 @@ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* Takes a list of patterns (consisting of a name identifier and a RegExp expression string)
|
|
58
|
-
* and returns match results with line / column information for a given code input.
|
|
58
|
+
* and via `match` returns match results with line / column information for a given code input.
|
|
59
|
+
* Only returns the first match per pattern given.
|
|
59
60
|
*/
|
|
60
61
|
class CodePatternMatcher {
|
|
61
62
|
/**
|
|
@@ -99,8 +100,6 @@ class CodePatternMatcher {
|
|
|
99
100
|
const pattern = this.patterns[patternExpressionMatches.findIndex(Boolean)];
|
|
100
101
|
|
|
101
102
|
if (seen.has(pattern)) {
|
|
102
|
-
const existingMatch = matches.find(m => m.name === pattern.name);
|
|
103
|
-
if (existingMatch) existingMatch.count += 1;
|
|
104
103
|
continue;
|
|
105
104
|
}
|
|
106
105
|
seen.add(pattern);
|
|
@@ -109,7 +108,6 @@ class CodePatternMatcher {
|
|
|
109
108
|
name: pattern.name,
|
|
110
109
|
line,
|
|
111
110
|
column: result.index - lineBeginsAtIndex,
|
|
112
|
-
count: 1,
|
|
113
111
|
});
|
|
114
112
|
}
|
|
115
113
|
|
|
@@ -229,23 +227,74 @@ class LegacyJavascript extends ByteEfficiencyAudit {
|
|
|
229
227
|
* @return {Pattern[]}
|
|
230
228
|
*/
|
|
231
229
|
static getTransformPatterns() {
|
|
230
|
+
/**
|
|
231
|
+
* @param {string} content
|
|
232
|
+
* @param {RegExp|string} pattern
|
|
233
|
+
* @return {number}
|
|
234
|
+
*/
|
|
235
|
+
const count = (content, pattern) => {
|
|
236
|
+
// Split is slightly faster than match.
|
|
237
|
+
if (typeof pattern === 'string') {
|
|
238
|
+
return content.split(pattern).length - 1;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return (content.match(pattern) ?? []).length;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
// For expression: prefer a string that is found in the transform runtime support code (those won't ever be minified).
|
|
245
|
+
|
|
232
246
|
return [
|
|
247
|
+
// @babel/plugin-transform-classes
|
|
248
|
+
//
|
|
249
|
+
// input:
|
|
250
|
+
//
|
|
251
|
+
// class MyTestClass {
|
|
252
|
+
// log() {
|
|
253
|
+
// console.log(1);
|
|
254
|
+
// }
|
|
255
|
+
// };
|
|
256
|
+
//
|
|
257
|
+
// output:
|
|
258
|
+
//
|
|
259
|
+
// function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
260
|
+
// function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
|
|
261
|
+
// function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
262
|
+
// function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
263
|
+
// function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
264
|
+
// let MyTestClass = function () {
|
|
265
|
+
// function MyTestClass() {
|
|
266
|
+
// _classCallCheck(this, MyTestClass);
|
|
267
|
+
// }
|
|
268
|
+
// return _createClass(MyTestClass, [{
|
|
269
|
+
// key: "log",
|
|
270
|
+
// value: function log() {
|
|
271
|
+
// console.log(1);
|
|
272
|
+
// }
|
|
273
|
+
// }]);
|
|
274
|
+
// }();
|
|
233
275
|
{
|
|
234
276
|
name: '@babel/plugin-transform-classes',
|
|
235
277
|
expression: 'Cannot call a class as a function',
|
|
236
|
-
estimateBytes:
|
|
278
|
+
estimateBytes: content => {
|
|
279
|
+
return 1000 + (count(content, '_classCallCheck') - 1) * '_classCallCheck()'.length;
|
|
280
|
+
},
|
|
237
281
|
},
|
|
238
282
|
{
|
|
239
283
|
name: '@babel/plugin-transform-regenerator',
|
|
240
|
-
expression:
|
|
284
|
+
expression: 'Generator is already running|regeneratorRuntime',
|
|
241
285
|
// Example of this transform: https://gist.github.com/connorjclark/af8bccfff377ac44efc104a79bc75da2
|
|
242
286
|
// `regeneratorRuntime.awrap` is generated for every usage of `await`, and adds ~80 bytes each.
|
|
243
|
-
estimateBytes:
|
|
287
|
+
estimateBytes: content => {
|
|
288
|
+
return count(content, /regeneratorRuntime\(?\)?\.a?wrap/g) * 80;
|
|
289
|
+
},
|
|
244
290
|
},
|
|
245
291
|
{
|
|
246
292
|
name: '@babel/plugin-transform-spread',
|
|
247
|
-
expression:
|
|
248
|
-
estimateBytes:
|
|
293
|
+
expression: 'Invalid attempt to spread non-iterable instance',
|
|
294
|
+
estimateBytes: content => {
|
|
295
|
+
const per = '_toConsumableArray()'.length;
|
|
296
|
+
return 1169 + count(content, /\.apply\(void 0,\s?_toConsumableArray/g) * per;
|
|
297
|
+
},
|
|
249
298
|
},
|
|
250
299
|
];
|
|
251
300
|
}
|
|
@@ -283,9 +332,9 @@ class LegacyJavascript extends ByteEfficiencyAudit {
|
|
|
283
332
|
|
|
284
333
|
const mapping = bundle.map.mappings().find(m => m.sourceURL === source);
|
|
285
334
|
if (mapping) {
|
|
286
|
-
matches.push({name, line: mapping.lineNumber, column: mapping.columnNumber
|
|
335
|
+
matches.push({name, line: mapping.lineNumber, column: mapping.columnNumber});
|
|
287
336
|
} else {
|
|
288
|
-
matches.push({name, line: 0, column: 0
|
|
337
|
+
matches.push({name, line: 0, column: 0});
|
|
289
338
|
}
|
|
290
339
|
}
|
|
291
340
|
}
|
|
@@ -298,10 +347,11 @@ class LegacyJavascript extends ByteEfficiencyAudit {
|
|
|
298
347
|
}
|
|
299
348
|
|
|
300
349
|
/**
|
|
350
|
+
* @param {LH.Artifacts.Script} script
|
|
301
351
|
* @param {PatternMatchResult[]} matches
|
|
302
352
|
* @return {number}
|
|
303
353
|
*/
|
|
304
|
-
static estimateWastedBytes(matches) {
|
|
354
|
+
static estimateWastedBytes(script, matches) {
|
|
305
355
|
// Split up results based on polyfill / transform. Only transforms start with @.
|
|
306
356
|
const polyfillResults = matches.filter(m => !m.name.startsWith('@'));
|
|
307
357
|
const transformResults = matches.filter(m => m.name.startsWith('@'));
|
|
@@ -325,8 +375,8 @@ class LegacyJavascript extends ByteEfficiencyAudit {
|
|
|
325
375
|
|
|
326
376
|
for (const result of transformResults) {
|
|
327
377
|
const pattern = this.getTransformPatterns().find(p => p.name === result.name);
|
|
328
|
-
if (!pattern || !pattern.estimateBytes) continue;
|
|
329
|
-
estimatedWastedBytesFromTransforms += pattern.estimateBytes(
|
|
378
|
+
if (!pattern || !pattern.estimateBytes || !script.content) continue;
|
|
379
|
+
estimatedWastedBytesFromTransforms += pattern.estimateBytes(script.content);
|
|
330
380
|
}
|
|
331
381
|
|
|
332
382
|
const estimatedWastedBytes =
|
|
@@ -363,7 +413,7 @@ class LegacyJavascript extends ByteEfficiencyAudit {
|
|
|
363
413
|
for (const [script, matches] of scriptToMatchResults.entries()) {
|
|
364
414
|
const compressionRatio = estimateCompressionRatioForContent(
|
|
365
415
|
compressionRatioByUrl, script.url, artifacts, networkRecords);
|
|
366
|
-
const wastedBytes = Math.round(this.estimateWastedBytes(matches) * compressionRatio);
|
|
416
|
+
const wastedBytes = Math.round(this.estimateWastedBytes(script, matches) * compressionRatio);
|
|
367
417
|
/** @type {typeof items[number]} */
|
|
368
418
|
const item = {
|
|
369
419
|
url: script.url,
|
|
@@ -122,13 +122,14 @@ class RenderBlockingResources extends Audit {
|
|
|
122
122
|
* @return {Promise<{fcpWastedMs: number, lcpWastedMs: number, results: Array<{url: string, totalBytes: number, wastedMs: number}>}>}
|
|
123
123
|
*/
|
|
124
124
|
static async computeResults(artifacts, context) {
|
|
125
|
+
const settings = context.settings;
|
|
125
126
|
const gatherContext = artifacts.GatherContext;
|
|
126
127
|
const trace = artifacts.traces[Audit.DEFAULT_PASS];
|
|
127
128
|
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
|
|
128
129
|
const simulatorData = {devtoolsLog, settings: context.settings};
|
|
129
130
|
const simulator = await LoadSimulator.request(simulatorData, context);
|
|
130
131
|
const wastedCssBytes = await RenderBlockingResources.computeWastedCSSBytes(artifacts, context);
|
|
131
|
-
const navInsights = await NavigationInsights.request(trace, context);
|
|
132
|
+
const navInsights = await NavigationInsights.request({trace, settings}, context);
|
|
132
133
|
|
|
133
134
|
const renderBlocking = navInsights.model.RenderBlocking;
|
|
134
135
|
if (renderBlocking instanceof Error) throw renderBlocking;
|
|
@@ -168,10 +168,11 @@ class CriticalRequestChains extends Audit {
|
|
|
168
168
|
* @return {Promise<LH.Audit.Product>}
|
|
169
169
|
*/
|
|
170
170
|
static async audit(artifacts, context) {
|
|
171
|
+
const settings = context.settings;
|
|
171
172
|
const trace = artifacts.traces[Audit.DEFAULT_PASS];
|
|
172
173
|
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
|
|
173
174
|
const URL = artifacts.URL;
|
|
174
|
-
const chains = await ComputedChains.request({devtoolsLog, trace, URL}, context);
|
|
175
|
+
const chains = await ComputedChains.request({settings, devtoolsLog, trace, URL}, context);
|
|
175
176
|
let chainCount = 0;
|
|
176
177
|
/**
|
|
177
178
|
* @param {LH.Audit.Details.SimpleCriticalRequestNode} node
|
|
@@ -16,9 +16,10 @@ import {Audit} from '../audit.js';
|
|
|
16
16
|
* @return {Promise<import('@paulirish/trace_engine/models/trace/insights/types.js').InsightSet|undefined>}
|
|
17
17
|
*/
|
|
18
18
|
async function getInsightSet(artifacts, context) {
|
|
19
|
+
const settings = context.settings;
|
|
19
20
|
const trace = artifacts.traces[Audit.DEFAULT_PASS];
|
|
20
21
|
const processedTrace = await ProcessedTrace.request(trace, context);
|
|
21
|
-
const traceEngineResult = await TraceEngineResult.request({trace}, context);
|
|
22
|
+
const traceEngineResult = await TraceEngineResult.request({trace, settings}, context);
|
|
22
23
|
|
|
23
24
|
const navigationId = processedTrace.timeOriginEvt.args.data?.navigationId;
|
|
24
25
|
const key = navigationId ?? NO_NAVIGATION;
|
|
@@ -57,8 +57,9 @@ class LayoutShifts extends Audit {
|
|
|
57
57
|
* @return {Promise<LH.Audit.Product>}
|
|
58
58
|
*/
|
|
59
59
|
static async audit(artifacts, context) {
|
|
60
|
+
const settings = context.settings;
|
|
60
61
|
const trace = artifacts.traces[Audit.DEFAULT_PASS];
|
|
61
|
-
const traceEngineResult = await TraceEngineResult.request({trace}, context);
|
|
62
|
+
const traceEngineResult = await TraceEngineResult.request({trace, settings}, context);
|
|
62
63
|
const clusters = traceEngineResult.data.LayoutShifts.clusters ?? [];
|
|
63
64
|
const {cumulativeLayoutShift: clsSavings, impactByNodeId} =
|
|
64
65
|
await CumulativeLayoutShiftComputed.request(trace, context);
|
|
@@ -192,7 +192,8 @@ class LongTasks extends Audit {
|
|
|
192
192
|
taskTimingsByEvent = new Map();
|
|
193
193
|
|
|
194
194
|
const simulatorOptions = {devtoolsLog, settings: context.settings};
|
|
195
|
-
const pageGraph =
|
|
195
|
+
const pageGraph =
|
|
196
|
+
await PageDependencyGraph.request({settings, trace, devtoolsLog, URL}, context);
|
|
196
197
|
const simulator = await LoadSimulator.request(simulatorOptions, context);
|
|
197
198
|
const simulation = await simulator.simulate(pageGraph, {label: 'long-tasks-diagnostic'});
|
|
198
199
|
for (const [node, timing] of simulation.nodeTimings.entries()) {
|
|
@@ -114,8 +114,12 @@ class ScriptTreemapDataAudit extends Audit {
|
|
|
114
114
|
*/
|
|
115
115
|
function collapseAll(node) {
|
|
116
116
|
while (node.children && node.children.length === 1) {
|
|
117
|
-
|
|
118
|
-
node.
|
|
117
|
+
const child = node.children[0];
|
|
118
|
+
node.name += '/' + child.name;
|
|
119
|
+
if (child.duplicatedNormalizedModuleName) {
|
|
120
|
+
node.duplicatedNormalizedModuleName = child.duplicatedNormalizedModuleName;
|
|
121
|
+
}
|
|
122
|
+
node.children = child.children;
|
|
119
123
|
}
|
|
120
124
|
|
|
121
125
|
if (node.children) {
|
|
@@ -137,7 +137,7 @@ class UsesRelPreconnectAudit extends Audit {
|
|
|
137
137
|
MainResource.request({devtoolsLog, URL: artifacts.URL}, context),
|
|
138
138
|
LoadSimulator.request({devtoolsLog, settings}, context),
|
|
139
139
|
ProcessedNavigation.request(trace, context),
|
|
140
|
-
PageDependencyGraph.request({trace, devtoolsLog, URL: artifacts.URL}, context),
|
|
140
|
+
PageDependencyGraph.request({settings, trace, devtoolsLog, URL: artifacts.URL}, context),
|
|
141
141
|
]);
|
|
142
142
|
|
|
143
143
|
const {rtt, additionalRttByOrigin} = loadSimulator.getOptions();
|
|
@@ -212,6 +212,7 @@ class UsesRelPreloadAudit extends Audit {
|
|
|
212
212
|
* @return {Promise<LH.Audit.Product>}
|
|
213
213
|
*/
|
|
214
214
|
static async audit(artifacts, context) {
|
|
215
|
+
const settings = context.settings;
|
|
215
216
|
const trace = artifacts.traces[UsesRelPreloadAudit.DEFAULT_PASS];
|
|
216
217
|
const devtoolsLog = artifacts.devtoolsLogs[UsesRelPreloadAudit.DEFAULT_PASS];
|
|
217
218
|
const URL = artifacts.URL;
|
|
@@ -219,7 +220,7 @@ class UsesRelPreloadAudit extends Audit {
|
|
|
219
220
|
|
|
220
221
|
const [mainResource, graph, simulator] = await Promise.all([
|
|
221
222
|
MainResource.request({devtoolsLog, URL}, context),
|
|
222
|
-
PageDependencyGraph.request({trace, devtoolsLog, URL}, context),
|
|
223
|
+
PageDependencyGraph.request({settings, trace, devtoolsLog, URL}, context),
|
|
223
224
|
LoadSimulator.request(simulatorOptions, context),
|
|
224
225
|
]);
|
|
225
226
|
|
|
@@ -4,6 +4,7 @@ declare const CriticalRequestChainsComputed: typeof CriticalRequestChains & {
|
|
|
4
4
|
URL: LH.Artifacts["URL"];
|
|
5
5
|
devtoolsLog: LH.DevtoolsLog;
|
|
6
6
|
trace: LH.Trace;
|
|
7
|
+
settings: LH.Audit.Context["settings"];
|
|
7
8
|
}, context: LH.Artifacts.ComputedContext) => ReturnType<typeof CriticalRequestChains.compute_>;
|
|
8
9
|
};
|
|
9
10
|
declare class CriticalRequestChains {
|
|
@@ -24,7 +25,7 @@ declare class CriticalRequestChains {
|
|
|
24
25
|
*/
|
|
25
26
|
static extractChainsFromGraph(mainResource: LH.Artifacts.NetworkRequest, graph: LH.Gatherer.Simulation.GraphNode): LH.Artifacts.CriticalRequestNode;
|
|
26
27
|
/**
|
|
27
|
-
* @param {{URL: LH.Artifacts['URL'], devtoolsLog: LH.DevtoolsLog, trace: LH.Trace}} data
|
|
28
|
+
* @param {{URL: LH.Artifacts['URL'], devtoolsLog: LH.DevtoolsLog, trace: LH.Trace, settings: LH.Audit.Context['settings']}} data
|
|
28
29
|
* @param {LH.Artifacts.ComputedContext} context
|
|
29
30
|
* @return {Promise<LH.Artifacts.CriticalRequestNode>}
|
|
30
31
|
*/
|
|
@@ -32,6 +33,7 @@ declare class CriticalRequestChains {
|
|
|
32
33
|
URL: LH.Artifacts["URL"];
|
|
33
34
|
devtoolsLog: LH.DevtoolsLog;
|
|
34
35
|
trace: LH.Trace;
|
|
36
|
+
settings: LH.Audit.Context["settings"];
|
|
35
37
|
}, context: LH.Artifacts.ComputedContext): Promise<LH.Artifacts.CriticalRequestNode>;
|
|
36
38
|
}
|
|
37
39
|
import * as Lantern from '../lib/lantern/lantern.js';
|
|
@@ -126,7 +126,7 @@ class CriticalRequestChains {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
/**
|
|
129
|
-
* @param {{URL: LH.Artifacts['URL'], devtoolsLog: LH.DevtoolsLog, trace: LH.Trace}} data
|
|
129
|
+
* @param {{URL: LH.Artifacts['URL'], devtoolsLog: LH.DevtoolsLog, trace: LH.Trace, settings: LH.Audit.Context['settings']}} data
|
|
130
130
|
* @param {LH.Artifacts.ComputedContext} context
|
|
131
131
|
* @return {Promise<LH.Artifacts.CriticalRequestNode>}
|
|
132
132
|
*/
|
|
@@ -139,5 +139,5 @@ class CriticalRequestChains {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
const CriticalRequestChainsComputed =
|
|
142
|
-
makeComputedArtifact(CriticalRequestChains, ['URL', 'devtoolsLog', 'trace']);
|
|
142
|
+
makeComputedArtifact(CriticalRequestChains, ['URL', 'devtoolsLog', 'trace', 'settings']);
|
|
143
143
|
export {CriticalRequestChainsComputed as CriticalRequestChains};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export { NavigationInsightsComputed as NavigationInsights };
|
|
2
2
|
declare const NavigationInsightsComputed: typeof NavigationInsights & {
|
|
3
|
-
request: (dependencies:
|
|
3
|
+
request: (dependencies: {
|
|
4
|
+
trace: LH.Trace;
|
|
5
|
+
settings: LH.Audit.Context["settings"];
|
|
6
|
+
}, context: LH.Artifacts.ComputedContext) => ReturnType<typeof NavigationInsights.compute_>;
|
|
4
7
|
};
|
|
5
8
|
/**
|
|
6
9
|
* @fileoverview Gets insights from the shared trace engine for the navigation audited by Lighthouse.
|
|
@@ -8,9 +11,12 @@ declare const NavigationInsightsComputed: typeof NavigationInsights & {
|
|
|
8
11
|
*/
|
|
9
12
|
declare class NavigationInsights {
|
|
10
13
|
/**
|
|
11
|
-
* @param {LH.Trace}
|
|
14
|
+
* @param {{trace: LH.Trace, settings: LH.Audit.Context['settings']}} data
|
|
12
15
|
* @param {LH.Artifacts.ComputedContext} context
|
|
13
16
|
*/
|
|
14
|
-
static compute_(
|
|
17
|
+
static compute_(data: {
|
|
18
|
+
trace: LH.Trace;
|
|
19
|
+
settings: LH.Audit.Context["settings"];
|
|
20
|
+
}, context: LH.Artifacts.ComputedContext): Promise<import("@paulirish/trace_engine/models/trace/insights/types.js").InsightSet>;
|
|
15
21
|
}
|
|
16
22
|
//# sourceMappingURL=navigation-insights.d.ts.map
|
|
@@ -14,12 +14,13 @@ import {TraceEngineResult} from './trace-engine-result.js';
|
|
|
14
14
|
*/
|
|
15
15
|
class NavigationInsights {
|
|
16
16
|
/**
|
|
17
|
-
* @param {LH.Trace}
|
|
17
|
+
* @param {{trace: LH.Trace, settings: LH.Audit.Context['settings']}} data
|
|
18
18
|
* @param {LH.Artifacts.ComputedContext} context
|
|
19
19
|
*/
|
|
20
|
-
static async compute_(
|
|
20
|
+
static async compute_(data, context) {
|
|
21
|
+
const {trace, settings} = data;
|
|
21
22
|
const processedTrace = await ProcessedTrace.request(trace, context);
|
|
22
|
-
const traceEngineResult = await TraceEngineResult.request({trace}, context);
|
|
23
|
+
const traceEngineResult = await TraceEngineResult.request({trace, settings}, context);
|
|
23
24
|
|
|
24
25
|
const navigationId = processedTrace.timeOriginEvt.args.data?.navigationId;
|
|
25
26
|
if (!navigationId) throw new Error('No navigationId found');
|
|
@@ -31,5 +32,5 @@ class NavigationInsights {
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
const NavigationInsightsComputed = makeComputedArtifact(NavigationInsights,
|
|
35
|
+
const NavigationInsightsComputed = makeComputedArtifact(NavigationInsights, ['trace', 'settings']);
|
|
35
36
|
export {NavigationInsightsComputed as NavigationInsights};
|
|
@@ -3,19 +3,21 @@ declare const PageDependencyGraphComputed: typeof PageDependencyGraph & {
|
|
|
3
3
|
request: (dependencies: {
|
|
4
4
|
trace: LH.Trace;
|
|
5
5
|
devtoolsLog: LH.DevtoolsLog;
|
|
6
|
+
settings: LH.Audit.Context["settings"];
|
|
6
7
|
URL: LH.Artifacts["URL"];
|
|
7
8
|
fromTrace?: boolean;
|
|
8
9
|
}, context: LH.Artifacts.ComputedContext) => ReturnType<typeof PageDependencyGraph.compute_>;
|
|
9
10
|
};
|
|
10
11
|
declare class PageDependencyGraph {
|
|
11
12
|
/**
|
|
12
|
-
* @param {{trace: LH.Trace, devtoolsLog: LH.DevtoolsLog, URL: LH.Artifacts['URL'], fromTrace?: boolean}} data
|
|
13
|
+
* @param {{trace: LH.Trace, devtoolsLog: LH.DevtoolsLog, settings: LH.Audit.Context['settings'], URL: LH.Artifacts['URL'], fromTrace?: boolean}} data
|
|
13
14
|
* @param {LH.Artifacts.ComputedContext} context
|
|
14
15
|
* @return {Promise<LH.Gatherer.Simulation.GraphNode>}
|
|
15
16
|
*/
|
|
16
17
|
static compute_(data: {
|
|
17
18
|
trace: LH.Trace;
|
|
18
19
|
devtoolsLog: LH.DevtoolsLog;
|
|
20
|
+
settings: LH.Audit.Context["settings"];
|
|
19
21
|
URL: LH.Artifacts["URL"];
|
|
20
22
|
fromTrace?: boolean;
|
|
21
23
|
}, context: LH.Artifacts.ComputedContext): Promise<LH.Gatherer.Simulation.GraphNode>;
|
|
@@ -13,19 +13,19 @@ import {TraceEngineResult} from './trace-engine-result.js';
|
|
|
13
13
|
|
|
14
14
|
class PageDependencyGraph {
|
|
15
15
|
/**
|
|
16
|
-
* @param {{trace: LH.Trace, devtoolsLog: LH.DevtoolsLog, URL: LH.Artifacts['URL'], fromTrace?: boolean}} data
|
|
16
|
+
* @param {{trace: LH.Trace, devtoolsLog: LH.DevtoolsLog, settings: LH.Audit.Context['settings'], URL: LH.Artifacts['URL'], fromTrace?: boolean}} data
|
|
17
17
|
* @param {LH.Artifacts.ComputedContext} context
|
|
18
18
|
* @return {Promise<LH.Gatherer.Simulation.GraphNode>}
|
|
19
19
|
*/
|
|
20
20
|
static async compute_(data, context) {
|
|
21
|
-
const {trace, devtoolsLog, URL} = data;
|
|
21
|
+
const {trace, settings, devtoolsLog, URL} = data;
|
|
22
22
|
const [{mainThreadEvents}, networkRecords] = await Promise.all([
|
|
23
23
|
ProcessedTrace.request(trace, context),
|
|
24
24
|
NetworkRecords.request(devtoolsLog, context),
|
|
25
25
|
]);
|
|
26
26
|
|
|
27
27
|
if (data.fromTrace) {
|
|
28
|
-
const traceEngineResult = await TraceEngineResult.request({trace}, context);
|
|
28
|
+
const traceEngineResult = await TraceEngineResult.request({trace, settings}, context);
|
|
29
29
|
const traceEngineData = traceEngineResult.data;
|
|
30
30
|
const requests =
|
|
31
31
|
Lantern.TraceEngineComputationData.createNetworkRequests(trace, traceEngineData);
|
|
@@ -40,6 +40,6 @@ class PageDependencyGraph {
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
const PageDependencyGraphComputed =
|
|
44
|
-
|
|
43
|
+
const PageDependencyGraphComputed = makeComputedArtifact(PageDependencyGraph,
|
|
44
|
+
['devtoolsLog', 'settings', 'trace', 'URL', 'fromTrace']);
|
|
45
45
|
export {PageDependencyGraphComputed as PageDependencyGraph};
|
|
@@ -2,6 +2,7 @@ export { TraceEngineResultComputed as TraceEngineResult };
|
|
|
2
2
|
declare const TraceEngineResultComputed: typeof TraceEngineResult & {
|
|
3
3
|
request: (dependencies: {
|
|
4
4
|
trace: LH.Trace;
|
|
5
|
+
settings: LH.Audit.Context["settings"];
|
|
5
6
|
}, context: LH.Artifacts.ComputedContext) => ReturnType<typeof TraceEngineResult.compute_>;
|
|
6
7
|
};
|
|
7
8
|
/**
|
|
@@ -10,9 +11,10 @@ declare const TraceEngineResultComputed: typeof TraceEngineResult & {
|
|
|
10
11
|
declare class TraceEngineResult {
|
|
11
12
|
/**
|
|
12
13
|
* @param {LH.TraceEvent[]} traceEvents
|
|
14
|
+
* @param {LH.Audit.Context['settings']} settings
|
|
13
15
|
* @return {Promise<LH.Artifacts.TraceEngineResult>}
|
|
14
16
|
*/
|
|
15
|
-
static runTraceEngine(traceEvents: LH.TraceEvent[]): Promise<LH.Artifacts.TraceEngineResult>;
|
|
17
|
+
static runTraceEngine(traceEvents: LH.TraceEvent[], settings: LH.Audit.Context["settings"]): Promise<LH.Artifacts.TraceEngineResult>;
|
|
16
18
|
/**
|
|
17
19
|
* Adapts the given DevTools function that returns a localized string to one
|
|
18
20
|
* that returns a LH.IcuMessage.
|
|
@@ -45,12 +47,13 @@ declare class TraceEngineResult {
|
|
|
45
47
|
*/
|
|
46
48
|
static localizeInsights(insightSets: import("@paulirish/trace_engine/models/trace/insights/types.js").TraceInsightSets): void;
|
|
47
49
|
/**
|
|
48
|
-
* @param {{trace: LH.Trace}} data
|
|
50
|
+
* @param {{trace: LH.Trace, settings: LH.Audit.Context['settings']}} data
|
|
49
51
|
* @param {LH.Artifacts.ComputedContext} context
|
|
50
52
|
* @return {Promise<LH.Artifacts.TraceEngineResult>}
|
|
51
53
|
*/
|
|
52
54
|
static compute_(data: {
|
|
53
55
|
trace: LH.Trace;
|
|
56
|
+
settings: LH.Audit.Context["settings"];
|
|
54
57
|
}, context: LH.Artifacts.ComputedContext): Promise<LH.Artifacts.TraceEngineResult>;
|
|
55
58
|
}
|
|
56
59
|
import * as LH from '../../types/lh.js';
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import log from 'lighthouse-logger';
|
|
8
|
+
|
|
7
9
|
import * as i18n from '../lib/i18n/i18n.js';
|
|
8
10
|
import * as TraceEngine from '../lib/trace-engine.js';
|
|
9
11
|
import {makeComputedArtifact} from './computed-artifact.js';
|
|
@@ -17,15 +19,35 @@ import * as LH from '../../types/lh.js';
|
|
|
17
19
|
class TraceEngineResult {
|
|
18
20
|
/**
|
|
19
21
|
* @param {LH.TraceEvent[]} traceEvents
|
|
22
|
+
* @param {LH.Audit.Context['settings']} settings
|
|
20
23
|
* @return {Promise<LH.Artifacts.TraceEngineResult>}
|
|
21
24
|
*/
|
|
22
|
-
static async runTraceEngine(traceEvents) {
|
|
25
|
+
static async runTraceEngine(traceEvents, settings) {
|
|
23
26
|
const processor = new TraceEngine.TraceProcessor(TraceEngine.TraceHandlers);
|
|
24
27
|
|
|
28
|
+
const lanternSettings = {};
|
|
29
|
+
if (settings.throttlingMethod) lanternSettings.throttlingMethod = settings.throttlingMethod;
|
|
30
|
+
if (settings.throttling) lanternSettings.throttling = settings.throttling;
|
|
31
|
+
if (settings.precomputedLanternData) {
|
|
32
|
+
lanternSettings.precomputedLanternData = settings.precomputedLanternData;
|
|
33
|
+
}
|
|
34
|
+
|
|
25
35
|
// eslint-disable-next-line max-len
|
|
26
36
|
await processor.parse(/** @type {import('@paulirish/trace_engine').Types.Events.Event[]} */ (
|
|
27
37
|
traceEvents
|
|
28
|
-
), {
|
|
38
|
+
), {
|
|
39
|
+
logger: {
|
|
40
|
+
start(id) {
|
|
41
|
+
const logId = `lh:computed:TraceEngineResult:${id}`;
|
|
42
|
+
log.time({msg: `Trace Engine ${id}`, id: logId});
|
|
43
|
+
},
|
|
44
|
+
end(id) {
|
|
45
|
+
const logId = `lh:computed:TraceEngineResult:${id}`;
|
|
46
|
+
log.timeEnd({msg: `Trace Engine ${id}`, id: logId});
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
lanternSettings,
|
|
50
|
+
});
|
|
29
51
|
if (!processor.parsedTrace) throw new Error('No data');
|
|
30
52
|
if (!processor.insights) throw new Error('No insights');
|
|
31
53
|
this.localizeInsights(processor.insights);
|
|
@@ -177,7 +199,7 @@ class TraceEngineResult {
|
|
|
177
199
|
}
|
|
178
200
|
|
|
179
201
|
/**
|
|
180
|
-
* @param {{trace: LH.Trace}} data
|
|
202
|
+
* @param {{trace: LH.Trace, settings: LH.Audit.Context['settings']}} data
|
|
181
203
|
* @param {LH.Artifacts.ComputedContext} context
|
|
182
204
|
* @return {Promise<LH.Artifacts.TraceEngineResult>}
|
|
183
205
|
*/
|
|
@@ -207,10 +229,10 @@ class TraceEngineResult {
|
|
|
207
229
|
}
|
|
208
230
|
}
|
|
209
231
|
|
|
210
|
-
const result = await TraceEngineResult.runTraceEngine(traceEvents);
|
|
232
|
+
const result = await TraceEngineResult.runTraceEngine(traceEvents, data.settings);
|
|
211
233
|
return result;
|
|
212
234
|
}
|
|
213
235
|
}
|
|
214
236
|
|
|
215
|
-
const TraceEngineResultComputed = makeComputedArtifact(TraceEngineResult, ['trace']);
|
|
237
|
+
const TraceEngineResultComputed = makeComputedArtifact(TraceEngineResult, ['trace', 'settings']);
|
|
216
238
|
export {TraceEngineResultComputed as TraceEngineResult};
|
|
@@ -386,7 +386,8 @@ class TraceElements extends BaseGatherer {
|
|
|
386
386
|
const session = context.driver.defaultSession;
|
|
387
387
|
|
|
388
388
|
const trace = context.dependencies.Trace;
|
|
389
|
-
const
|
|
389
|
+
const settings = context.settings;
|
|
390
|
+
const traceEngineResult = await TraceEngineResult.request({trace, settings}, context);
|
|
390
391
|
const rootCauses = context.dependencies.RootCauses;
|
|
391
392
|
|
|
392
393
|
const processedTrace = await ProcessedTrace.request(trace, context);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lighthouse",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "12.4.0-dev.
|
|
4
|
+
"version": "12.4.0-dev.20250313",
|
|
5
5
|
"description": "Automated auditing, performance metrics, and best practices for the web.",
|
|
6
6
|
"main": "./core/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -184,7 +184,7 @@
|
|
|
184
184
|
"webtreemap-cdt": "^3.2.1"
|
|
185
185
|
},
|
|
186
186
|
"dependencies": {
|
|
187
|
-
"@paulirish/trace_engine": "0.0.
|
|
187
|
+
"@paulirish/trace_engine": "0.0.48",
|
|
188
188
|
"@sentry/node": "^7.0.0",
|
|
189
189
|
"axe-core": "^4.10.2",
|
|
190
190
|
"chrome-launcher": "^1.1.2",
|