Lazy Loading
Zero-config module loading with automatic route detection.
Overview
| Feature | Description |
|---|---|
| Zero-Config | Routes auto-detected from @controller() |
| One-Liner Setup | setupLazyLoadingForExpress() |
| Warmup Strategies | Idle, immediate, scheduled |
| Preload Hints | Low, medium, high, never |
| Performance Metrics | Built-in tracking |
| Auto Middleware | Loads middleware for lazy routes |

Quick Start
1. Create Lazy Modules
import { CreateLazyModule } from "@expressots/core";
import { ReportsController } from "./reports.controller";
import { AdminController } from "./admin.controller";
// Reports module - loads when /reports routes are accessed
export const ReportsLazyModule = CreateLazyModule(
[ReportsController],
{ name: "ReportsModule" }
).withPreloadHint("low");
// Admin module - only loads when accessed
export const AdminLazyModule = CreateLazyModule(
[AdminController],
{ name: "AdminModule" }
).withPreloadHint("never");
2. Setup Lazy Loading
import { setupLazyLoadingForExpress } from "@expressots/adapter-express";
export class App extends AppExpress {
private config: AppContainer = this.configContainer([
// Eager modules (loaded at startup)
CoreModule,
AuthModule,
UserModule,
// Don't add lazy modules here!
]);
async configureServices(): Promise<void> {
// One-liner setup!
const { lazyModulesCount, middleware, routeMappings } =
setupLazyLoadingForExpress(this.container.Container, {
lazyModules: [ReportsLazyModule, AdminLazyModule],
globalPrefix: "/api",
enableMetrics: true,
enableWarmup: true,
warmupConfig: {
strategy: "idle",
delay: 10000,
hints: ["low", "medium"]
}
});
// Add auto-load middleware
if (middleware) {
this.Middleware.add(middleware);
}
console.log(`Registered ${lazyModulesCount} lazy modules`);
console.log("Auto-detected routes:", routeMappings);
}
}
3. Define Controllers
Routes are automatically detected from @controller() decorators:
// routes automatically detected!
@controller("/reports")
export class ReportsController {
@Get("/")
getAllReports() {
return { reports: [] };
}
@Get("/generate")
generateReport() {
return { status: "generating" };
}
}
No manual route mapping needed! The system automatically:
- Detects
/api/reports/*routes - Maps them to
ReportsLazyModule - Loads module on first access
Auto-Detection System
How It Works
The lazy loading system automatically detects routes from your controllers:
@controller("/admin")
export class AdminController {
@Get("/dashboard") // Detected: /api/admin/dashboard
dashboard() {}
@Get("/users") // Detected: /api/admin/users
users() {}
}
Behind the scenes:
- System scans
@controller()decorators - Extracts route prefixes (
"/admin") - Combines with
globalPrefix("/api") - Maps routes to lazy modules automatically
Result: /api/admin/* → AdminLazyModule
Manual Route Mapping (Optional)
For complex scenarios, provide manual mappings:
setupLazyLoadingForExpress(container, {
lazyModules: [ReportsLazyModule],
routePrefixes: {
ReportsModule: "/reports", // Manual mapping: module name -> route prefix
},
globalPrefix: "/api"
});
Preload Hints
Control when/if modules are preloaded using hints:
Never (Default for Admin Modules)
Never preload - only load when accessed:
const AdminLazyModule = CreateLazyModule(
[AdminController],
{ name: "AdminModule" }
).withPreloadHint("never");
Use for: Admin panels, rarely-used features
Low Priority
Preload during idle time (low priority):
const ReportsLazyModule = CreateLazyModule(
[ReportsController],
{ name: "ReportsModule" }
).withPreloadHint("low");
Use for: Features used by some users occasionally
Medium Priority
Preload after initial startup:
const AnalyticsLazyModule = CreateLazyModule(
[AnalyticsController],
{ name: "AnalyticsModule" }
).withPreloadHint("medium");
Use for: Features used by many users
High Priority
Preload immediately after startup:
const SearchLazyModule = CreateLazyModule(
[SearchController],
{ name: "SearchModule" }
).withPreloadHint("high");
Use for: Features used by almost all users
Warmup Strategies
Idle Warmup (Recommended)
Preload modules during idle time:
setupLazyLoadingForExpress(container, {
lazyModules: [ReportsLazyModule, AdminLazyModule],
enableWarmup: true,
warmupConfig: {
strategy: "idle", // Load during idle
delay: 10000, // Wait 10s after startup
hints: ["low", "medium"] // Only preload low/medium priority
}
});
Best for: Most applications (doesn't block startup)
Immediate Warmup
Preload all modules immediately after startup:
warmupConfig: {
strategy: "immediate",
hints: ["low", "medium", "high"]
}
Best for: Applications where startup time isn't critical
Scheduled Warmup
Start warmup after a fixed delay:
warmupConfig: {
strategy: "scheduled",
delay: 30000, // Start warmup 30s after setup
hints: ["low", "medium"]
}
Best for: Deferring warmup until after peak startup traffic