Skip to content

[Autocomplete] Optimize selected option lookup in useAut…#47953

Open
anchmelev wants to merge 1 commit intomui:masterfrom
anchmelev:autocomplete/47843-selected-lookup
Open

[Autocomplete] Optimize selected option lookup in useAut…#47953
anchmelev wants to merge 1 commit intomui:masterfrom
anchmelev:autocomplete/47843-selected-lookup

Conversation

@anchmelev
Copy link

Closes #47843

Summary

This PR improves Autocomplete performance in multiple mode with large datasets by optimizing selected-option lookups in useAutocomplete.

Problem

When many options are selected (for example, 10,000), selected-state checks are done repeatedly with linear scans (Array.some) in hot paths:

  • filtering with filterSelectedOptions
  • rendering option state (aria-selected via getOptionProps)

That leads to quadratic work and visible lag.

What changed

  1. Added a strict-equality fast path for selected lookup:
  • build a Set of selected values once per render when isOptionEqualToValue is the default (option === value)
  • use Set.has(option) for O(1) lookup
  1. Kept a safe fallback for custom equality:
  • when isOptionEqualToValue is customized, keep using some(...) to preserve user-defined semantics
  1. Reused a shared isOptionSelected helper in both hot paths:
  • filterSelectedOptions
  • getOptionProps (aria-selected)
  1. Added a regression test ensuring custom isOptionEqualToValue behavior is unchanged.

Why this approach

Set.has is only correct for strict reference equality.
For custom comparators (for example, compare by id), Set.has can be incorrect, so this PR explicitly falls back to comparator-based scans in that case.

This gives a large perf win for the default path without changing behavior for customized equality.

Benchmark notes

Local micro-benchmark (10,000 options, 10,000 selected, two selected-state passes):

  • Before: ~100,010,000 comparisons, ~121ms avg
  • After (strict-equality fast path): 0 comparator calls in lookup path, ~0.72ms avg

Tests

  • pnpm prettier
  • pnpm eslint packages/mui-material/src/useAutocomplete/useAutocomplete.js packages/mui-material/src/useAutocomplete/useAutocomplete.test.js
  • pnpm test:node useAutocomplete

…ocomplete

Use a Set-based fast path when isOptionEqualToValue is the default strict equality comparator.
This avoids quadratic selected-state checks in large multiple selections while preserving custom equality semantics.
Also add a regression test to ensure custom isOptionEqualToValue behavior is unchanged.
@mui-bot
Copy link

mui-bot commented Mar 11, 2026

Netlify deploy preview

https://deploy-preview-47953--material-ui.netlify.app/

Bundle size report

Bundle Parsed size Gzip size
@mui/material 🔺+183B(+0.04%) 🔺+57B(+0.04%)
@mui/lab 0B(0.00%) 0B(0.00%)
@mui/system 0B(0.00%) 0B(0.00%)
@mui/utils 0B(0.00%) 0B(0.00%)

Details of bundle changes

Generated by 🚫 dangerJS against 5322073

@anchmelev
Copy link
Author

Could a maintainer please add a label (e.g. scope: autocomplete)?
Check if PR has label is currently failing because the PR has no labels.

@anchmelev anchmelev changed the title [material-ui][Autocomplete] Optimize selected option lookup in useAut… [Autocomplete] Optimize selected option lookup in useAut… Mar 12, 2026
@zannager zannager added the scope: autocomplete Changes related to the autocomplete. This includes ComboBox. label Mar 12, 2026
@zannager zannager requested a review from ZeeshanTamboli March 12, 2026 13:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: autocomplete Changes related to the autocomplete. This includes ComboBox.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[RFC] [Autocomplete] performance improvement

3 participants