perfgraph 0.1.0
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/LICENSE +21 -0
- package/README.md +280 -0
- package/dist/causal/builder.d.ts +34 -0
- package/dist/causal/builder.d.ts.map +1 -0
- package/dist/causal/builder.js +132 -0
- package/dist/causal/builder.js.map +1 -0
- package/dist/causal/index.d.ts +11 -0
- package/dist/causal/index.d.ts.map +1 -0
- package/dist/causal/index.js +10 -0
- package/dist/causal/index.js.map +1 -0
- package/dist/causal/rules/js.d.ts +49 -0
- package/dist/causal/rules/js.d.ts.map +1 -0
- package/dist/causal/rules/js.js +209 -0
- package/dist/causal/rules/js.js.map +1 -0
- package/dist/causal/rules/layout.d.ts +39 -0
- package/dist/causal/rules/layout.d.ts.map +1 -0
- package/dist/causal/rules/layout.js +169 -0
- package/dist/causal/rules/layout.js.map +1 -0
- package/dist/causal/rules/lcp.d.ts +49 -0
- package/dist/causal/rules/lcp.d.ts.map +1 -0
- package/dist/causal/rules/lcp.js +250 -0
- package/dist/causal/rules/lcp.js.map +1 -0
- package/dist/causal/rules/network.d.ts +39 -0
- package/dist/causal/rules/network.d.ts.map +1 -0
- package/dist/causal/rules/network.js +140 -0
- package/dist/causal/rules/network.js.map +1 -0
- package/dist/causal/types.d.ts +142 -0
- package/dist/causal/types.d.ts.map +1 -0
- package/dist/causal/types.js +88 -0
- package/dist/causal/types.js.map +1 -0
- package/dist/cli/analyze.d.ts +33 -0
- package/dist/cli/analyze.d.ts.map +1 -0
- package/dist/cli/analyze.js +137 -0
- package/dist/cli/analyze.js.map +1 -0
- package/dist/cli/collect.d.ts +28 -0
- package/dist/cli/collect.d.ts.map +1 -0
- package/dist/cli/collect.js +125 -0
- package/dist/cli/collect.js.map +1 -0
- package/dist/cli/extract.d.ts +31 -0
- package/dist/cli/extract.d.ts.map +1 -0
- package/dist/cli/extract.js +135 -0
- package/dist/cli/extract.js.map +1 -0
- package/dist/cli/mcp.d.ts +14 -0
- package/dist/cli/mcp.d.ts.map +1 -0
- package/dist/cli/mcp.js +53 -0
- package/dist/cli/mcp.js.map +1 -0
- package/dist/cli/normalize.d.ts +58 -0
- package/dist/cli/normalize.d.ts.map +1 -0
- package/dist/cli/normalize.js +179 -0
- package/dist/cli/normalize.js.map +1 -0
- package/dist/cli/report.d.ts +33 -0
- package/dist/cli/report.d.ts.map +1 -0
- package/dist/cli/report.js +137 -0
- package/dist/cli/report.js.map +1 -0
- package/dist/cli/run.d.ts +49 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +243 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/collect/buffer-monitor.d.ts +25 -0
- package/dist/collect/buffer-monitor.d.ts.map +1 -0
- package/dist/collect/buffer-monitor.js +69 -0
- package/dist/collect/buffer-monitor.js.map +1 -0
- package/dist/collect/console.d.ts +25 -0
- package/dist/collect/console.d.ts.map +1 -0
- package/dist/collect/console.js +82 -0
- package/dist/collect/console.js.map +1 -0
- package/dist/collect/coverage.d.ts +26 -0
- package/dist/collect/coverage.d.ts.map +1 -0
- package/dist/collect/coverage.js +99 -0
- package/dist/collect/coverage.js.map +1 -0
- package/dist/collect/dom.d.ts +37 -0
- package/dist/collect/dom.d.ts.map +1 -0
- package/dist/collect/dom.js +118 -0
- package/dist/collect/dom.js.map +1 -0
- package/dist/collect/lighthouse.d.ts +41 -0
- package/dist/collect/lighthouse.d.ts.map +1 -0
- package/dist/collect/lighthouse.js +111 -0
- package/dist/collect/lighthouse.js.map +1 -0
- package/dist/collect/network.d.ts +32 -0
- package/dist/collect/network.d.ts.map +1 -0
- package/dist/collect/network.js +236 -0
- package/dist/collect/network.js.map +1 -0
- package/dist/collect/orchestrator.d.ts +23 -0
- package/dist/collect/orchestrator.d.ts.map +1 -0
- package/dist/collect/orchestrator.js +350 -0
- package/dist/collect/orchestrator.js.map +1 -0
- package/dist/collect/performance.d.ts +28 -0
- package/dist/collect/performance.d.ts.map +1 -0
- package/dist/collect/performance.js +108 -0
- package/dist/collect/performance.js.map +1 -0
- package/dist/collect/runtime.d.ts +26 -0
- package/dist/collect/runtime.d.ts.map +1 -0
- package/dist/collect/runtime.js +81 -0
- package/dist/collect/runtime.js.map +1 -0
- package/dist/collect/session.d.ts +58 -0
- package/dist/collect/session.d.ts.map +1 -0
- package/dist/collect/session.js +162 -0
- package/dist/collect/session.js.map +1 -0
- package/dist/collect/trace.d.ts +40 -0
- package/dist/collect/trace.d.ts.map +1 -0
- package/dist/collect/trace.js +127 -0
- package/dist/collect/trace.js.map +1 -0
- package/dist/collect/types.d.ts +317 -0
- package/dist/collect/types.d.ts.map +1 -0
- package/dist/collect/types.js +12 -0
- package/dist/collect/types.js.map +1 -0
- package/dist/distill/insights.d.ts +67 -0
- package/dist/distill/insights.d.ts.map +1 -0
- package/dist/distill/insights.js +317 -0
- package/dist/distill/insights.js.map +1 -0
- package/dist/distill/summaries.d.ts +71 -0
- package/dist/distill/summaries.d.ts.map +1 -0
- package/dist/distill/summaries.js +165 -0
- package/dist/distill/summaries.js.map +1 -0
- package/dist/extract/critical-path.d.ts +17 -0
- package/dist/extract/critical-path.d.ts.map +1 -0
- package/dist/extract/critical-path.js +95 -0
- package/dist/extract/critical-path.js.map +1 -0
- package/dist/extract/index.d.ts +16 -0
- package/dist/extract/index.d.ts.map +1 -0
- package/dist/extract/index.js +32 -0
- package/dist/extract/index.js.map +1 -0
- package/dist/extract/js-hotspots.d.ts +15 -0
- package/dist/extract/js-hotspots.d.ts.map +1 -0
- package/dist/extract/js-hotspots.js +22 -0
- package/dist/extract/js-hotspots.js.map +1 -0
- package/dist/extract/layout-shifts.d.ts +19 -0
- package/dist/extract/layout-shifts.d.ts.map +1 -0
- package/dist/extract/layout-shifts.js +47 -0
- package/dist/extract/layout-shifts.js.map +1 -0
- package/dist/extract/lcp-breakdown.d.ts +19 -0
- package/dist/extract/lcp-breakdown.d.ts.map +1 -0
- package/dist/extract/lcp-breakdown.js +110 -0
- package/dist/extract/lcp-breakdown.js.map +1 -0
- package/dist/extract/main-thread.d.ts +16 -0
- package/dist/extract/main-thread.d.ts.map +1 -0
- package/dist/extract/main-thread.js +41 -0
- package/dist/extract/main-thread.js.map +1 -0
- package/dist/extract/render-blocking.d.ts +16 -0
- package/dist/extract/render-blocking.d.ts.map +1 -0
- package/dist/extract/render-blocking.js +79 -0
- package/dist/extract/render-blocking.js.map +1 -0
- package/dist/extract/third-party.d.ts +15 -0
- package/dist/extract/third-party.d.ts.map +1 -0
- package/dist/extract/third-party.js +127 -0
- package/dist/extract/third-party.js.map +1 -0
- package/dist/extract/types.d.ts +183 -0
- package/dist/extract/types.d.ts.map +1 -0
- package/dist/extract/types.js +118 -0
- package/dist/extract/types.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +188 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/handlers.d.ts +72 -0
- package/dist/mcp/handlers.d.ts.map +1 -0
- package/dist/mcp/handlers.js +285 -0
- package/dist/mcp/handlers.js.map +1 -0
- package/dist/mcp/progress.d.ts +37 -0
- package/dist/mcp/progress.d.ts.map +1 -0
- package/dist/mcp/progress.js +51 -0
- package/dist/mcp/progress.js.map +1 -0
- package/dist/mcp/prompts.d.ts +57 -0
- package/dist/mcp/prompts.d.ts.map +1 -0
- package/dist/mcp/prompts.js +225 -0
- package/dist/mcp/prompts.js.map +1 -0
- package/dist/mcp/resources.d.ts +48 -0
- package/dist/mcp/resources.d.ts.map +1 -0
- package/dist/mcp/resources.js +149 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/server.d.ts +34 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +452 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/types.d.ts +47 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +67 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/normalize/clock.d.ts +40 -0
- package/dist/normalize/clock.d.ts.map +1 -0
- package/dist/normalize/clock.js +96 -0
- package/dist/normalize/clock.js.map +1 -0
- package/dist/normalize/dom-ir.d.ts +16 -0
- package/dist/normalize/dom-ir.d.ts.map +1 -0
- package/dist/normalize/dom-ir.js +48 -0
- package/dist/normalize/dom-ir.js.map +1 -0
- package/dist/normalize/index.d.ts +23 -0
- package/dist/normalize/index.d.ts.map +1 -0
- package/dist/normalize/index.js +118 -0
- package/dist/normalize/index.js.map +1 -0
- package/dist/normalize/lighthouse-insights.d.ts +27 -0
- package/dist/normalize/lighthouse-insights.d.ts.map +1 -0
- package/dist/normalize/lighthouse-insights.js +318 -0
- package/dist/normalize/lighthouse-insights.js.map +1 -0
- package/dist/normalize/lighthouse-ir.d.ts +25 -0
- package/dist/normalize/lighthouse-ir.d.ts.map +1 -0
- package/dist/normalize/lighthouse-ir.js +151 -0
- package/dist/normalize/lighthouse-ir.js.map +1 -0
- package/dist/normalize/network-ir.d.ts +23 -0
- package/dist/normalize/network-ir.d.ts.map +1 -0
- package/dist/normalize/network-ir.js +180 -0
- package/dist/normalize/network-ir.js.map +1 -0
- package/dist/normalize/runtime-ir.d.ts +18 -0
- package/dist/normalize/runtime-ir.d.ts.map +1 -0
- package/dist/normalize/runtime-ir.js +114 -0
- package/dist/normalize/runtime-ir.js.map +1 -0
- package/dist/normalize/trace-ir.d.ts +20 -0
- package/dist/normalize/trace-ir.d.ts.map +1 -0
- package/dist/normalize/trace-ir.js +224 -0
- package/dist/normalize/trace-ir.js.map +1 -0
- package/dist/normalize/types.d.ts +536 -0
- package/dist/normalize/types.d.ts.map +1 -0
- package/dist/normalize/types.js +242 -0
- package/dist/normalize/types.js.map +1 -0
- package/dist/output/manifest.d.ts +44 -0
- package/dist/output/manifest.d.ts.map +1 -0
- package/dist/output/manifest.js +232 -0
- package/dist/output/manifest.js.map +1 -0
- package/dist/output/toon.d.ts +19 -0
- package/dist/output/toon.d.ts.map +1 -0
- package/dist/output/toon.js +22 -0
- package/dist/output/toon.js.map +1 -0
- package/dist/output/writer.d.ts +31 -0
- package/dist/output/writer.d.ts.map +1 -0
- package/dist/output/writer.js +51 -0
- package/dist/output/writer.js.map +1 -0
- package/dist/report/analyzer.d.ts +29 -0
- package/dist/report/analyzer.d.ts.map +1 -0
- package/dist/report/analyzer.js +330 -0
- package/dist/report/analyzer.js.map +1 -0
- package/dist/report/index.d.ts +13 -0
- package/dist/report/index.d.ts.map +1 -0
- package/dist/report/index.js +12 -0
- package/dist/report/index.js.map +1 -0
- package/dist/report/markdown.d.ts +21 -0
- package/dist/report/markdown.d.ts.map +1 -0
- package/dist/report/markdown.js +182 -0
- package/dist/report/markdown.js.map +1 -0
- package/dist/report/remediations.d.ts +42 -0
- package/dist/report/remediations.d.ts.map +1 -0
- package/dist/report/remediations.js +179 -0
- package/dist/report/remediations.js.map +1 -0
- package/dist/report/scorer.d.ts +35 -0
- package/dist/report/scorer.d.ts.map +1 -0
- package/dist/report/scorer.js +72 -0
- package/dist/report/scorer.js.map +1 -0
- package/dist/report/types.d.ts +201 -0
- package/dist/report/types.d.ts.map +1 -0
- package/dist/report/types.js +149 -0
- package/dist/report/types.js.map +1 -0
- package/dist/shared/fs-utils.d.ts +12 -0
- package/dist/shared/fs-utils.d.ts.map +1 -0
- package/dist/shared/fs-utils.js +44 -0
- package/dist/shared/fs-utils.js.map +1 -0
- package/dist/shared/types.d.ts +69 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +18 -0
- package/dist/shared/types.js.map +1 -0
- package/dist/shared/utils.d.ts +6 -0
- package/dist/shared/utils.d.ts.map +1 -0
- package/dist/shared/utils.js +9 -0
- package/dist/shared/utils.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent-optimized summary layer that fuses Lighthouse insights,
|
|
3
|
+
* extracted features, and evidence data into a compact Insights structure.
|
|
4
|
+
*
|
|
5
|
+
* The result can be serialized to `insights.toon` (~5-15 KB for a typical SPA).
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
import { buildLighthouseInsights } from '../normalize/lighthouse-insights.js';
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Helpers
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
function isRecord(value) {
|
|
14
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
15
|
+
}
|
|
16
|
+
function safeNumber(value) {
|
|
17
|
+
return typeof value === 'number' ? value : undefined;
|
|
18
|
+
}
|
|
19
|
+
/** Navigate to the LHR root — handles { lhr: {...} } wrapper used by LighthouseRawData. */
|
|
20
|
+
function getLHRRoot(raw) {
|
|
21
|
+
if (!isRecord(raw))
|
|
22
|
+
return {};
|
|
23
|
+
if (isRecord(raw.lhr))
|
|
24
|
+
return raw.lhr;
|
|
25
|
+
return raw;
|
|
26
|
+
}
|
|
27
|
+
/** Extract numericValue from a Lighthouse audit by ID. */
|
|
28
|
+
function getAuditNumericValue(lhr, auditId) {
|
|
29
|
+
const audits = isRecord(lhr.audits) ? lhr.audits : {};
|
|
30
|
+
const audit = isRecord(audits[auditId])
|
|
31
|
+
? audits[auditId]
|
|
32
|
+
: undefined;
|
|
33
|
+
return safeNumber(audit?.numericValue);
|
|
34
|
+
}
|
|
35
|
+
/** Extract category scores from Lighthouse. */
|
|
36
|
+
function extractScores(raw) {
|
|
37
|
+
const lhr = getLHRRoot(raw);
|
|
38
|
+
const categories = isRecord(lhr.categories) ? lhr.categories : {};
|
|
39
|
+
const getScore = (name) => {
|
|
40
|
+
const cat = categories[name];
|
|
41
|
+
return isRecord(cat) ? safeNumber(cat.score) : undefined;
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
performance: getScore('performance'),
|
|
45
|
+
accessibility: getScore('accessibility'),
|
|
46
|
+
bestPractices: getScore('best-practices'),
|
|
47
|
+
seo: getScore('seo'),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// Build helpers
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
/** Build lcpElement from Lighthouse insights + features. */
|
|
54
|
+
function buildLcpElement(insights, features) {
|
|
55
|
+
const lb = insights.lcpBreakdown;
|
|
56
|
+
if (!lb)
|
|
57
|
+
return undefined;
|
|
58
|
+
return {
|
|
59
|
+
selector: lb.lcpElementSelector ?? '',
|
|
60
|
+
snippet: lb.lcpElementSnippet,
|
|
61
|
+
nodeLabel: lb.lcpElementNodeLabel,
|
|
62
|
+
renderDelayMs: lb.elementRenderDelay,
|
|
63
|
+
resourceLoadDelayMs: features.lcpBreakdown?.resourceLoadDelay,
|
|
64
|
+
resourceLoadTimeMs: features.lcpBreakdown?.resourceLoadTime,
|
|
65
|
+
ttfbMs: lb.timeToFirstByte,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** Build renderBlocking array from Lighthouse insights. */
|
|
69
|
+
function buildRenderBlocking(insights) {
|
|
70
|
+
const rb = insights.renderBlocking;
|
|
71
|
+
if (!rb || !rb.resources)
|
|
72
|
+
return [];
|
|
73
|
+
return rb.resources.map((r) => ({
|
|
74
|
+
url: r.url,
|
|
75
|
+
bytes: r.totalBytes,
|
|
76
|
+
wastedMs: r.wastedMs,
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
/** Convert a NetworkChainNode to a CriticalPathNode. */
|
|
80
|
+
function convertChainNode(node) {
|
|
81
|
+
const result = {
|
|
82
|
+
url: node.url,
|
|
83
|
+
durationMs: node.navStartToEndTime,
|
|
84
|
+
};
|
|
85
|
+
if (node.children) {
|
|
86
|
+
const children = Object.values(node.children).map(convertChainNode);
|
|
87
|
+
if (children.length > 0) {
|
|
88
|
+
result.children = children;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
/** Build criticalPath from features + Lighthouse insights. */
|
|
94
|
+
function buildCriticalPath(features, insights) {
|
|
95
|
+
const cp = features.criticalPath;
|
|
96
|
+
const ndt = insights.networkDependencyTree;
|
|
97
|
+
if (!cp && !ndt)
|
|
98
|
+
return undefined;
|
|
99
|
+
let tree;
|
|
100
|
+
if (ndt?.chains) {
|
|
101
|
+
const entries = Object.values(ndt.chains);
|
|
102
|
+
if (entries.length > 0) {
|
|
103
|
+
tree = convertChainNode(entries[0]);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
depth: cp?.deepestChainDepth ?? 0,
|
|
108
|
+
longestChainMs: ndt?.longestChainDuration ?? cp?.longestSingleRequest,
|
|
109
|
+
tree,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/** Collect warnings from multiple sources. */
|
|
113
|
+
function buildWarnings(lighthouseJson) {
|
|
114
|
+
const warnings = [];
|
|
115
|
+
// From LighthouseRawData.warnings (collection-level warnings)
|
|
116
|
+
const raw = lighthouseJson;
|
|
117
|
+
if (Array.isArray(raw.warnings)) {
|
|
118
|
+
for (const w of raw.warnings) {
|
|
119
|
+
if (typeof w === 'string')
|
|
120
|
+
warnings.push(w);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// From LHR runtime warnings
|
|
124
|
+
const lhr = getLHRRoot(lighthouseJson);
|
|
125
|
+
if (Array.isArray(lhr.warnings)) {
|
|
126
|
+
for (const w of lhr.warnings) {
|
|
127
|
+
if (typeof w === 'string')
|
|
128
|
+
warnings.push(w);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return warnings;
|
|
132
|
+
}
|
|
133
|
+
function buildRecommendations(input) {
|
|
134
|
+
const recs = [];
|
|
135
|
+
// Critical: LCP > 4000ms
|
|
136
|
+
if (input.lcpMs !== undefined && input.lcpMs > 4000) {
|
|
137
|
+
recs.push({
|
|
138
|
+
priority: 'critical',
|
|
139
|
+
title: 'Optimize Largest Contentful Paint',
|
|
140
|
+
action: 'Reduce LCP by optimizing server response time, eliminating render-blocking resources, and optimizing images.',
|
|
141
|
+
evidence: [`LCP: ${input.lcpMs}ms`],
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
// Critical: TBT > 600ms
|
|
145
|
+
if (input.tbtMs !== undefined && input.tbtMs > 600) {
|
|
146
|
+
recs.push({
|
|
147
|
+
priority: 'critical',
|
|
148
|
+
title: 'Reduce Total Blocking Time',
|
|
149
|
+
action: 'Break up long tasks, reduce JavaScript execution time, and consider code splitting.',
|
|
150
|
+
evidence: [`TBT: ${input.tbtMs}ms`],
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Critical: CLS > 0.25
|
|
154
|
+
if (input.cls !== undefined && input.cls > 0.25) {
|
|
155
|
+
recs.push({
|
|
156
|
+
priority: 'critical',
|
|
157
|
+
title: 'Reduce Cumulative Layout Shift',
|
|
158
|
+
action: 'Set explicit dimensions on images and embeds, avoid inserting content above existing content.',
|
|
159
|
+
evidence: [`CLS: ${input.cls}`],
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// High: LCP > 2500ms (not already critical)
|
|
163
|
+
if (input.lcpMs !== undefined &&
|
|
164
|
+
input.lcpMs > 2500 &&
|
|
165
|
+
input.lcpMs <= 4000) {
|
|
166
|
+
recs.push({
|
|
167
|
+
priority: 'high',
|
|
168
|
+
title: 'Improve LCP to meet 2.5s threshold',
|
|
169
|
+
action: 'Optimize server response time (TTFB), preload key resources, and optimize the LCP element.',
|
|
170
|
+
evidence: [`LCP: ${input.lcpMs}ms`],
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
// High: render blocking resources exist
|
|
174
|
+
if (input.renderBlocking.length > 0) {
|
|
175
|
+
const totalWasted = input.renderBlocking.reduce((s, r) => s + (r.wastedMs ?? 0), 0);
|
|
176
|
+
const evidence = [
|
|
177
|
+
`${input.renderBlocking.length} render-blocking resources`,
|
|
178
|
+
];
|
|
179
|
+
if (totalWasted > 0) {
|
|
180
|
+
evidence.push(`Potential savings: ${totalWasted}ms`);
|
|
181
|
+
}
|
|
182
|
+
recs.push({
|
|
183
|
+
priority: 'high',
|
|
184
|
+
title: 'Reduce render-blocking resources',
|
|
185
|
+
action: 'Defer non-critical CSS and JavaScript, inline critical styles, and use preload for key resources.',
|
|
186
|
+
evidence,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
// High: deep critical chain
|
|
190
|
+
if (input.criticalPath && input.criticalPath.depth > 5) {
|
|
191
|
+
recs.push({
|
|
192
|
+
priority: 'high',
|
|
193
|
+
title: 'Optimize critical request chain',
|
|
194
|
+
action: 'Reduce sequential network requests by inlining critical resources, using HTTP/2, and preloading key assets.',
|
|
195
|
+
evidence: [`Critical chain depth: ${input.criticalPath.depth}`],
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
// Medium: high FCP
|
|
199
|
+
if (input.fcpMs !== undefined && input.fcpMs > 3000) {
|
|
200
|
+
recs.push({
|
|
201
|
+
priority: 'medium',
|
|
202
|
+
title: 'Improve First Contentful Paint',
|
|
203
|
+
action: 'Reduce server response time and eliminate render-blocking resources above the fold.',
|
|
204
|
+
evidence: [`FCP: ${input.fcpMs}ms`],
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
// Medium: third-party overhead
|
|
208
|
+
const tp = input.features.thirdPartyOverhead;
|
|
209
|
+
if (tp && tp.thirdPartyRatio > 0.3) {
|
|
210
|
+
recs.push({
|
|
211
|
+
priority: 'medium',
|
|
212
|
+
title: 'Reduce third-party code overhead',
|
|
213
|
+
action: 'Audit third-party scripts for necessity, defer non-critical ones, use async loading.',
|
|
214
|
+
evidence: [
|
|
215
|
+
`Third-party ratio: ${(tp.thirdPartyRatio * 100).toFixed(1)}%`,
|
|
216
|
+
],
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
// Medium: many long tasks
|
|
220
|
+
const js = input.features.jsHotspots;
|
|
221
|
+
if (js && js.longTaskCount > 10) {
|
|
222
|
+
recs.push({
|
|
223
|
+
priority: 'medium',
|
|
224
|
+
title: 'Reduce JavaScript long tasks',
|
|
225
|
+
action: 'Break up JavaScript execution into smaller chunks, use requestIdleCallback, consider web workers.',
|
|
226
|
+
evidence: [`${js.longTaskCount} long tasks detected`],
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
return recs;
|
|
230
|
+
}
|
|
231
|
+
// ---------------------------------------------------------------------------
|
|
232
|
+
// Public API
|
|
233
|
+
// ---------------------------------------------------------------------------
|
|
234
|
+
/**
|
|
235
|
+
* Build a compact Insights structure from extracted features and raw
|
|
236
|
+
* Lighthouse data.
|
|
237
|
+
*
|
|
238
|
+
* The result is designed to be serialized as `insights.toon` (~5-15 KB)
|
|
239
|
+
* and consumed by AI agents for quick performance diagnosis.
|
|
240
|
+
*
|
|
241
|
+
* @param features - Extracted feature set from `extract()`
|
|
242
|
+
* @param lighthouseJson - Raw Lighthouse JSON (LighthouseRawData or plain LHR)
|
|
243
|
+
* @returns A compact Insights structure
|
|
244
|
+
*/
|
|
245
|
+
export function buildInsights(features, lighthouseJson) {
|
|
246
|
+
// 1. Parse Lighthouse insight audits
|
|
247
|
+
const lighthouseInsights = buildLighthouseInsights(lighthouseJson);
|
|
248
|
+
// 2. Lighthouse scores block
|
|
249
|
+
const scores = extractScores(lighthouseJson);
|
|
250
|
+
// 3. Navigate to LHR audit container
|
|
251
|
+
const lhr = getLHRRoot(lighthouseJson);
|
|
252
|
+
// 4. Metrics from Lighthouse audits (fallback chain)
|
|
253
|
+
const lcpAuditMs = getAuditNumericValue(lhr, 'largest-contentful-paint');
|
|
254
|
+
const fcpMs = getAuditNumericValue(lhr, 'first-contentful-paint');
|
|
255
|
+
const clsAudit = getAuditNumericValue(lhr, 'cumulative-layout-shift');
|
|
256
|
+
const tbtAudit = getAuditNumericValue(lhr, 'total-blocking-time');
|
|
257
|
+
// LCP: prefer FeatureSet breakdown total, then Lighthouse insight
|
|
258
|
+
// composite, then raw audit
|
|
259
|
+
const lcpMs = features.lcpBreakdown?.totalLCP ??
|
|
260
|
+
(lighthouseInsights.lcpBreakdown
|
|
261
|
+
? lighthouseInsights.lcpBreakdown.timeToFirstByte +
|
|
262
|
+
lighthouseInsights.lcpBreakdown.elementRenderDelay
|
|
263
|
+
: undefined) ??
|
|
264
|
+
lcpAuditMs;
|
|
265
|
+
// CLS: prefer FeatureSet, then raw audit
|
|
266
|
+
const cls = features.layoutShifts?.cls ?? clsAudit;
|
|
267
|
+
// TBT: prefer Lighthouse audit (the real TBT metric) when it's sane,
|
|
268
|
+
// otherwise use FeatureSet busyMs, or undefined if both are absurd.
|
|
269
|
+
// In headless/automated environments Lighthouse TBT can be wildly inflated
|
|
270
|
+
// (e.g. 151s) due to CDP overhead or browser throttling — we cap at 60s
|
|
271
|
+
// and fall back to busyMs as a best-effort proxy.
|
|
272
|
+
const TBT_SANE_MAX = 60_000; // 60 seconds — anything above is an artifact
|
|
273
|
+
const tbtMs = tbtAudit !== undefined && tbtAudit >= 0 && tbtAudit <= TBT_SANE_MAX
|
|
274
|
+
? tbtAudit
|
|
275
|
+
: features.mainThreadBlocking?.busyMs !== undefined &&
|
|
276
|
+
features.mainThreadBlocking?.busyMs <= TBT_SANE_MAX
|
|
277
|
+
? features.mainThreadBlocking?.busyMs
|
|
278
|
+
: undefined;
|
|
279
|
+
// 5. LCP element
|
|
280
|
+
const lcpElement = buildLcpElement(lighthouseInsights, features);
|
|
281
|
+
// 6. Render-blocking resources
|
|
282
|
+
const renderBlocking = buildRenderBlocking(lighthouseInsights);
|
|
283
|
+
// 7. Critical path
|
|
284
|
+
const criticalPath = buildCriticalPath(features, lighthouseInsights);
|
|
285
|
+
// 8. Warnings
|
|
286
|
+
const warnings = buildWarnings(lighthouseJson);
|
|
287
|
+
// 9. Data-driven recommendations
|
|
288
|
+
const topRecommendations = buildRecommendations({
|
|
289
|
+
lcpMs,
|
|
290
|
+
fcpMs,
|
|
291
|
+
cls,
|
|
292
|
+
tbtMs,
|
|
293
|
+
renderBlocking,
|
|
294
|
+
criticalPath,
|
|
295
|
+
features,
|
|
296
|
+
});
|
|
297
|
+
return {
|
|
298
|
+
url: features.url ?? '',
|
|
299
|
+
analyzedAt: new Date().toISOString(),
|
|
300
|
+
lighthouse: {
|
|
301
|
+
performance: scores.performance,
|
|
302
|
+
accessibility: scores.accessibility,
|
|
303
|
+
bestPractices: scores.bestPractices,
|
|
304
|
+
seo: scores.seo,
|
|
305
|
+
lcpMs,
|
|
306
|
+
fcpMs,
|
|
307
|
+
cls,
|
|
308
|
+
tbtMs,
|
|
309
|
+
},
|
|
310
|
+
lcpElement,
|
|
311
|
+
renderBlocking,
|
|
312
|
+
criticalPath,
|
|
313
|
+
warnings,
|
|
314
|
+
topRecommendations,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=insights.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insights.js","sourceRoot":"","sources":["../../src/distill/insights.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact summary builders for large raw data files.
|
|
3
|
+
*
|
|
4
|
+
* Each function takes a raw data structure (network.json, lighthouse.json,
|
|
5
|
+
* coverage.json) and returns a small summary object that can be written
|
|
6
|
+
* as a companion file (~1-5 KB) for agent consumption.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
import type { NetworkRawData, LighthouseRawData, CoverageRawData } from '../collect/types.js';
|
|
11
|
+
export interface NetworkSummary {
|
|
12
|
+
totalRequests: number;
|
|
13
|
+
totalBytes: number;
|
|
14
|
+
topRequestsByDuration: Array<{
|
|
15
|
+
url: string;
|
|
16
|
+
duration: number;
|
|
17
|
+
resourceType: string;
|
|
18
|
+
bytes: number;
|
|
19
|
+
}>;
|
|
20
|
+
blockingResources: Array<{
|
|
21
|
+
url: string;
|
|
22
|
+
resourceType: string;
|
|
23
|
+
}>;
|
|
24
|
+
initiatorChains: Array<{
|
|
25
|
+
url: string;
|
|
26
|
+
depth: number;
|
|
27
|
+
}>;
|
|
28
|
+
}
|
|
29
|
+
export interface LighthouseSummary {
|
|
30
|
+
categories: Record<string, number>;
|
|
31
|
+
failedInsightAudits: Array<{
|
|
32
|
+
id: string;
|
|
33
|
+
title: string;
|
|
34
|
+
score: number;
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
37
|
+
export interface CoverageSummary {
|
|
38
|
+
unusedBytesByUrl: Array<{
|
|
39
|
+
url: string;
|
|
40
|
+
totalBytes: number;
|
|
41
|
+
unusedBytes: number;
|
|
42
|
+
unusedPercentage: number;
|
|
43
|
+
}>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Build a compact summary of network request data.
|
|
47
|
+
*
|
|
48
|
+
* @param network - Raw network data from NetworkCollector
|
|
49
|
+
* @returns A compact NetworkSummary (~1-3 KB)
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildNetworkSummary(network: NetworkRawData): NetworkSummary;
|
|
52
|
+
/**
|
|
53
|
+
* Build a compact summary of Lighthouse audit results.
|
|
54
|
+
*
|
|
55
|
+
* @param lighthouse - Raw Lighthouse data from LighthouseCollector
|
|
56
|
+
* @returns A compact LighthouseSummary (~1-2 KB)
|
|
57
|
+
*/
|
|
58
|
+
export declare function buildLighthouseSummary(lighthouse: LighthouseRawData): LighthouseSummary;
|
|
59
|
+
/**
|
|
60
|
+
* Build a compact summary of JS/CSS code coverage data.
|
|
61
|
+
*
|
|
62
|
+
* Coverage data from CDP does not include the full script source, so
|
|
63
|
+
* `totalBytes` is approximated as the maximum `endOffset` across all
|
|
64
|
+
* coverage ranges. This gives a lower-bound estimate of the script size;
|
|
65
|
+
* truly uncovered code that falls outside any range is not counted.
|
|
66
|
+
*
|
|
67
|
+
* @param coverage - Raw coverage data from CoverageCollector
|
|
68
|
+
* @returns A compact CoverageSummary (~1-3 KB)
|
|
69
|
+
*/
|
|
70
|
+
export declare function buildCoverageSummary(coverage: CoverageRawData): CoverageSummary;
|
|
71
|
+
//# sourceMappingURL=summaries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summaries.d.ts","sourceRoot":"","sources":["../../src/distill/summaries.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,eAAe,EAEhB,MAAM,qBAAqB,CAAC;AAM7B,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB,EAAE,KAAK,CAAC;QAC3B,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;IACH,iBAAiB,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChE,eAAe,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxD;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,mBAAmB,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,KAAK,CAAC;QACtB,GAAG,EAAE,MAAM,CAAC;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC,CAAC;CACJ;AAyCD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,CAgC3E;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,iBAAiB,GAC5B,iBAAiB,CA8BnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,eAAe,GACxB,eAAe,CA6DjB"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact summary builders for large raw data files.
|
|
3
|
+
*
|
|
4
|
+
* Each function takes a raw data structure (network.json, lighthouse.json,
|
|
5
|
+
* coverage.json) and returns a small summary object that can be written
|
|
6
|
+
* as a companion file (~1-5 KB) for agent consumption.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Helpers
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
function isRecord(value) {
|
|
14
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Merge overlapping CoverageRange[] so that intersecting spans are
|
|
18
|
+
* counted once. Returns a new sorted, non-overlapping array.
|
|
19
|
+
*/
|
|
20
|
+
function mergeRanges(ranges) {
|
|
21
|
+
if (ranges.length === 0)
|
|
22
|
+
return [];
|
|
23
|
+
const sorted = [...ranges].sort((a, b) => a.startOffset - b.startOffset);
|
|
24
|
+
const merged = [{ ...sorted[0] }];
|
|
25
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
26
|
+
const last = merged[merged.length - 1];
|
|
27
|
+
const current = sorted[i];
|
|
28
|
+
if (current.startOffset <= last.endOffset) {
|
|
29
|
+
// Extend last range if current ends further
|
|
30
|
+
if (current.endOffset > last.endOffset) {
|
|
31
|
+
last.endOffset = current.endOffset;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
merged.push({ ...current });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return merged;
|
|
39
|
+
}
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Summary builders
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
/**
|
|
44
|
+
* Build a compact summary of network request data.
|
|
45
|
+
*
|
|
46
|
+
* @param network - Raw network data from NetworkCollector
|
|
47
|
+
* @returns A compact NetworkSummary (~1-3 KB)
|
|
48
|
+
*/
|
|
49
|
+
export function buildNetworkSummary(network) {
|
|
50
|
+
const requests = network.requests ?? [];
|
|
51
|
+
// Sort by response receive time descending (longest first)
|
|
52
|
+
const sorted = [...requests].sort((a, b) => {
|
|
53
|
+
const durA = a.response?.timing?.receiveHeadersEnd ?? 0;
|
|
54
|
+
const durB = b.response?.timing?.receiveHeadersEnd ?? 0;
|
|
55
|
+
return durB - durA;
|
|
56
|
+
});
|
|
57
|
+
return {
|
|
58
|
+
totalRequests: requests.length,
|
|
59
|
+
totalBytes: requests.reduce((s, r) => s + (r.response?.encodedDataLength ?? 0), 0),
|
|
60
|
+
topRequestsByDuration: sorted.slice(0, 20).map((r) => ({
|
|
61
|
+
url: r.url,
|
|
62
|
+
duration: r.response?.timing?.receiveHeadersEnd ?? 0,
|
|
63
|
+
resourceType: r.type ?? 'unknown',
|
|
64
|
+
bytes: r.response?.encodedDataLength ?? 0,
|
|
65
|
+
})),
|
|
66
|
+
blockingResources: requests
|
|
67
|
+
.filter((r) => r.type === 'Stylesheet' || r.type === 'Script')
|
|
68
|
+
.map((r) => ({
|
|
69
|
+
url: r.url,
|
|
70
|
+
resourceType: r.type ?? 'unknown',
|
|
71
|
+
})),
|
|
72
|
+
initiatorChains: [], // Placeholder — real initiator chain data from IR
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Build a compact summary of Lighthouse audit results.
|
|
77
|
+
*
|
|
78
|
+
* @param lighthouse - Raw Lighthouse data from LighthouseCollector
|
|
79
|
+
* @returns A compact LighthouseSummary (~1-2 KB)
|
|
80
|
+
*/
|
|
81
|
+
export function buildLighthouseSummary(lighthouse) {
|
|
82
|
+
const lhr = isRecord(lighthouse.lhr) ? lighthouse.lhr : {};
|
|
83
|
+
// Extract category scores
|
|
84
|
+
const categories = {};
|
|
85
|
+
const catObj = isRecord(lhr.categories) ? lhr.categories : {};
|
|
86
|
+
for (const [id, cat] of Object.entries(catObj)) {
|
|
87
|
+
if (isRecord(cat) && typeof cat.score === 'number') {
|
|
88
|
+
categories[id] = cat.score;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Extract failed insight audits (score < 0.5)
|
|
92
|
+
const failedInsightAudits = [];
|
|
93
|
+
const auditsObj = isRecord(lhr.audits) ? lhr.audits : {};
|
|
94
|
+
for (const [id, audit] of Object.entries(auditsObj)) {
|
|
95
|
+
if (isRecord(audit) &&
|
|
96
|
+
typeof audit.score === 'number' &&
|
|
97
|
+
audit.score < 0.5) {
|
|
98
|
+
failedInsightAudits.push({
|
|
99
|
+
id,
|
|
100
|
+
title: typeof audit.title === 'string' ? audit.title : id,
|
|
101
|
+
score: audit.score,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return { categories, failedInsightAudits };
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Build a compact summary of JS/CSS code coverage data.
|
|
109
|
+
*
|
|
110
|
+
* Coverage data from CDP does not include the full script source, so
|
|
111
|
+
* `totalBytes` is approximated as the maximum `endOffset` across all
|
|
112
|
+
* coverage ranges. This gives a lower-bound estimate of the script size;
|
|
113
|
+
* truly uncovered code that falls outside any range is not counted.
|
|
114
|
+
*
|
|
115
|
+
* @param coverage - Raw coverage data from CoverageCollector
|
|
116
|
+
* @returns A compact CoverageSummary (~1-3 KB)
|
|
117
|
+
*/
|
|
118
|
+
export function buildCoverageSummary(coverage) {
|
|
119
|
+
const entries = [];
|
|
120
|
+
// ---- JS scripts ----
|
|
121
|
+
for (const script of coverage.js ?? []) {
|
|
122
|
+
const allRanges = [];
|
|
123
|
+
for (const fn of script.functions ?? []) {
|
|
124
|
+
for (const range of fn.ranges ?? []) {
|
|
125
|
+
allRanges.push(range);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (allRanges.length === 0)
|
|
129
|
+
continue;
|
|
130
|
+
const merged = mergeRanges(allRanges);
|
|
131
|
+
const totalBytes = merged[merged.length - 1].endOffset;
|
|
132
|
+
const usedBytes = merged.reduce((sum, r) => sum + (r.endOffset - r.startOffset), 0);
|
|
133
|
+
const unusedBytes = Math.max(0, totalBytes - usedBytes);
|
|
134
|
+
entries.push({
|
|
135
|
+
url: script.url || '(inline)',
|
|
136
|
+
totalBytes,
|
|
137
|
+
unusedBytes,
|
|
138
|
+
unusedPercentage: totalBytes > 0
|
|
139
|
+
? Math.round((unusedBytes / totalBytes) * 100)
|
|
140
|
+
: 0,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
// ---- CSS stylesheets ----
|
|
144
|
+
for (const sheet of coverage.css ?? []) {
|
|
145
|
+
const ranges = sheet.ranges ?? [];
|
|
146
|
+
if (ranges.length === 0)
|
|
147
|
+
continue;
|
|
148
|
+
const merged = mergeRanges(ranges);
|
|
149
|
+
const totalBytes = merged[merged.length - 1].endOffset;
|
|
150
|
+
const usedBytes = merged.reduce((sum, r) => sum + (r.endOffset - r.startOffset), 0);
|
|
151
|
+
const unusedBytes = Math.max(0, totalBytes - usedBytes);
|
|
152
|
+
entries.push({
|
|
153
|
+
url: sheet.url || '(inline)',
|
|
154
|
+
totalBytes,
|
|
155
|
+
unusedBytes,
|
|
156
|
+
unusedPercentage: totalBytes > 0
|
|
157
|
+
? Math.round((unusedBytes / totalBytes) * 100)
|
|
158
|
+
: 0,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// Sort by unused bytes descending, take top 10
|
|
162
|
+
entries.sort((a, b) => b.unusedBytes - a.unusedBytes);
|
|
163
|
+
return { unusedBytesByUrl: entries.slice(0, 10) };
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=summaries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summaries.js","sourceRoot":"","sources":["../../src/distill/summaries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Critical Path Length extractor.
|
|
3
|
+
*
|
|
4
|
+
* Computes metrics from the critical path chain derived in the Network IR:
|
|
5
|
+
* total chain length (duration sum), request counts, depth, and longest
|
|
6
|
+
* single request.
|
|
7
|
+
*/
|
|
8
|
+
import type { IRBundle } from '../normalize/types.js';
|
|
9
|
+
import type { CriticalPath } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Extract critical path metrics from an IRBundle.
|
|
12
|
+
*
|
|
13
|
+
* Returns undefined when the critical path info is empty or none of its
|
|
14
|
+
* tree URLs can be matched to a network request.
|
|
15
|
+
*/
|
|
16
|
+
export declare function extractCriticalPath(ir: IRBundle): CriticalPath | undefined;
|
|
17
|
+
//# sourceMappingURL=critical-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"critical-path.d.ts","sourceRoot":"","sources":["../../src/extract/critical-path.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAA2C,MAAM,uBAAuB,CAAC;AAC/F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA2E/C;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,GAAG,YAAY,GAAG,SAAS,CA2B1E"}
|