Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[2.0 rc.14] Feature request: prerender(view), running a view's reads to preload them without creating its elements or running its effects

Open
#3,975 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
12/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active

Research direction

The payload names no files or tests. Start with the workaround in the body, which renders the view into a detached host inside a Loading boundary, to see which reads it triggers. Then look at how hydration runs component code once to trace dependencies, since the author suggests it as a starting point. Done means a design the maintainers accept, since the runtime or compiler support needed is their call.

Written by the indexing model from the issue text.

Description

Summary

Preloading on hover or intent usually means listing what the next view will read, which repeats its component tree. Rendering the view itself discovers its reads, but the only way to do that today is a full client render into a detached element, kept from committing by a <Loading> that never resolves. That builds every element of the view only to discard them, gives no signal when all its reads have settled, and needs owner and context plumbing by hand. A primitive that runs a view's components and reads, and nothing else, would make render-driven preloading cheap and explicit.

Today

The current way, and the undocumented behaviour it depends on, is #3974:

function preview(view: () => JSX.Element, owner: Owner | null) {
  const host = document.createElement("div");
  return runWithOwner(owner, () =>
    render(() => {
      const gate = createMemo(() => new Promise<never>(() => {}));
      return (
        <Loading fallback={null}>
          {gate()}
          {view()}
        </Loading>
      );
    }, host),
  );
}

Measured in headless Chromium under vite dev, previewing a list with one detail per row, each element's ref logging its creation: the list's read started at 0 ms and both detail reads at 103 ms, as soon as the list answered. The ul and both p elements were created (their ref callbacks ran), but the host stayed empty and no createEffect or onSettled ran. Every element of the previewed tree is built and thrown away, and nothing reports when the detail reads finished.

Proposal
const run = prerender(() => <Page />); // under the current owner and context
run.settled; // resolves when every read in the tree, including ones found as data arrived, has settled or failed
run.dispose(); // stop early; loads already started still finish
  • Runs component bodies, memos and async reads (memos, stores, projections, lazy() and lazyModule()), following the tree level by level as data arrives, as a pending boundary does.
  • Creates no elements, render effects or effects, and commits nothing.
  • Keeps its pending state out of isPending and transitions, its holds out of the hold diagnostics, and its errors away from any <Errored>; a failed read stays failed in its source, for the real view to retry.
  • Disposes itself once settled resolves.

The compiled client output creates elements in component bodies, so skipping them likely needs runtime or compiler support; how is the maintainers' call. Hydration already runs component code once to trace dependencies (with promises held), which may be a starting point.

Related: #3213 (RFC for <Activity>, keeping hidden UI and its state; this request is narrower: no DOM and nothing kept, only the reads), #1008 (<Offscreen>), #1877 (a low-level primitive to pause effects in offscreen branches), #3941 (lazyModule(), preloading code), and React's <Activity mode="hidden">, which pre-renders hidden trees to load their data and code.

(submitted by Claude Opus 5.5 on behalf of rvlzzr)

Dominant language
TypeScript
Stars
36.1k
Forks
1.1k
Avg merge
9h 56m
Merged PRs (30d)
336

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from solidjs/solid

All issues in solidjs/solid

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.