Skip to content

perf(listbox): re-render only rows whose visibility changes while filtering - #582

Draft
kianbazza wants to merge 1 commit into
canaryfrom
ui-640-re-render-only-rows-whose-visibility-changes-while-filtering
Draft

kianbazza wants to merge 1 commit into
canaryfrom
ui-640-re-render-only-rows-whose-visibility-changes-while-filtering

Conversation

@kianbazza

@kianbazza kianbazza commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Each row subscribed to the whole search string, so every keystroke re-rendered every mounted row. Rows now subscribe to a boolean, so only rows whose visibility flips re-render.

 useListboxItem()
-  normalizedSearch = store.useState('normalizedSearch')
-  score = store.useState('getItemScore', id)
-  isVisible = forceMount || filterDisabled || !normalizedSearch || score > 0
+  passesFilter = store.useState('isItemVisible', id)
+  isVisible = forceMount || filterDisabled || passesFilter

 <Separator>
-  search = store.useState('normalizedSearch')
+  hasSearch = store.useState('hasSearch')

isItemVisible and hasSearch are new store selectors. getItemScore and normalizedSearch stay, since the store is public as DropdownMenuStore and friends.

Evidence

row-renders.test.tsx › "re-renders only rows whose output changes while filtering": 20 items and an alwaysRender separator, each wrapped in a <Profiler>.

type "i", then "tem"           (every row stays visible)
  item commits                 before: 60   after: 0
  separator commits            before: 3    after: 0

type " 1", then "9"            (9 rows already hidden)
  hidden-row commits           before: 9    after: 0
  • Before: AssertionError: Item 01: expected 7 to be 4
    After: passes

Merge Danger

Door: two-way

Visibility follows the same rule as before: no search, filtering disabled, forceMount, or a positive score.

Blast Radius: small

Touches every menu family's rows (items and separators). A wrong selector would show up as rows not hiding or not reappearing while filtering, which the existing filtering tests cover.

Closes UI-640

@vercel

vercel Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
ui-canary Ready Ready Preview Oct 10, 2026 11:34pm UTC

Request Review

@linear-code

linear-code Bot commented Oct 10, 2026

Copy link
Copy Markdown

UI-640

@kianbazza
kianbazza force-pushed the ui-640-re-render-only-rows-whose-visibility-changes-while-filtering branch from 41a53bb to f695de5 Compare October 10, 2026 23:33

This branch was successfully deployed

1 active deployment
Preview – ui-canary — f695de5c Deployed Oct 10, 2026 by vercel[bot]
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