Skip to content

fix: some more small sorting optimizations#6387

Merged
KevinVandy merged 1 commit into
betafrom
sorting-perf-again
Jul 7, 2026
Merged

fix: some more small sorting optimizations#6387
KevinVandy merged 1 commit into
betafrom
sorting-perf-again

Conversation

@KevinVandy

@KevinVandy KevinVandy commented Jul 6, 2026

Copy link
Copy Markdown
Member

🎯 Changes

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm test:pr.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed grouped rows showing duplicate expand/collapse controls in table examples.
    • Improved row sorting and selection behavior so row state stays consistent when rows are cloned or reordered.
    • Smoothed sorting for invalid or unavailable sort options by keeping the original row order when appropriate.
  • Performance

    • Reduced unnecessary row cloning during sorting and memoization updates for more stable table interactions.
  • Tests

    • Added coverage for grouped rows, row selection cloning, and leaf-row recalculation behavior.

@nx-cloud

nx-cloud Bot commented Jul 6, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit e267566

Command Status Duration Result
nx affected --targets=test:eslint,test:sherif,t... ✅ Succeeded 7m 33s View ↗
nx run-many --targets=build --exclude=examples/** ✅ Succeeded 44s View ↗

☁️ Nx Cloud last updated this comment at 2026-07-06 23:53:40 UTC

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Introduces a copyInstancePropertiesWithoutMemos utility to fix memoized closures leaking into cloned rows during row-selection and row-sorting, adds leaf-row memoization keyed on subRows, optimizes column_toggleSorting lookup, fixes duplicate expander rendering for grouped rows in example apps, and updates perf tracking documents.

Changes

Row cloning, memoization, and sorting fixes

Layer / File(s) Summary
Clone helper utility
packages/table-core/src/utils.ts
Adds copyInstancePropertiesWithoutMemos, copying own properties while skipping _memo_-prefixed keys.
Row-selection cloning fix
packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts, packages/table-core/tests/implementation/features/row-selection/rowSelectionFeature.test.ts
selectRowsFn clones now use the new helper instead of Object.assign, with a test verifying clones don't reuse memoized row APIs.
Sorted row model cloning and early exit
packages/table-core/src/features/row-sorting/createSortedRowModel.ts, packages/table-core/tests/unit/features/row-sorting/createSortedRowModel.test.ts
Returns pre-sorted model early when no valid sort entries remain; sortData clones branch rows only when subRows order changes, tracked via a changed flag, with expanded tests for identity, cloning, and memo isolation.
Leaf-row memoization
packages/table-core/src/core/rows/coreRowsFeature.ts, packages/table-core/tests/unit/core/rows/constructRow.test.ts
row_getLeafRows memoizes on row.subRows, with tests for cached identity and recomputation after mutation.
Sort toggle optimization
packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts
column_toggleSorting derives existingSorting from a single findIndex call instead of separate find/findIndex scans.
Grouped-row expander fix
examples/preact/kitchen-sink/src/main.tsx, examples/react/kitchen-sink/src/routes/index.tsx, examples/solid/kitchen-sink/src/App.tsx
firstName cell renderers now return null for grouped rows to avoid a duplicate expander.
Perf tracking docs
perf-done.md, perf-skipped.md, perf-todo.md
Documents newly confirmed fixes (C10, B10, NR1, D14, E12), adds new skipped findings, and removes resolved todo entries with updated counts.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • TanStack/table#6314: Both PRs modify selectRowsFn in rowSelectionFeature.utils.ts to change cloned-row property copying behavior.
  • TanStack/table#6344: Both PRs touch the selectRowsFn recursive selection/cloning path in the same file.
  • TanStack/table#6371: Both PRs modify the sorting workflow in createSortedRowModel.ts's sortData logic.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main theme of the PR: several small sorting-related optimizations and fixes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sorting-perf-again

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Jul 6, 2026

Copy link
Copy Markdown
More templates

@tanstack/alpine-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/alpine-table@6387

@tanstack/angular-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/angular-table@6387

@tanstack/angular-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/angular-table-devtools@6387

@tanstack/lit-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/lit-table@6387

@tanstack/match-sorter-utils

npm i https://pkg.pr.new/TanStack/table/@tanstack/match-sorter-utils@6387

@tanstack/preact-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/preact-table@6387

@tanstack/preact-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/preact-table-devtools@6387

@tanstack/react-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/react-table@6387

@tanstack/react-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/react-table-devtools@6387

@tanstack/solid-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/solid-table@6387

@tanstack/solid-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/solid-table-devtools@6387

@tanstack/svelte-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/svelte-table@6387

@tanstack/table-core

npm i https://pkg.pr.new/TanStack/table/@tanstack/table-core@6387

@tanstack/table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/table-devtools@6387

@tanstack/vue-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/vue-table@6387

@tanstack/vue-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/vue-table-devtools@6387

commit: e267566

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts (1)

719-751: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

flatRows and rowsById still expose the original branch row

newSelectedFlatRows.push(row) and newSelectedRowsById[row.id] = row run before the clone is created, so selected rows with subRows still leak the pre-clone instance through flatRows and rowsById. That leaves the same memo-bound row methods reachable via those access paths; write the cloned row into all three outputs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts`
around lines 719 - 751, The selected branch-row handling in recurseRows still
stores the original row into newSelectedFlatRows and newSelectedRowsById before
cloning, so flatRows and rowsById can expose the pre-clone instance. Update the
logic in rowSelectionFeature.utils.ts so the cloned row created for selected
rows with subRows is the object written into result, newSelectedFlatRows, and
newSelectedRowsById, keeping the branch consistent for all three outputs while
preserving the prototype chain and subRows assignment.
packages/table-core/src/features/row-sorting/createSortedRowModel.ts (1)

139-185: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve parent-before-children order in sortedFlatRows
sortData(row.subRows) drains the whole subtree into sortedFlatRows before the current row is pushed, so nested branches become child-first instead of depth-first parent-first. Push the current row before recursing and replace that slot with the clone if needed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/table-core/src/features/row-sorting/createSortedRowModel.ts` around
lines 139 - 185, The flattened row ordering in createSortedRowModel’s sortData
is wrong because recursing into row.subRows pushes descendants into
sortedFlatRows before the parent row, breaking parent-before-children
depth-first order. Update sortData so the current row is added to sortedFlatRows
before sorting its subRows, and if a cloned row is needed after recursion,
replace that same slot with the clone while preserving the existing compareRows
and copyInstancePropertiesWithoutMemos behavior.
🧹 Nitpick comments (1)
packages/table-core/tests/unit/features/row-sorting/createSortedRowModel.test.ts (1)

106-129: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider also asserting flatRows order for this scenario.

This test validates .rows/.subRows correctly, but doesn't check table.getSortedRowModel().flatRows ordering. Adding that assertion here would have caught the parent-after-children ordering regression flagged in createSortedRowModel.ts (sortData).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/table-core/tests/unit/features/row-sorting/createSortedRowModel.test.ts`
around lines 106 - 129, The branch-row sorting test in createSortedRowModel
should also verify flatRows ordering, not just rows and subRows. Update the
existing “clones branch rows when sorted subRows change” case to assert
table.getSortedRowModel().flatRows reflects the expected parent-after-children
order after sorting. Use the same makeTable and getSortedRowModel setup, and add
an assertion on flatRows to cover the sortData regression.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts`:
- Around line 719-751: The selected branch-row handling in recurseRows still
stores the original row into newSelectedFlatRows and newSelectedRowsById before
cloning, so flatRows and rowsById can expose the pre-clone instance. Update the
logic in rowSelectionFeature.utils.ts so the cloned row created for selected
rows with subRows is the object written into result, newSelectedFlatRows, and
newSelectedRowsById, keeping the branch consistent for all three outputs while
preserving the prototype chain and subRows assignment.

In `@packages/table-core/src/features/row-sorting/createSortedRowModel.ts`:
- Around line 139-185: The flattened row ordering in createSortedRowModel’s
sortData is wrong because recursing into row.subRows pushes descendants into
sortedFlatRows before the parent row, breaking parent-before-children
depth-first order. Update sortData so the current row is added to sortedFlatRows
before sorting its subRows, and if a cloned row is needed after recursion,
replace that same slot with the clone while preserving the existing compareRows
and copyInstancePropertiesWithoutMemos behavior.

---

Nitpick comments:
In
`@packages/table-core/tests/unit/features/row-sorting/createSortedRowModel.test.ts`:
- Around line 106-129: The branch-row sorting test in createSortedRowModel
should also verify flatRows ordering, not just rows and subRows. Update the
existing “clones branch rows when sorted subRows change” case to assert
table.getSortedRowModel().flatRows reflects the expected parent-after-children
order after sorting. Use the same makeTable and getSortedRowModel setup, and add
an assertion on flatRows to cover the sortData regression.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6eebe02f-890c-4820-929f-a7e7010606de

📥 Commits

Reviewing files that changed from the base of the PR and between 5d5330e and e267566.

📒 Files selected for processing (14)
  • examples/preact/kitchen-sink/src/main.tsx
  • examples/react/kitchen-sink/src/routes/index.tsx
  • examples/solid/kitchen-sink/src/App.tsx
  • packages/table-core/src/core/rows/coreRowsFeature.ts
  • packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts
  • packages/table-core/src/features/row-sorting/createSortedRowModel.ts
  • packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts
  • packages/table-core/src/utils.ts
  • packages/table-core/tests/implementation/features/row-selection/rowSelectionFeature.test.ts
  • packages/table-core/tests/unit/core/rows/constructRow.test.ts
  • packages/table-core/tests/unit/features/row-sorting/createSortedRowModel.test.ts
  • perf-done.md
  • perf-skipped.md
  • perf-todo.md

@KevinVandy KevinVandy merged commit 74d5f71 into beta Jul 7, 2026
8 checks passed
@KevinVandy KevinVandy deleted the sorting-perf-again branch July 7, 2026 00:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant