1. docs
  2. lazy imports

Lazy Imports

Code you don't need yet shouldn't block first render. Lazy loading has one machinery and two entry points: lazyImport lazily imports any value, and lazyContent lazily imports renderable content. Both load modules on demand as ordinary async data, and both share one cache.

lazyImport Copy link

lazyImport wraps a dynamic import() in an activity, so lazily-loaded content composes like any other async data: subscribe with effect, & the import's promise is tracked by the settlement signal — renderToString & hydrate wait for it (see Server Rendering and Client Hydration). The result is cached per key for the life of the page: repeat calls with the same key return the same activity without re-importing (createRoutes loads its route pages through this same machinery — see Routing).

API lazyImport<ImportType>(key, importer)

Inclusion import { lazyImport } from '@loom-js/core';

Arguments

  • key: string | Symbol - The cache key.

  • importer: () => Promise<ImportType> - The import function — e.g. async () => (await import('./chart')).Chart.

Returns The import's activity — a LazyImportActivity<ImportType>, so effect, watch & value() carry ImportType | undefined: undefined until the import resolves, then whatever the importer's promise resolved to.

ts Copy code
import { component, lazyImport } from '@loom-js/core';
 
import { Loading } from './loading';
 
const chart = lazyImport('chart', async () => (await import('./chart')).Chart);
 
export const Dashboard = component(
  (html) => html`
    <section>
      ${chart.effect(({ value: Chart }) => (Chart ? Chart() : Loading()))}
    </section>
  `
);

When the imported thing is renderable content, lazyContent trims the ceremony — the name says what resolves.

lazyContent Copy link

lazyContent(path, importer?) - The same machinery & cache as lazyImport, typed for renderable content: the importer resolves a ContextFunction | undefined (defaulting to undefined), & the path doubles as the cache key.

ts Copy code
import { component, lazyContent } from '@loom-js/core';
 
import { Loading } from './loading';
 
// No invented key — the path doubles as it. No undefined-dance in the
// effect — the importer resolves content already ready to render.
const chartPanel = lazyContent('./chart-panel', async () =>
  (await import('./chart-panel')).ChartPanel()
);
 
export const Dashboard = component(
  (html) => html`
    <section>
      ${chartPanel.effect(({ value }) => value ?? Loading())}
    </section>
  `
);