Inspect the intermediate state of Vite plugins during development and build processes
—
Plugin and server performance monitoring with detailed timing and invocation data for optimizing Vite build performance.
Detailed performance metrics for individual plugins including invocation counts and timing data.
interface PluginMetricInfo {
/** Plugin name */
name: string;
/** Plugin enforcement mode ('pre' | 'post' | undefined) */
enforce?: string;
/** Transform hook performance metrics */
transform: {
/** Number of times transform hook was called */
invokeCount: number;
/** Total time spent in transform hook (milliseconds) */
totalTime: number;
};
/** ResolveId hook performance metrics */
resolveId: {
/** Number of times resolveId hook was called */
invokeCount: number;
/** Total time spent in resolveId hook (milliseconds) */
totalTime: number;
};
}Usage Example:
// Get plugin performance metrics
const metrics = await rpc.getPluginMetrics({ vite: 'instance-id', env: 'client' });
// Find slowest plugins
const slowestPlugins = metrics
.sort((a, b) => (b.transform.totalTime + b.resolveId.totalTime) - (a.transform.totalTime + a.resolveId.totalTime))
.slice(0, 5);
console.log('Top 5 slowest plugins:');
slowestPlugins.forEach((plugin, index) => {
const totalTime = plugin.transform.totalTime + plugin.resolveId.totalTime;
const totalInvocations = plugin.transform.invokeCount + plugin.resolveId.invokeCount;
const avgTime = totalTime / totalInvocations;
console.log(`${index + 1}. ${plugin.name}`);
console.log(` Total time: ${totalTime}ms`);
console.log(` Invocations: ${totalInvocations}`);
console.log(` Avg per call: ${avgTime.toFixed(2)}ms`);
});Performance metrics for server middleware with timing breakdown and call hierarchy.
interface ServerMetrics {
/** Middleware performance data organized by request URL */
middleware?: Record<string, { name: string; self: number; total: number; }[]>;
}Usage Example:
// Get server middleware metrics
const serverMetrics = await rpc.getServerMetrics({ vite: 'instance-id', env: 'client' });
if (serverMetrics.middleware) {
Object.entries(serverMetrics.middleware).forEach(([url, metrics]) => {
console.log(`Request: ${url}`);
metrics.forEach((metric, index) => {
const indent = ' '.repeat(index);
console.log(`${indent}${metric.name}: ${metric.self}ms (${metric.total}ms total)`);
});
const totalTime = metrics[metrics.length - 1]?.total || 0;
console.log(`Total request time: ${totalTime}ms\n`);
});
}Utility functions for analyzing performance data:
// Analyze plugin efficiency
function analyzePluginEfficiency(metrics: PluginMetricInfo[]) {
return metrics.map(plugin => {
const transform = plugin.transform;
const resolveId = plugin.resolveId;
return {
name: plugin.name,
enforce: plugin.enforce,
efficiency: {
transformAvg: transform.invokeCount > 0 ? transform.totalTime / transform.invokeCount : 0,
resolveIdAvg: resolveId.invokeCount > 0 ? resolveId.totalTime / resolveId.invokeCount : 0,
totalTime: transform.totalTime + resolveId.totalTime,
totalCalls: transform.invokeCount + resolveId.invokeCount
}
};
}).sort((a, b) => b.efficiency.totalTime - a.efficiency.totalTime);
}
// Find bottlenecks
function findBottlenecks(metrics: PluginMetricInfo[], threshold: number = 100) {
return metrics.filter(plugin => {
const totalTime = plugin.transform.totalTime + plugin.resolveId.totalTime;
return totalTime > threshold;
});
}
// Usage
const efficiency = analyzePluginEfficiency(metrics);
const bottlenecks = findBottlenecks(metrics, 50); // Plugins taking >50ms total
console.log('Plugin efficiency analysis:', efficiency.slice(0, 3));
console.log('Performance bottlenecks:', bottlenecks.map(p => p.name));Analyzing server middleware performance patterns:
function analyzeMiddlewarePerformance(serverMetrics: ServerMetrics) {
if (!serverMetrics.middleware) return null;
const analysis = {
slowestRequests: [] as { url: string; totalTime: number }[],
middlewareImpact: new Map<string, { totalTime: number; requestCount: number }>()
};
// Analyze each request
Object.entries(serverMetrics.middleware).forEach(([url, metrics]) => {
const totalTime = metrics[metrics.length - 1]?.total || 0;
analysis.slowestRequests.push({ url, totalTime });
// Track middleware impact across all requests
metrics.forEach(metric => {
const current = analysis.middlewareImpact.get(metric.name) || { totalTime: 0, requestCount: 0 };
current.totalTime += metric.self;
current.requestCount += 1;
analysis.middlewareImpact.set(metric.name, current);
});
});
// Sort slowest requests
analysis.slowestRequests.sort((a, b) => b.totalTime - a.totalTime);
return analysis;
}
// Usage
const middlewareAnalysis = analyzeMiddlewarePerformance(serverMetrics);
if (middlewareAnalysis) {
console.log('Slowest requests:', middlewareAnalysis.slowestRequests.slice(0, 5));
// Show middleware impact
const middlewareByImpact = Array.from(middlewareAnalysis.middlewareImpact.entries())
.sort(([,a], [,b]) => b.totalTime - a.totalTime);
console.log('Middleware by total impact:');
middlewareByImpact.slice(0, 5).forEach(([name, stats]) => {
const avgTime = stats.totalTime / stats.requestCount;
console.log(`${name}: ${stats.totalTime}ms total, ${avgTime.toFixed(2)}ms avg`);
});
}// Set up periodic performance monitoring
setInterval(async () => {
const metrics = await rpc.getPluginMetrics({ vite: 'instance-id', env: 'client' });
const bottlenecks = findBottlenecks(metrics, 100);
if (bottlenecks.length > 0) {
console.warn('Performance bottlenecks detected:', bottlenecks.map(p => p.name));
}
}, 10000); // Check every 10 secondsfunction setupPerformanceAlerts(thresholds: { plugin: number; request: number }) {
// Alert on slow plugins
const checkPluginPerformance = async () => {
const metrics = await rpc.getPluginMetrics({ vite: 'instance-id', env: 'client' });
const slowPlugins = metrics.filter(p =>
(p.transform.totalTime + p.resolveId.totalTime) > thresholds.plugin
);
if (slowPlugins.length > 0) {
console.warn(`Slow plugins detected (>${thresholds.plugin}ms):`,
slowPlugins.map(p => p.name));
}
};
// Alert on slow requests
const checkRequestPerformance = async () => {
const serverMetrics = await rpc.getServerMetrics({ vite: 'instance-id', env: 'client' });
if (serverMetrics.middleware) {
Object.entries(serverMetrics.middleware).forEach(([url, metrics]) => {
const totalTime = metrics[metrics.length - 1]?.total || 0;
if (totalTime > thresholds.request) {
console.warn(`Slow request detected: ${url} (${totalTime}ms)`);
}
});
}
};
return { checkPluginPerformance, checkRequestPerformance };
}Install with Tessl CLI
npx tessl i tessl/npm-vite-plugin-inspect