Skip to content

Lazy loading

wybthon.lazy

lazy

Lazy-loaded components integrated with Loading boundaries.

lazy wraps a loader callback (sync or async) that produces a component. The component loads on first mount, backed by an async create_memo: while the load is in flight, the nearest Loading boundary shows its fallback, and a load failure raises into the nearest Errored boundary. This matches SolidJS's lazy(() => import(...)) semantics, adapted to Python's import system.

The loader may return:

  • a component callable directly,
  • an imported module (an export is picked by convention: Page, then default, then the first callable), or
  • a module path string, or a (module_path, attr) tuple, imported via importlib.

Async loaders can await arbitrary work first (for example micropip.install(...) in Pyodide) before returning any of the above.

Example
About = lazy(lambda: ("app.about.page", "Page"))

async def load_chart():
    import micropip
    await micropip.install("app-charts")
    import app_charts
    return app_charts.Chart

Chart = lazy(load_chart)
Chart.preload()  # warm the cache on hover/intent

Loading(lambda: About(), fallback=p("Loading..."))
See Also

Functions:

Name Description
lazy

Create a lazily-loaded component from a loader callback.

LazyComponent

LazyComponent(loader: Callable[[], Any])

Bases: Component

A component returned by lazy; call .preload() to load early.

Methods:

Name Description
retry

Retry a failed load, notifying mounted error boundaries on recovery.

preload

Start loading now (a no-op when already loading or loaded).

retry

retry() -> None

Retry a failed load, notifying mounted error boundaries on recovery.

preload

preload() -> None

Start loading now (a no-op when already loading or loaded).

lazy

lazy(loader: Callable[[], Any], *, chunk: str | None = None) -> LazyComponent

Create a lazily-loaded component from a loader callback.

The loader runs once, on the first mount (or on .preload()); the resolved component is cached for every later mount. While loading, the nearest Loading boundary shows its fallback. A loader error raises into the nearest Errored boundary.

Parameters:

Name Type Description Default
loader Callable[[], Any]

Zero-arg callable, sync or async, returning a component callable, a module, a module-path string, or a (module_path, attr) tuple.

required
chunk str | None

Optional named build chunk to fetch before invoking the loader.

None

Returns:

Type Description
LazyComponent

A component with a .preload() method that starts the load

LazyComponent

early.

Example
Team = lazy(lambda: ("app.about.team.page", "Page"))

Route(path="/about/team", component=Team)
Link("Team", href="/about/team", on_mouseenter=lambda e: Team.preload())

What's in this module

lazy defers loading a component until it first mounts. The load is backed by an async create_memo, so it suspends into the nearest Loading while in flight and raises into the nearest Errored on failure, matching SolidJS's lazy(() => import(...)) adapted to Python's import system.

Name Description
lazy lazy(loader, *, chunk=None); the loader is a zero-arg callable, sync or async, returning a component, a module, a module-path string, or a (module_path, attr) tuple. chunk names a build chunk to fetch first.
LazyComponent What lazy returns: a Component with .preload() to start the load early and .retry() to retry a failed load.
from wybthon import Loading, component, lazy, p
from wybthon.router import Link, Route, Router

About = lazy(lambda: ("app.about.page", "Page"))  # importlib, attribute "Page"


async def load_chart():
    import micropip

    await micropip.install("app-charts")
    import app_charts

    return app_charts.Chart


Chart = lazy(load_chart)


@component
def App():
    return Loading(
        lambda: Router([Route("/about", About), Route("/chart", Chart)]),
        fallback=lambda: p("Loading..."),
    )


nav_link = Link("Chart", href="/chart", on_mouseover=Chart.preload)
  • When the loader returns a module, the export is picked by convention: Page, then default, then the first callable.
  • The loader runs at most once; the resolved component is cached across unmounts.
  • Props and children passed to the lazy component are forwarded to the loaded component unchanged.

See also