Skip to content

SelectPanel, FilteredActionList: typing re-renders every item #8717

Open

Description

@mattcosta7

Part of #8676 (P1). Measure with #8714 before and after.

Problem

  • FilteredActionList.tsx renders each item through MappedActionListItem (:628), which passes an inline onSelect to ActionList.Item (:651).
  • SelectPanel.tsx builds an inline onAction for every item (:714).
  • None of the ActionList, FilteredActionList, SelectPanel, DataTable or TreeView components uses React.memo.

Measured: with 300 items and a leading visual that counts its renders, typing one character that matches every item re-rendered all 300.

FilteredActionList/useAnnouncements.tsx also runs JSON.stringify over every item (getAnnouncementState, :63) and document.querySelector('live-region') (:82) on every render, even with announcements disabled. That was verified in code but not measured. Draft #8641 replaces the querySelector but keeps the JSON.stringify.

Proposed fix

  • Wrap MappedActionListItem and ActionList.Item in React.memo.
  • Route onSelect and onAction through a ref so item props stay stable.
  • Memoize the announcement state, and skip it when announcements are disabled.
  • Consider deferring filtering with useDeferredValue, the way Autocomplete defers its input (AutocompleteDeferredInputContext).

Memoization only pays off when consumers keep items stable, so measure with both stable and inline items. The fix must work on React 18 and 19.

Acceptance criteria

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions