lazy()
The lazy() function wraps a dynamic import into a transparent stand-in. On the server (or once the import resolves), calls pass through directly. On the client before the chunk loads, it creates a reactive async boundary that swaps in the real content when the chunk arrives.
Syntax
Section titled “Syntax”lazy(importer)Parameters
Section titled “Parameters”importer
: A function that returns a Promise — typically a dynamic import() with a .then() that resolves to a callable producing a RefSpec.
Return value
Section titled “Return value”The same type as whatever the promise resolves to. Calls are intercepted transparently — if the import has resolved, calls go straight through. If it hasn’t, an async boundary is created.
Description
Section titled “Description”lazy() intercepts exactly one call. The importer should resolve to a function that produces a RefSpec when called:
// The import resolves to a function: (data) => RefSpecconst LazyChart = lazy(() => import('./Chart').then(m => m.Chart(svc)));
// Call the result — if loaded, passes through; if not, creates async boundaryconst view = LazyChart(data);Fast path (cached)
Section titled “Fast path (cached)”When the import has already resolved (always the case on the server, since bundlers resolve imports synchronously), the call goes directly to the real value. No async boundary, no signal overhead.
Slow path (pending)
Section titled “Slow path (pending)”When the import hasn’t resolved yet:
lazy()returns a wrapper function- When called, the wrapper creates a reactive boundary using
signal+match - The boundary renders nothing while pending
- When the import resolves,
matchswaps in the real content ASYNC_FRAGMENTmetadata is attached so SSR can introspect the boundary
preloadAll()
Section titled “preloadAll()”Resolves all pending lazy imports. Call before hydration to prevent client/server mismatch:
await lazy.preloadAll();Examples
Section titled “Examples”Lazy-loaded route
Section titled “Lazy-loaded route”const LazyStreamingPage = (svc: Service) => svc.lazy(() => import('./pages/StreamingPage').then(m => m.StreamingPage(svc)) );
// Use in a route switchmatch(currentRoute, (route) => { switch (route) { case 'home': return HomePage(svc); case 'streaming': return LazyStreamingPage(svc)(); }})Multiple lazy components
Section titled “Multiple lazy components”const LazyChart = lazy(() => import('./Chart').then(m => m.Chart(svc)));const LazyTable = lazy(() => import('./Table').then(m => m.Table(svc)));
// Both chunks load in parallelel('div')( LazyChart(chartData), LazyTable(tableData),)Preload before hydration
Section titled “Preload before hydration”// Server rendered the full page — ensure all chunks are// loaded before hydrating so the DOM matchesawait lazy.preloadAll();hydrate(containerEl, App);Module usage
Section titled “Module usage”lazy is available via LazyModule for use with compose():
import { compose } from '@rimitive/core';import { SignalModule } from '@rimitive/signals/extend';import { LazyModule } from '@rimitive/view/lazy';import { MatchModule } from '@rimitive/view/match';
const { lazy } = compose( SignalModule, MatchModule.with({ adapter }), LazyModule,);LazyModule depends on SignalModule and MatchModule — both must be composed.