Chrome renderer freeze when TanStack row model gates a Suspense child
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 35/100
- Issue 类型
- 缺陷
- 描述清晰度
- 需要澄清
- 活跃度
- 冷清
- 技术栈
- react, typescript, vite
- 领域
- frontend
调研方向
克隆链接的独立复现项目,运行 pnpm install、pnpm check 和 pnpm preview:repro,然后在 Chrome 中使用 Synchronous active row button 复现卡顿。先从精简后的 App 示例开始,比较有无 table.getRowModel().rows.length 时的行为;完成的标准是确定问题属于 TanStack Table,还是属于 React 与浏览器之间的交互,并记录已确认的修复方案或明确范围的移交。
由索引模型根据 Issue 内容生成。
描述
Summary
In a Vite production preview, Chrome can freeze after a real browser click when all of the following happen in the same render path:
- A synchronous React state update switches TanStack Table from empty data to a fresh one-row
dataarray. - The component reads
table.getRowModel().rows.length. - That row-model read gates mounting a child inside
Suspense. - The child suspends by throwing a timer-backed promise.
The repro is standalone and uses only local React state/data.
Reproduction
Standalone repro:
https://github.com/HaukeSchnau/trusted-click-table-suspense-freeze-repro
Repro commit used while filing this issue:
https://github.com/HaukeSchnau/trusted-click-table-suspense-freeze-repro/tree/67c0ea8
git clone https://github.com/HaukeSchnau/trusted-click-table-suspense-freeze-repro.git
cd trusted-click-table-suspense-freeze-repro
pnpm install
pnpm check
pnpm preview:repro
Then open http://127.0.0.1:4174/ in Chrome and click Synchronous active row.
The repro command uses Vite production preview. I have not characterized Vite dev mode.
Expected behavior
The click completes, the Suspense fallback handles the thrown promise, and the page remains responsive.
Actual behavior
The Chrome tab freezes during the click. Reloading or closing the tab is required to recover.
Environment
- React
19.2.3 react-dom19.2.3@tanstack/react-table8.21.3- Vite
7.3.0 - TypeScript
5.9.3 - Node
v24.11.1 - pnpm
10.25.0 - Chrome
147.0.0.0fromnavigator.userAgent - macOS
26.4.1(25E253)
I have only confirmed the freeze in Chrome. Firefox and Safari are untested.
Reduced trigger
const columns: [] = [];
const coreRowModel = getCoreRowModel();
let resolved = false;
let promise: Promise<void> | undefined;
function Suspender() {
if (!resolved) {
promise ??= new Promise((resolve) => {
window.setTimeout(() => {
resolved = true;
resolve();
});
});
throw promise;
}
return null;
}
function App() {
const [active, setActive] = useState(false);
const table = useReactTable({
data: active ? [null] : [],
columns,
getCoreRowModel: coreRowModel,
});
return (
<>
{table.getRowModel().rows.length ? (
<Suspense fallback={null}>
<Suspender />
</Suspense>
) : null}
<button id="sync-active" onClick={() => setActive(true)}>
Synchronous active row
</button>
</>
);
}
Isolation notes
The repro does not use TanStack Router, TanStack Query, React Compiler, Vite React plugin, APIs, auth, or production app code.
This may ultimately be a React Suspense or browser interaction. I’m filing here first because the smallest library-specific condition I’ve isolated is the TanStack Table row-model read over fresh data; the reduced app becomes responsive when that row-model read is removed.
- 主要语言
- TypeScript
- 星标
- 28.4k
- 派生
- 3.6k
- 平均合并
- 1 天 1 小时
- 30 天内合并 PR
- 7
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
TanStack/table 的其他 Issue
-
难度 1/5 1 小时以内 新手友好度 78/100
-
难度 5/5 一周以上 新手友好度 35/100
-
难度 3/5 1-2 天 新手友好度 78/100
-
难度 5/5 一周以上 新手友好度 35/100
-
难度 3/5 1-2 天 新手友好度 55/100
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 84/100
bcgov/bc-wallet-mobile#4761 · 1 条评论 ·
-
external-issue to-triage
难度 2/5 1-3 小时 新手友好度 88/100
-
area-deployment area-integrations triage:bot-seen
难度 2/5 半天 新手友好度 86/100
-
难度 2/5 1-3 小时 新手友好度 82/100
-
refactor
难度 2/5 1-3 小时 新手友好度 84/100