โก Performance Benchmarks
Head-to-head performance comparison with other DI frameworks
๐ About These Benchmarks
These benchmarks compare NovaDI with other popular TypeScript DI frameworks across multiple performance metrics. Each test runs 1000 iterations to ensure accurate results. Open your browser console (F12) to see detailed execution logs and timing information.
๐ Test Metrics:
- Singleton Resolution: Measure cached singleton lookup performance
- Transient Resolution: Test new instance creation on every resolve
- Build Time: Container setup time with 100 registrations
- Complex Graph: Realistic multi-layer dependency graph resolution
- Bundle Size: Minified + gzipped framework size
๐ฏ Compared Frameworks: NovaDI, Brandi, InversifyJS, TSyringe, TypeDI
๐ Looking for usage examples? Check out the Examples page for interactive demos of NovaDI features and patterns.
๐งช Test Class Structures
Below are the class structures used in the performance benchmarks. Understanding what's being tested helps interpret the results.
๐ฆ Simple Test Classes (Singleton & Transient Tests)
These minimal classes are used to benchmark pure resolution speed without complexity.
// Simple test interfaces
interface ICache {
get(key: string): any
set(key: string, value: any): void
}
// Simple implementations (no dependencies)
class Logger implements ILogger {
log(message: string, context?: string): void {}
info(message: string, context?: string): void {}
warn(message: string, context?: string): void {}
error(message: string, error?: Error): void {}
}
class Cache implements ICache {
private data = new Map()
get(key: string) { return this.data.get(key) }
set(key: string, value: any) { this.data.set(key, value) }
}
// Benchmark code
builder.registerType(Logger).as<ILogger>().singleInstance()
builder.registerType(Cache).as<ICache>().singleInstance()
// Measure 1000 cached singleton resolutions
for (let i = 0; i < 1000; i++) {
app.resolveType<ILogger>()
app.resolveType<ICache>()
}
๐ค Complex Graph Test (Smart Home System)
This test uses the full smart home system (Example 6) with multi-layer dependencies. Same structure is used for No AutoWire variant.
// Multi-layer dependency graph:
// AutomationService โ Logger + EventBus โ Logger
// Devices (SmartThermostat, SmartLight) โ Logger
// Sensors (TemperatureSensor, MotionSensor) - no dependencies
// Core services
builder.registerType(ConsoleLogger).as<ILogger>().singleInstance()
builder
.registerType(EventBus)
.as<IEventBus>()
.autoWire({ map: { logger: (c) => c.resolveType<ILogger>() } })
.singleInstance()
builder
.registerType(AutomationService)
.as<AutomationService>()
.autoWire({
map: {
logger: (c) => c.resolveType<ILogger>(),
eventBus: (c) => c.resolveType<IEventBus>()
}
})
.singleInstance()
// Sensors (instances)
builder.registerInstance(new TemperatureSensor(...)).as<ISensor>().keyed('TempSensor')
builder.registerInstance(new MotionSensor(...)).as<ISensor>().keyed('MotionSensor')
// Devices (with autowired logger dependency)
builder.registerType(SmartThermostat).as<IDevice>().keyed('Thermostat')
.autoWire({ map: { logger: (c) => c.resolveType<ILogger>(), ... } })
// Measure 1000 complex resolutions
for (let i = 0; i < 1000; i++) {
app.resolveType<AutomationService>() // Resolves Logger + EventBus chain
}
โก Same Structure, No AutoWire
Uses direct factory registration instead of .autoWire() to eliminate function call overhead.
// Instead of .autoWire({ map: { logger: (c) => c.resolveType<ILogger>() } })
// Use direct factory:
builder.register((c) => {
const logger = c.resolveType<ILogger>()
return new EventBus(logger)
}).as<IEventBus>().singleInstance()
builder.register((c) => {
const logger = c.resolveType<ILogger>()
const eventBus = c.resolveType<IEventBus>()
return new AutomationService(logger, eventBus)
}).as<AutomationService>().singleInstance()
// Same test: 1000 resolutions of AutomationService
// Expected result: Faster due to no autoWire map overhead
๐ Technical Reference - Smart Home Domain Classes
Interfaces
Service Classes
Sensor Classes
Device Classes (Actuators)
Dependency Graph (Demo 5 / Performance Tests)
Performance Benchmarks
Head-to-head performance comparison with other popular DI frameworks
- NovaDI - Our decorator-free, browser-first framework
- Brandi - Decorator-free TypeScript DI
- InversifyJS - Popular decorator-based DI framework
- TSyringe - Microsoft's lightweight DI container
- TypeDI - TypeStack's decorator-based container
- 4 metrics: Resolution Speed, Build Time, Complex Graph, Bundle Size
๐ Performance Benchmark Results
NovaDI Complex Graph (No AutoWire)
Testing NovaDI Complex Graph performance without AutoWire overhead - direct factory registration
- Direct Factory Registration - No autowire map function overhead
- Fair Comparison - Same pattern as TypeDI implementation
- Expected Performance - Should match or beat TypeDI
- 1000 Resolutions - Complex dependency graph test
โ ๏ธ Console Output Required
Press F12 or Ctrl+Shift+I (Windows/Linux) / Cmd+Option+I (Mac) to open your browser's developer console. All demo execution details, dependency resolution logs, and automation events are logged there with grouped output for easy navigation.