Skip to content

perf: reduce per-item and global work on hot paths - #2110

Open
MathiasWP wants to merge 1 commit into
huntabyte:mainfrom
MathiasWP:bits-ui-perf-quick-wins
Open

perf: reduce per-item and global work on hot paths#2110
MathiasWP wants to merge 1 commit into
huntabyte:mainfrom
MathiasWP:bits-ui-perf-quick-wins

Conversation

@MathiasWP

Copy link
Copy Markdown
Contributor

Five contained perf fixes. No API or behavior changes.

  • Select/Combobox itemsprops read root.highlightedValue / root.includesItem() directly, so moving the highlight invalidated every mounted item (N prop objects + N mergeProps + N attribute diffs per keypress). Now derived from per-item booleans, so only the two items that changed rebuild.
  • Select/Combobox (multiple) — selection lookup was Array.includes per item per value change; now a derived Set.
  • Calendar/RangeCalendarisToday(date, getLocalTimeZone()) ran today() per cell, i.e. ~42 Intl.DateTimeFormat#formatToParts calls per render. Hoisted to a root derived keyed on months, so it refreshes on the same cadence.
  • Menu family — the capture-phase document pointermove listener was attached for the component's whole lifetime just to flip keyboard mode off. Now attached only while keyboard mode is on.
  • ScrollArea/Slider/NavigationMenuSvelteResizeObserver allocated one ResizeObserver per call site (ScrollArea makes ~6, several on the same node). Replaced with one shared observer + refcounted WeakMap.

Tests: 1272 browser + 122 unit passing, svelte-check clean.

- Select/Combobox: derive item props from per-item booleans so moving the
  highlight or changing the value only rebuilds props for the items that
  actually changed instead of every mounted item
- Select/Combobox (multiple): use a set for selection lookups instead of
  scanning the value array once per item
- Calendar/RangeCalendar: resolve the local timezone once per calendar
  rather than once per rendered cell
- Menu family: only attach the document-level `pointermove` listener while
  keyboard mode is active
- ScrollArea/Slider/NavigationMenu: share a single `ResizeObserver` across
  all observed elements
@changeset-bot

changeset-bot Bot commented Aug 21, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3af44ec

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
bits-ui Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor
built with Refined Cloudflare Pages Action

⚡ Cloudflare Pages Deployment

Name Status Preview Last Commit
bits-ui ✅ Ready (View Log) Visit Preview 3af44ec

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