SSR_BOUNDARY_WATERFALL fires on the first cold render because of lazy route chunks, and its advice points at data
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 15/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
- 技术栈
- typescript
- 领域
- frontend
调研方向
Start with the reproduction: run pnpm dev in the linked solid2-mail app, then request a nested route cold and warm to confirm the first-render-only warning. The payload points at fileRoutes() and its components Map in @solidjs/router/fs (dist/fs.js), where each route's lazy() import is cached, and at the SSR_BOUNDARY_WATERFALL diagnostic. The open question is which import causes the third sequential wait, and the author has not pinned it down. Done means the chunk imports start together on the server or the diagnostic stops reporting lazy-module waits as data reads.
由索引模型根据 Issue 内容生成。
描述
Summary
On the first SSR request after the dev server starts, the root <Loading> boundary reports SSR_BOUNDARY_WATERFALL (3 sequential waits). The waits aren't data reads. They come from fileRoutes() wrapping each code-split route component in lazy(). Each nested route level has to import() its module before the router can render the next level, so the chunks load one after another.
The warning's advice ("derive both from the same inputs", "preload the dependent data or join the requests") sends you looking at queries. The app can't fix this through queries: every query is already preloaded in parallel and wrapped in its own nested <Loading>.
Reproduction
App: https://github.com/brenelz/solid2-mail (file routes: (mail) layout → [mailbox]/[threadId] page)
- Start the dev server fresh:
pnpm dev - Make the first request a nested route:
curl -s -o /dev/null http://localhost:5173/inbox/thr-oncall - Request the same URL again.
| Request | Time | Warning |
|---|---|---|
| 1st (cold) | 1.57s | Yes |
| 2nd | 0.012s | No |
| 3rd | 0.011s | No |
[SSR_BOUNDARY_WATERFALL] A <Loading> boundary took 4 render passes — 3 sequential async waits, 173ms end to end: each read could start only after the previous one answered. If a later read doesn't need the earlier answer, derive both from the same inputs so they start together; if the dependency is intrinsic, preload the dependent data or join the requests.
in <Document> › <App> › <Router> › <RouterContextObj> › <Root> › <RootComp> › <Loading>
After you edit a route or component file, the warning comes back once, because Vite invalidates the module and it has to be imported again.
Cause
@solidjs/router/fs → fileRoutes() caches one lazy() component per route src for the lifetime of the process (dist/fs.js, the components Map). On a cold server:
- The
(mail)layout chunk is imported, and the root boundary suspends. - The layout renders and the router reaches the child, so the page chunk is imported and the boundary suspends again.
- One more sequential wait. I didn't pin down which import this is.
After that the lazy components are resolved, render synchronously, and the boundary finishes in one pass.
Expected
One or more of:
- Router: on the server, start every matched route's component import together, the same way route
preloads already run for every matched level, instead of discovering them one level per render pass. - Diagnostics: recognize waits caused by
lazy()module resolution and either skip them or report them separately, with advice about code splitting or eager server imports instead of data reads.
Versions
- solid-js 2.0.0-rc.15
- @solidjs/web 2.0.0-rc.15
- @solidjs/diagnostics 2.0.0-rc.15
- @solidjs/router 2.0.0-next.39
- @solidjs/vite-plugin 3.0.0-next.50
- filesystem-routing 0.4.0
- vite 8.3.4
- macOS (Darwin 25.5.0)
- 主要语言
- TypeScript
- 星标
- 36.2k
- 派生
- 1.1k
- 平均合并
- 11 小时 5 分钟
- 30 天内合并 PR
- 353
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
solidjs/solid 的其他 Issue
-
`lazy()`: remounting an already-loaded component renders empty (or the Suspense fallback) since 1.9.14可能已有人在做 @itisrmk 于 10 天前认领。 未关闭1.x
难度 2/5 1-3 小时 新手友好度 62/100
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 48/100
维护者通常 1 天内回复
-
难度 4/5 1-2 天 新手友好度 48/100
维护者通常 1 天内回复
-
enhancement
难度 5/5 一周以上 新手友好度 35/100
维护者通常 1 天内回复
-
`createRoot`'s dispose function keeps `fn` alive, so `<For>`/`<Index>` rows retain removed list items可能已有人在做 @boombang 于 12 天前认领。 未关闭1.x
难度 4/5 1-2 天 新手友好度 45/100
维护者通常 1 天内回复
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 75/100
维护者通常 1 天内回复
-
难度 1/5 1-3 小时 新手友好度 84/100
-
难度 2/5 1-3 小时 新手友好度 83/100
keptinventory/kept#336 ·
维护者通常 1 天内回复
-
good first issue
难度 2/5 1-3 小时 新手友好度 84/100
-
hemi-earn
难度 2/5 1-3 小时 新手友好度 72/100
vetro-protocol/vetro-monorepo#1013 ·
维护者通常 1 天内回复