Closed lukeed closed 3 months ago
My naiive guess is that there's too much store logic happening (or not granular enough) which is why the initial render is also taking so long.
Rendering the same 3200 items into a plain <ul>
completes almost instantly, which is also true even if I match the same DOM structure (attributes and all).
The initial render with the Command.Root
list takes at least 8s.
Hey @lukeed, thanks for raising this issue!
I will try to find some time to investigate further. I'm hoping it is something small I've overlooked that is causing this behavior.
My own little investigation made it seem like the major factor is a sort being run excessively; each Command.Item
creation calls context.value(id, value)
:
which in turn triggers a sort during a state.update
:
which is repeated n
times, resulting in approx n * nlogn = n^2 * logn
operations run
Not sure the best way to handle - I think the ideal solution would be sorting after all the Command.Item
s are created (once the slot is done mounting?), but as long as the sorting isn't run every time, any solution would probably be fine.
Also, more concentrated repro for testing purposes:
<script>
import { Command } from "cmdk-sv";
const ten_first_names = ["John", "Doe", "Jane", "Smith", "Michael", "Brown", "William", "Johnson", "David", "Williams"];
const ten_middle_names = ["James", "Lee", "Robert", "Michael", "David", "Joseph", "Thomas", "Charles", "Christopher", "Daniel"];
const ten_last_names = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"];
const names = ten_first_names.map((first, i) => {
return ten_middle_names.map((middle, j) => {
return ten_last_names.map((last, k) => {
return `${first} ${middle} ${last}`;
});
});
}).flat(2);
</script>
<Command.Root loop>
<Command.Input placeholder="Search items..." />
<Command.Empty>No item found.</Command.Empty>
<Command.List class="h-[var(--cmdk-list-height)] max-h-96">
{#each names as txt (txt)}
<Command.Item value={txt}>{txt}</Command.Item>
{/each}
</Command.List>
</Command.Root>
Hey @csjh, thanks a ton for the detailed comment and reproduction.
I'll try to find some time to dig into this further and come to some sort of solution for this issue!
I have a looped Command/popover w/ 3200 items in it. It takes a while to render, but the main issue is that as soon as I attempt to type into the
Command.Input
the tab freezes with 100% CPUThis example was ported over from React and works fine after the initial slow render.