0
# Performance Metrics
1
2
Plugin and server performance monitoring with detailed timing and invocation data for optimizing Vite build performance.
3
4
## Capabilities
5
6
### Plugin Performance Metrics
7
8
Detailed performance metrics for individual plugins including invocation counts and timing data.
9
10
```typescript { .api }
11
interface PluginMetricInfo {
12
/** Plugin name */
13
name: string;
14
/** Plugin enforcement mode ('pre' | 'post' | undefined) */
15
enforce?: string;
16
/** Transform hook performance metrics */
17
transform: {
18
/** Number of times transform hook was called */
19
invokeCount: number;
20
/** Total time spent in transform hook (milliseconds) */
21
totalTime: number;
22
};
23
/** ResolveId hook performance metrics */
24
resolveId: {
25
/** Number of times resolveId hook was called */
26
invokeCount: number;
27
/** Total time spent in resolveId hook (milliseconds) */
28
totalTime: number;
29
};
30
}
31
```
32
33
**Usage Example:**
34
35
```typescript
36
// Get plugin performance metrics
37
const metrics = await rpc.getPluginMetrics({ vite: 'instance-id', env: 'client' });
38
39
// Find slowest plugins
40
const slowestPlugins = metrics
41
.sort((a, b) => (b.transform.totalTime + b.resolveId.totalTime) - (a.transform.totalTime + a.resolveId.totalTime))
42
.slice(0, 5);
43
44
console.log('Top 5 slowest plugins:');
45
slowestPlugins.forEach((plugin, index) => {
46
const totalTime = plugin.transform.totalTime + plugin.resolveId.totalTime;
47
const totalInvocations = plugin.transform.invokeCount + plugin.resolveId.invokeCount;
48
const avgTime = totalTime / totalInvocations;
49
50
console.log(`${index + 1}. ${plugin.name}`);
51
console.log(` Total time: ${totalTime}ms`);
52
console.log(` Invocations: ${totalInvocations}`);
53
console.log(` Avg per call: ${avgTime.toFixed(2)}ms`);
54
});
55
```
56
57
### Server Middleware Metrics
58
59
Performance metrics for server middleware with timing breakdown and call hierarchy.
60
61
```typescript { .api }
62
interface ServerMetrics {
63
/** Middleware performance data organized by request URL */
64
middleware?: Record<string, { name: string; self: number; total: number; }[]>;
65
}
66
```
67
68
**Usage Example:**
69
70
```typescript
71
// Get server middleware metrics
72
const serverMetrics = await rpc.getServerMetrics({ vite: 'instance-id', env: 'client' });
73
74
if (serverMetrics.middleware) {
75
Object.entries(serverMetrics.middleware).forEach(([url, metrics]) => {
76
console.log(`Request: ${url}`);
77
78
metrics.forEach((metric, index) => {
79
const indent = ' '.repeat(index);
80
console.log(`${indent}${metric.name}: ${metric.self}ms (${metric.total}ms total)`);
81
});
82
83
const totalTime = metrics[metrics.length - 1]?.total || 0;
84
console.log(`Total request time: ${totalTime}ms\n`);
85
});
86
}
87
```
88
89
### Performance Analysis Helpers
90
91
Utility functions for analyzing performance data:
92
93
```typescript
94
// Analyze plugin efficiency
95
function analyzePluginEfficiency(metrics: PluginMetricInfo[]) {
96
return metrics.map(plugin => {
97
const transform = plugin.transform;
98
const resolveId = plugin.resolveId;
99
100
return {
101
name: plugin.name,
102
enforce: plugin.enforce,
103
efficiency: {
104
transformAvg: transform.invokeCount > 0 ? transform.totalTime / transform.invokeCount : 0,
105
resolveIdAvg: resolveId.invokeCount > 0 ? resolveId.totalTime / resolveId.invokeCount : 0,
106
totalTime: transform.totalTime + resolveId.totalTime,
107
totalCalls: transform.invokeCount + resolveId.invokeCount
108
}
109
};
110
}).sort((a, b) => b.efficiency.totalTime - a.efficiency.totalTime);
111
}
112
113
// Find bottlenecks
114
function findBottlenecks(metrics: PluginMetricInfo[], threshold: number = 100) {
115
return metrics.filter(plugin => {
116
const totalTime = plugin.transform.totalTime + plugin.resolveId.totalTime;
117
return totalTime > threshold;
118
});
119
}
120
121
// Usage
122
const efficiency = analyzePluginEfficiency(metrics);
123
const bottlenecks = findBottlenecks(metrics, 50); // Plugins taking >50ms total
124
125
console.log('Plugin efficiency analysis:', efficiency.slice(0, 3));
126
console.log('Performance bottlenecks:', bottlenecks.map(p => p.name));
127
```
128
129
### Middleware Analysis
130
131
Analyzing server middleware performance patterns:
132
133
```typescript
134
function analyzeMiddlewarePerformance(serverMetrics: ServerMetrics) {
135
if (!serverMetrics.middleware) return null;
136
137
const analysis = {
138
slowestRequests: [] as { url: string; totalTime: number }[],
139
middlewareImpact: new Map<string, { totalTime: number; requestCount: number }>()
140
};
141
142
// Analyze each request
143
Object.entries(serverMetrics.middleware).forEach(([url, metrics]) => {
144
const totalTime = metrics[metrics.length - 1]?.total || 0;
145
analysis.slowestRequests.push({ url, totalTime });
146
147
// Track middleware impact across all requests
148
metrics.forEach(metric => {
149
const current = analysis.middlewareImpact.get(metric.name) || { totalTime: 0, requestCount: 0 };
150
current.totalTime += metric.self;
151
current.requestCount += 1;
152
analysis.middlewareImpact.set(metric.name, current);
153
});
154
});
155
156
// Sort slowest requests
157
analysis.slowestRequests.sort((a, b) => b.totalTime - a.totalTime);
158
159
return analysis;
160
}
161
162
// Usage
163
const middlewareAnalysis = analyzeMiddlewarePerformance(serverMetrics);
164
if (middlewareAnalysis) {
165
console.log('Slowest requests:', middlewareAnalysis.slowestRequests.slice(0, 5));
166
167
// Show middleware impact
168
const middlewareByImpact = Array.from(middlewareAnalysis.middlewareImpact.entries())
169
.sort(([,a], [,b]) => b.totalTime - a.totalTime);
170
171
console.log('Middleware by total impact:');
172
middlewareByImpact.slice(0, 5).forEach(([name, stats]) => {
173
const avgTime = stats.totalTime / stats.requestCount;
174
console.log(`${name}: ${stats.totalTime}ms total, ${avgTime.toFixed(2)}ms avg`);
175
});
176
}
177
```
178
179
### Performance Monitoring Best Practices
180
181
#### Continuous Monitoring
182
183
```typescript
184
// Set up periodic performance monitoring
185
setInterval(async () => {
186
const metrics = await rpc.getPluginMetrics({ vite: 'instance-id', env: 'client' });
187
const bottlenecks = findBottlenecks(metrics, 100);
188
189
if (bottlenecks.length > 0) {
190
console.warn('Performance bottlenecks detected:', bottlenecks.map(p => p.name));
191
}
192
}, 10000); // Check every 10 seconds
193
```
194
195
#### Performance Alerts
196
197
```typescript
198
function setupPerformanceAlerts(thresholds: { plugin: number; request: number }) {
199
// Alert on slow plugins
200
const checkPluginPerformance = async () => {
201
const metrics = await rpc.getPluginMetrics({ vite: 'instance-id', env: 'client' });
202
const slowPlugins = metrics.filter(p =>
203
(p.transform.totalTime + p.resolveId.totalTime) > thresholds.plugin
204
);
205
206
if (slowPlugins.length > 0) {
207
console.warn(`Slow plugins detected (>${thresholds.plugin}ms):`,
208
slowPlugins.map(p => p.name));
209
}
210
};
211
212
// Alert on slow requests
213
const checkRequestPerformance = async () => {
214
const serverMetrics = await rpc.getServerMetrics({ vite: 'instance-id', env: 'client' });
215
if (serverMetrics.middleware) {
216
Object.entries(serverMetrics.middleware).forEach(([url, metrics]) => {
217
const totalTime = metrics[metrics.length - 1]?.total || 0;
218
if (totalTime > thresholds.request) {
219
console.warn(`Slow request detected: ${url} (${totalTime}ms)`);
220
}
221
});
222
}
223
};
224
225
return { checkPluginPerformance, checkRequestPerformance };
226
}
227
```