From 1,256ms to 96ms: Fixing INP in a Massive React Dropdown
The Scenario In Subito's design system, we rely heavily on a custom MultiSelect component. We use it across our marketplace as a standard checkbox-style filter: you search, tick a few boxes, and hit Apply. Under the hood, it's built on top of react-select , completely re-skinned. For most filters (like item condition or shipping), the option list has about a dozen entries. It felt instant because…
The Subito design system utilizes a custom MultiSelect component, built upon react-select, to function as a standard checkbox-style filter for its marketplace. This filter displays a catalog of around 1,175 options on the Marca (Brand) filter page, which negatively impacts performance on mobile devices with throttled CPUs, resulting in a poor Interaction to Next Paint (INP) metric of 1,256ms.
The primary issue lies within the synchronous block of work triggered by opening the dropdown, which forces React to create ~1,175 Option component instances, generating several DOM nodes. To solve this problem, the team adopted a virtualization technique, rendering only the items currently visible on the screen, plus a small buffer just outside the viewport. This approach avoids the need to create React components and DOM nodes for items that the user cannot currently see.
The team implemented a custom useVirtualScroll hook to track the scroll position and render only the visible rows, plus a small buffer (OVERSCAN of 5 items). Once the height of one row is measured after mounting, the hook calculates the total height of the list, as well as the slice of the list to render based on the current scroll position and viewport height. Only the ~13 necessary rows are mounted in the DOM, with the full list still available for scrolling and searching.
The key requirement for this approach is that every row must be the same height. If this condition is not met, the list will break and display gaps, overlapping rows, or unreachable options. The solution was successfully implemented using standard React APIs and does not require rewriting everything or importing large third-party virtualization libraries.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.