Files
Imhotep/packages/imhotep-bench/src/render-target-benchmark.ts
T

123 lines
4.0 KiB
TypeScript
Raw Normal View History

// render-target-benchmark.ts - Benchmark renderer adapter mounting.
// Measures scene target creation and resolution overhead.
import {
runBenchmark,
BenchmarkSuite,
type BenchmarkResult,
} from './benchmark.js';
import {
pageTarget,
storybookStoryTarget,
reactComponentTarget,
vueComponentTarget,
fixtureTarget,
matchSceneTarget,
type SceneTarget,
} from 'imhotep-core';
// ---------------------------------------------------------------------------
// Simulated adapter resolution
// ---------------------------------------------------------------------------
function resolveTargetUrl(target: SceneTarget): string {
return matchSceneTarget(target, {
page: (url) => url,
'playwright-page': (pageRef, url) => url || `playwright://${pageRef}`,
'storybook-story': (storyId, storybookUrl) => `${storybookUrl}/iframe.html?id=${storyId}`,
'react-component': (rendererId, componentId) =>
`component://react/${rendererId}/${componentId}`,
'vue-component': (rendererId, componentId) =>
`component://vue/${rendererId}/${componentId}`,
'custom-renderer': (rendererId, targetId) =>
`component://custom/${rendererId}/${targetId}`,
fixture: (fixtureId) => `file:///fixtures/${fixtureId}.html`,
});
}
function mountComponent(target: SceneTarget): { targetId: string; url: string } {
const url = resolveTargetUrl(target);
const targetId = `mount_${Math.random().toString(36).slice(2, 8)}`;
// Simulate mount overhead
const overhead = Array.from({ length: 100 }, (_, i) => i * 2).reduce((a, b) => a + b, 0);
return { targetId, url };
}
// ---------------------------------------------------------------------------
// Benchmarks
// ---------------------------------------------------------------------------
export async function runRenderTargetBenchmarks(): Promise<BenchmarkResult[]> {
const suite = new BenchmarkSuite('render-target-mount', {
defaults: { warmupRuns: 2, measurementRuns: 5 }
});
// React mount time
suite.add('react-mount', () => {
const target = reactComponentTarget('react-dom', 'Button');
mountComponent(target);
});
// Vue mount time
suite.add('vue-mount', () => {
const target = vueComponentTarget('vue-dom', 'Button');
mountComponent(target);
});
// Storybook story load time
suite.add('storybook-load', () => {
const target = storybookStoryTarget('button--primary', 'http://localhost:6006');
mountComponent(target);
});
// Page target resolution
suite.add('page-target-resolve', () => {
const target = pageTarget('https://example.com/page');
resolveTargetUrl(target);
});
// Fixture target resolution
suite.add('fixture-target-resolve', () => {
const target = fixtureTarget('property-render-react');
resolveTargetUrl(target);
});
// Mixed renderer batch
suite.add('mixed-renderer-batch-10', () => {
const targets: SceneTarget[] = [
reactComponentTarget('react-dom', 'Button'),
vueComponentTarget('vue-dom', 'Button'),
storybookStoryTarget('button--primary', 'http://localhost:6006'),
pageTarget('https://example.com/page'),
fixtureTarget('property-render-react'),
reactComponentTarget('react-dom', 'Card'),
vueComponentTarget('vue-dom', 'Card'),
storybookStoryTarget('card--default', 'http://localhost:6006'),
pageTarget('https://example.com/other'),
fixtureTarget('property-render-vue'),
];
for (const t of targets) {
mountComponent(t);
}
});
const result = await suite.runSequential();
return result.results;
}
// CLI entry point
if (import.meta.url === `file://${process.argv[1]}`) {
runRenderTargetBenchmarks().then((results) => {
console.log('\n=== Render Target Benchmark Results ===\n');
for (const r of results) {
console.log(`${r.name}:`);
console.log(` mean: ${r.meanDurationMs.toFixed(3)}ms`);
console.log(` min: ${r.minDurationMs.toFixed(3)}ms`);
console.log(` max: ${r.maxDurationMs.toFixed(3)}ms`);
console.log(` memory: ${r.meanMemoryDeltaBytes.toFixed(0)}B`);
console.log();
}
});
}