[2.0 rc.14] Feature request: prerender(view), running a view's reads to preload them without creating its elements or running its effects
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
- Tech stack
- javascript, typescript
- Domain
- frontend, performance
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()andlazyModule()), 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
isPendingand 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
settledresolves.
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
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from solidjs/solid
-
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Difficulty 3/5 Half a day Newbie friendliness 32/100
solidjs/solid#3974 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 52/100
Maintainers usually reply within 1 day
-
hydrate() run mid-parse leaves dead server nodes beside fresh client copies (async entry script)Open
Difficulty 4/5 3-5 days Newbie friendliness 20/100
Maintainers usually reply within 1 day
Similar issues
-
🐛 Bug: Calendar work items cannot be opened on mobilePossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 1/5 Under an hour Newbie friendliness 75/100
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
jaegertracing/jaeger-ui#4596 ·
Maintainers usually reply within 1 day
-
area:tui enhancement platform:macos
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
anthropics/claude-code#101490 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
netlify/netlify-mcp#75 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day