Skip to content

perf(rendering): avoid unused list virtual rows#559

Closed
JustYannicc wants to merge 71 commits into
SuperCmdLabs:mainfrom
JustYannicc:codex/perf-list-conditional-virtual-rows
Closed

perf(rendering): avoid unused list virtual rows#559
JustYannicc wants to merge 71 commits into
SuperCmdLabs:mainfrom
JustYannicc:codex/perf-list-conditional-virtual-rows

Conversation

@JustYannicc

Copy link
Copy Markdown
Collaborator

What changed

ListComponent now builds one virtual row layout per filtered item set: normal list rows for list mode, or emoji grid rows for emoji-grid mode. The render branches keep concrete row types through a discriminated layout object, while shared metrics, visible range, scroll-into-view, and item-index mapping continue to consume the selected virtual rows.

Why

The previous runtime computed both buildListVirtualRows(groupedItems) and buildEmojiGridVirtualRows(groupedItems) on every filtered item change, then discarded one based on shouldUseEmojiGridValue. Emoji-heavy lists paid for a full normal-list row array they never rendered, and normal lists paid for unused emoji-grid rows.

Compatibility impact

No intended behavior change. Emoji grid detection, row keys, visible range math, selection mapping, scroll positioning, list/detail mode gating, and both render branches remain functionally unchanged.

How tested

  • node scripts/test-emoji-grid-virtualization.mjs
  • node --test scripts/test-list-registry-stable-order.mjs scripts/test-emoji-grid-virtualization.mjs
  • node --test scripts/test-grid-virtualization.mjs scripts/test-registry-dirty-checks.mjs
  • ./node_modules/.bin/tsc -p tsconfig.renderer.json --noEmit
  • ./node_modules/.bin/vite build
  • Codex LSP diagnostics on src/renderer/src/raycast-api/list-runtime.tsx: no errors

Performance evidence

Local helper-substep benchmark, 11 samples per case, measuring the old build-both shape against the new conditional shape with the same grouped fixtures:

  • 5k emoji rows: old emoji path median 0.0343 ms/iteration; new emoji path median 0.0111 ms/iteration.
  • 20k emoji rows: old emoji path median 0.1693 ms/iteration; new emoji path median 0.0433 ms/iteration.
  • 5k normal rows: old normal path median 0.0363 ms/iteration; new normal path median 0.0224 ms/iteration.
  • 20k normal rows: old normal path median 0.1715 ms/iteration; new normal path median 0.1172 ms/iteration.

The absolute delta is small, but the timing was stable and directly targets the row-construction work removed by this change.

Stack validation

Started from fork/codex/perf-consolidated-integration-stack fetched at 264fb89dc5c867d6c3d77bc4b95e26e235e326ea. Branch codex/perf-list-conditional-virtual-rows contains one scoped commit on top: 9798e97.

Replaces

None.

…ated-integration-stack

# Conflicts:
#	src/renderer/src/raycast-api/hooks/use-cached-promise.ts
…ated-integration-stack

# Conflicts:
#	src/renderer/src/raycast-api/list-runtime-renderers.tsx
#	src/renderer/src/raycast-api/list-runtime.tsx
…ated-integration-stack

# Conflicts:
#	src/renderer/src/CameraExtension.tsx
…ated-integration-stack

# Conflicts:
#	src/renderer/src/raycast-api/list-runtime.tsx
… into codex/perf-consolidated-integration-stack
@JustYannicc

Copy link
Copy Markdown
Collaborator Author

Superseded by the consolidated wave-2 UI/runtime PR: #572

@JustYannicc JustYannicc closed this Jul 4, 2026
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