lighthouse 12.3.0-dev.20250205 → 12.3.0-dev.20250206
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/audit.d.ts +5 -0
- package/core/audits/audit.js +11 -0
- package/core/audits/insights/README.md +3 -0
- package/core/audits/insights/cls-culprits-insight.d.ts +11 -0
- package/core/audits/insights/cls-culprits-insight.js +52 -0
- package/core/audits/insights/document-latency-insight.d.ts +11 -0
- package/core/audits/insights/document-latency-insight.js +47 -0
- package/core/audits/insights/dom-size-insight.d.ts +11 -0
- package/core/audits/insights/dom-size-insight.js +84 -0
- package/core/audits/insights/font-display-insight.d.ts +11 -0
- package/core/audits/insights/font-display-insight.js +52 -0
- package/core/audits/insights/forced-reflow-insight.d.ts +11 -0
- package/core/audits/insights/forced-reflow-insight.js +52 -0
- package/core/audits/insights/image-delivery-insight.d.ts +11 -0
- package/core/audits/insights/image-delivery-insight.js +52 -0
- package/core/audits/insights/insight-audit.d.ts +16 -0
- package/core/audits/insights/insight-audit.js +88 -0
- package/core/audits/insights/interaction-to-next-paint-insight.d.ts +11 -0
- package/core/audits/insights/interaction-to-next-paint-insight.js +52 -0
- package/core/audits/insights/lcp-discovery-insight.d.ts +11 -0
- package/core/audits/insights/lcp-discovery-insight.js +47 -0
- package/core/audits/insights/lcp-phases-insight.d.ts +11 -0
- package/core/audits/insights/lcp-phases-insight.js +52 -0
- package/core/audits/insights/long-critical-network-tree-insight.d.ts +11 -0
- package/core/audits/insights/long-critical-network-tree-insight.js +52 -0
- package/core/audits/insights/render-blocking-insight.d.ts +11 -0
- package/core/audits/insights/render-blocking-insight.js +56 -0
- package/core/audits/insights/slow-css-selector-insight.d.ts +11 -0
- package/core/audits/insights/slow-css-selector-insight.js +52 -0
- package/core/audits/insights/third-parties-insight.d.ts +11 -0
- package/core/audits/insights/third-parties-insight.js +52 -0
- package/core/audits/insights/viewport-insight.d.ts +11 -0
- package/core/audits/insights/viewport-insight.js +53 -0
- package/core/computed/metrics/lantern-metric.js +5 -1
- package/core/computed/trace-engine-result.d.ts +0 -4
- package/core/computed/trace-engine-result.js +0 -26
- package/core/config/default-config.js +35 -0
- package/core/gather/gatherers/trace-elements.d.ts +8 -0
- package/core/gather/gatherers/trace-elements.js +71 -1
- package/core/runner.js +2 -0
- package/dist/report/bundle.esm.js +38 -3
- package/dist/report/flow.js +40 -5
- package/dist/report/standalone.js +38 -3
- package/package.json +4 -3
- package/report/assets/styles.css +35 -0
- package/report/renderer/components.js +1 -1
- package/report/renderer/details-renderer.d.ts +5 -0
- package/report/renderer/details-renderer.js +21 -0
- package/report/renderer/performance-category-renderer.js +24 -9
- package/shared/localization/locales/en-US.json +213 -0
- package/shared/localization/locales/en-XL.json +213 -0
- package/types/artifacts.d.ts +1 -1
- package/types/lhr/audit-details.d.ts +6 -0
|
@@ -65,6 +65,71 @@ class TraceElements extends BaseGatherer {
|
|
|
65
65
|
if (name) this.animationIdToName.set(id, name);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* @param {LH.Artifacts.TraceEngineResult} traceEngineResult
|
|
70
|
+
* @param {string|undefined} navigationId
|
|
71
|
+
* @return {Promise<Array<{nodeId: number}>>}
|
|
72
|
+
*/
|
|
73
|
+
static async getTraceEngineElements(traceEngineResult, navigationId) {
|
|
74
|
+
// Can only resolve elements for the latest insight set, which should correspond
|
|
75
|
+
// to the current navigation id (if present). Can't resolve elements for pages
|
|
76
|
+
// that are gone.
|
|
77
|
+
const insightSet = [...traceEngineResult.insights.values()].at(-1);
|
|
78
|
+
if (!insightSet) {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (navigationId) {
|
|
83
|
+
if (insightSet.navigation?.args.data?.navigationId !== navigationId) {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
if (insightSet.navigation) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Execute `cb(obj, key)` on every object property (non-objects only), recursively.
|
|
94
|
+
* @param {any} obj
|
|
95
|
+
* @param {(obj: Record<string, string>, key: string) => void} cb
|
|
96
|
+
* @param {Set<object>} seen
|
|
97
|
+
*/
|
|
98
|
+
function recursiveObjectEnumerate(obj, cb, seen) {
|
|
99
|
+
if (seen.has(seen)) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
seen.add(obj);
|
|
104
|
+
|
|
105
|
+
if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
|
|
106
|
+
Object.keys(obj).forEach(key => {
|
|
107
|
+
if (typeof obj[key] === 'object') {
|
|
108
|
+
recursiveObjectEnumerate(obj[key], cb, seen);
|
|
109
|
+
} else {
|
|
110
|
+
cb(obj, key);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
} else if (Array.isArray(obj)) {
|
|
114
|
+
obj.forEach(item => {
|
|
115
|
+
if (typeof item === 'object' || Array.isArray(item)) {
|
|
116
|
+
recursiveObjectEnumerate(item, cb, seen);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** @type {number[]} */
|
|
123
|
+
const nodeIds = [];
|
|
124
|
+
recursiveObjectEnumerate(insightSet.model, (obj, key) => {
|
|
125
|
+
if (typeof obj[key] === 'number' && (key === 'nodeId' || key === 'node_id')) {
|
|
126
|
+
nodeIds.push(obj[key]);
|
|
127
|
+
}
|
|
128
|
+
}, new Set());
|
|
129
|
+
|
|
130
|
+
return [...new Set(nodeIds)].map(id => ({nodeId: id}));
|
|
131
|
+
}
|
|
132
|
+
|
|
68
133
|
/**
|
|
69
134
|
* We want to a single representative node to represent the shift, so let's pick
|
|
70
135
|
* the one with the largest impact (size x distance moved).
|
|
@@ -319,7 +384,10 @@ class TraceElements extends BaseGatherer {
|
|
|
319
384
|
|
|
320
385
|
const processedTrace = await ProcessedTrace.request(trace, context);
|
|
321
386
|
const {mainThreadEvents} = processedTrace;
|
|
387
|
+
const navigationId = processedTrace.timeOriginEvt.args.data?.navigationId;
|
|
322
388
|
|
|
389
|
+
const traceEngineData = await TraceElements.getTraceEngineElements(
|
|
390
|
+
traceEngineResult, navigationId);
|
|
323
391
|
const lcpNodeData = await TraceElements.getLcpElement(trace, context);
|
|
324
392
|
const shiftsData = await TraceElements.getTopLayoutShifts(
|
|
325
393
|
trace, traceEngineResult.data, rootCauses, context);
|
|
@@ -328,6 +396,7 @@ class TraceElements extends BaseGatherer {
|
|
|
328
396
|
|
|
329
397
|
/** @type {Map<string, TraceElementData[]>} */
|
|
330
398
|
const backendNodeDataMap = new Map([
|
|
399
|
+
['trace-engine', traceEngineData],
|
|
331
400
|
['largest-contentful-paint', lcpNodeData ? [lcpNodeData] : []],
|
|
332
401
|
['layout-shift', shiftsData],
|
|
333
402
|
['animation', animatedElementData],
|
|
@@ -336,6 +405,7 @@ class TraceElements extends BaseGatherer {
|
|
|
336
405
|
|
|
337
406
|
/** @type {Map<number, LH.Crdp.Runtime.CallFunctionOnResponse | null>} */
|
|
338
407
|
const callFunctionOnCache = new Map();
|
|
408
|
+
/** @type {LH.Artifacts.TraceElement[]} */
|
|
339
409
|
const traceElements = [];
|
|
340
410
|
for (const [traceEventType, backendNodeData] of backendNodeDataMap) {
|
|
341
411
|
for (let i = 0; i < backendNodeData.length; i++) {
|
|
@@ -348,8 +418,8 @@ class TraceElements extends BaseGatherer {
|
|
|
348
418
|
|
|
349
419
|
if (response?.result?.value) {
|
|
350
420
|
traceElements.push({
|
|
351
|
-
traceEventType,
|
|
352
421
|
...response.result.value,
|
|
422
|
+
traceEventType,
|
|
353
423
|
animations: backendNodeData[i].animations,
|
|
354
424
|
nodeId: backendNodeId,
|
|
355
425
|
type: backendNodeData[i].type,
|
package/core/runner.js
CHANGED
|
@@ -484,6 +484,7 @@ vs
|
|
|
484
484
|
'multi-check-audit.js',
|
|
485
485
|
'byte-efficiency/byte-efficiency-audit.js',
|
|
486
486
|
'manual/manual-audit.js',
|
|
487
|
+
'insights/insight-audit.js',
|
|
487
488
|
];
|
|
488
489
|
|
|
489
490
|
const fileList = [
|
|
@@ -499,6 +500,7 @@ vs
|
|
|
499
500
|
...fs.readdirSync(path.join(moduleDir, './audits/byte-efficiency'))
|
|
500
501
|
.map(f => `byte-efficiency/${f}`),
|
|
501
502
|
...fs.readdirSync(path.join(moduleDir, './audits/manual')).map(f => `manual/${f}`),
|
|
503
|
+
...fs.readdirSync(path.join(moduleDir, './audits/insights')).map(f => `insights/${f}`),
|
|
502
504
|
];
|
|
503
505
|
return fileList.filter(f => {
|
|
504
506
|
return /\.js$/.test(f) && !ignoredFiles.includes(f);
|