Skip to content

Batch non-virtual Combobox option updates - #3899

Open
tevinch wants to merge 1 commit into
tailwindlabs:mainfrom
tevinch:fix-combobox-option-batching
Open

tevinch wants to merge 1 commit into
tailwindlabs:mainfrom
tevinch:fix-combobox-option-batching

Conversation

@tevinch

@tevinch tevinch commented Oct 2, 2026

Copy link
Copy Markdown

Filtering a non-virtual Combobox currently sorts its options and notifies every subscription for each individual mount and unmount. This batches those updates by option ID, then orders the final list and notifies subscribers once per batch.

Pending updates are flushed before navigation, selection and explicit activation changes. This preserves synchronous ArrowUp opening, pointer lookup, immediate focus followed by Tab, and transitions to virtual options that reuse IDs. The public API and option count stay unchanged.

Addresses #3898.

Validation:

  • New machine regression fails on the original code with 4,096 selector evaluations for 64 registrations; the update keeps the same selection/navigation workflow within four passes over the 64 subscribers.
  • Regression coverage includes mount/unmount/remount, disabled fallback, immediate focus/Tab and a StrictMode non-virtual-to-virtual transition followed by selection.
  • Final full suite: 56 suites, 2,052 tests and 100 snapshots pass; 36 tests skipped. One earlier run hit an unchanged Vue transition timing snapshot; that file and the final full run pass without changes.
  • React/Vue builds, formatting and the packed React package's type-resolution check pass.
  • Software-operated Chrome checks with React 19.3.0 complete filtering, keyboard selection, reopening, empty-result recovery and pointer selection using 1,000 non-virtual options. Static, ordered, multiple and virtual flows were also checked. The packed build installs and completes the ordinary selection flow in a separate consumer project.

These checks cover the repeated registration cost; they do not establish identical timing across browsers or applications.

@vercel

vercel Bot commented Oct 2, 2026

Copy link
Copy Markdown

@tevinch is attempting to deploy a commit to the Tailwind Labs Team on Vercel.

A member of the Team first needs to authorize it.

@corneliusroemer

Copy link
Copy Markdown

Have you done perf testing? Would be good to include before/after on a large number of options to show the benefit.

@tevinch

tevinch commented Oct 2, 2026

Copy link
Copy Markdown
Author

I added a repeated before/after comparison for npm 2.2.10 versus the packed build of 62be2bd. Median of five fresh-page trials after one warm-up, in milliseconds:

Rendered options npm 2.2.10 Packed correction
250 901.8 55.1
500 4604.4 175.2
1,000 22411.7 580.0

This used production bundles, React 19.3.0 and headed Chrome 154.0.8037.93 on macOS 14.6 / Apple M1. The metric runs from the capture-phase input event to the next animation-frame callback, excluding initial opening; it is not a completed-paint or INP measurement. The ordinary list retained the requested option count before and after typing 1 in all 30 trials. Keyboard selection, reopening, empty-result recovery and pointer selection also completed.

The fixture and reproduction steps and all samples are available.

These absolute baseline times are substantially slower than yours. This was a software-operated browser with its existing extensions and controller attached, not your Linux environment or exact reproduction. Some baseline operations exceeded the controller response deadline; I read their completed page metrics afterward without resending input. No timed sample was discarded. The comparison supports reduced update cost here, but I would not treat the ratio as a general speedup.

This branch has not been deployed

No deployments
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.

2 participants