Skip to content

perf(renderer): reduce Raycast list render churn - #619

Closed
JustYannicc wants to merge 121 commits into
SuperCmdLabs:mainfrom
JustYannicc:codex/perf-raycast-list-emoji-render-churn-20260705
Closed

perf(renderer): reduce Raycast list render churn#619
JustYannicc wants to merge 121 commits into
SuperCmdLabs:mainfrom
JustYannicc:codex/perf-raycast-list-emoji-render-churn-20260705

Conversation

@JustYannicc

Copy link
Copy Markdown
Collaborator

What changed

  • Memoized ListItemRenderer and ListEmojiGridItemRenderer with render-relevant comparators that ignore inline selection/action callback identity.
  • Added current-selection/current-primary-action refs in list-runtime.tsx so memoized rows keep activation behavior current even when DOM handlers are not refreshed on unrelated selection moves.
  • Added scripts/measure-raycast-list-render-churn.mjs and scripts/test-list-emoji-render-churn.mjs to measure and assert list/emoji selection render churn.

Why

Selection movement in list-runtime.tsx creates fresh row/cell callbacks for every visible list item and emoji cell. Without memoized leaf renderers, every visible row/cell re-rendered even though only the previously selected and newly selected items changed visually.

Compatibility impact

No Raycast API surface changes. The comparators preserve visible/render-relevant props including selected state, data index, list text values, assetsPath, icon references, and accessory references. Callback identity is intentionally ignored, with activation behavior reading the latest selection/action through refs.

How tested

  • node --test scripts/test-list-emoji-render-churn.mjs scripts/test-list-conditional-virtual-rows.mjs scripts/test-emoji-grid-virtualization.mjs
  • ./node_modules/.bin/tsc -p tsconfig.renderer.json --noEmit --pretty false
  • Codex LSP diagnostics on src/renderer/src/raycast-api/list-runtime-renderers.tsx: no diagnostics found
  • Codex LSP diagnostics on src/renderer/src/raycast-api/list-runtime.tsx: no diagnostics found

Performance evidence

Before this change, with SUPERCMD_NODE_MODULES=/Users/justyannicc/.codex/worktrees/3847/SuperCmd/node_modules node scripts/measure-raycast-list-render-churn.mjs --iterations=5 --warmups=1 --selection-steps=800 --json:

  • selectionRenderChurn.listItemRenderCount: 51200
  • selectionRenderChurn.emojiGridItemRenderCount: 89600
  • listMedianDurationMs: 566.0315
  • emojiMedianDurationMs: 417.1664

After this change, with node scripts/measure-raycast-list-render-churn.mjs --iterations=5 --warmups=1 --selection-steps=800 --json:

  • selectionRenderChurn.listItemRenderCount: 1600
  • selectionRenderChurn.emojiGridItemRenderCount: 1600
  • listMedianDurationMs: 86.1857
  • emojiMedianDurationMs: 102.6075

Grid control check remains at the wave4 memo baseline shape: node scripts/measure-raycast-grid-render-churn.mjs --iterations=5 --warmups=1 --selection-steps=800 --json reported selectionRenderChurn.cellRenderCount: 1600.

Stack validation

Started from branch codex/perf-wave4-integrated-stack-20260705 at ac90ce403aeddab98d0a1b245afce268c48b8bfd; git rev-parse HEAD was verified before creating codex/perf-raycast-list-emoji-render-churn-20260705.

Replaces

Wave5 performance implementation for Raycast list/emoji row render churn. Replaces no prior PR.

(cherry picked from commit 83c2a89)
(cherry picked from commit 0a7560b)
# Conflicts:
#	src/renderer/src/raycast-api/hooks/use-cached-promise.ts
…launcher surfaces

# Conflicts:
#	src/renderer/src/raycast-api/list-runtime-renderers.tsx
#	src/renderer/src/raycast-api/list-runtime.tsx
…IO stalls

# Conflicts:
#	src/renderer/src/CameraExtension.tsx
# Conflicts:
#	src/renderer/src/raycast-api/list-runtime.tsx
…resh overhead

# Conflicts:
#	scripts/bench-script-command-discovery.mjs
#	scripts/benchmark-file-search-delete-batch.mjs
#	scripts/lib/script-command-runner-harness.mjs
#	scripts/lib/ts-import.mjs
#	scripts/test-file-search-delete-batch.mjs
#	scripts/test-script-command-runner.mjs
#	src/main/file-search-index.ts
#	src/main/main.ts
…hurn

# Conflicts:
#	scripts/lib/script-command-runner-harness.mjs
#	scripts/lib/ts-import.mjs
#	scripts/test-extension-lifecycle-sandbox.mjs
#	scripts/test-script-command-runner.mjs
#	src/main/main.ts
#	src/renderer/src/ExtensionView.tsx
… hot paths

# Conflicts:
#	scripts/test-use-frecency-sorting.mjs
#	src/renderer/src/raycast-api/form-runtime.tsx
#	src/renderer/src/raycast-api/grid-runtime-hooks.ts
#	src/renderer/src/raycast-api/grid-runtime-items.tsx
#	src/renderer/src/raycast-api/hooks/use-frecency-sorting.ts
# Conflicts:
#	.github/workflows/project-checks.yml
#	package.json
#	scripts/file-search-perf-harness.mjs
#	scripts/test-browser-search-performance.mjs
#	scripts/test-file-search-perf-harness.mjs
#	scripts/test-root-search-perf.mjs
#	src/renderer/src/CameraExtension.tsx
#	src/renderer/src/hooks/useBrowserSearch.ts
#	src/renderer/src/raycast-api/list-runtime.tsx
…cle and media fixes

# Conflicts:
#	scripts/lib/ts-import.mjs
#	scripts/measure-extension-bundle-cache.mjs
#	src/main/commands.ts
#	src/main/extension-runner.ts
#	src/main/main.ts
#	src/renderer/src/ExtensionView.tsx
#	src/renderer/src/raycast-api/grid-runtime-hooks.ts
#	src/renderer/src/raycast-api/list-runtime-hooks.ts
@JustYannicc

Copy link
Copy Markdown
Collaborator Author

Superseded by consolidated renderer/Raycast wave5 PR #621: #621

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