Skip to content

v0.38.0 — Gallery in-place selection updates

Choose a tag to compare

@Deaththegrim Deaththegrim released this 07 May 00:36
· 66 commits to main since this release

v0.38.0 — Gallery in-place selection updates

The biggest remaining perf hit on huge libraries was that every selection click rebuilt the entire grid. For a 700-entry library, click-to-select used to create and discard ~21,000 DOM nodes per keystroke / click — even arrow-key navigation triggered the same full rebuild.

Three new helpers

_refreshTileSelection(id)  — flip .selected class + aria-selected + checkbox
                             checkmark on one tile, found via
                             querySelector('[data-prompt-id=...]')
_refreshFocusedTile()      — move .focused class from previous to current
                             tile (two DOM mutations max)
applySelectionChange(ids)  — wrapper: syncWidget() + _refreshTileSelection
                             per id + _refreshFocusedTile() + updateBulkBar()

Call sites updated

Action Before After
Tile click syncWidget(); render() (full rebuild) applySelectionChange([id])
Shift-range click syncWidget(); render() applySelectionChange(rangeIds)
Checkbox click syncWidget(); render() applySelectionChange([id])
Enter/Space keypress syncWidget(); render() applySelectionChange([id])
Bulk Clear syncWidget(); render() applySelectionChange(wereSelected)
Arrow-key focus move render() then scroll _refreshFocusedTile() then scroll

Trade-off

The "selected tiles bubble to the top" behaviour from render's sort step doesn't fire on a selection-only change anymore — selected tiles stay visually in place until the next sort/filter change. Most workflows click tiles they can already see, so this is a clear win for huge libraries.

render() still runs for filter / sort / refresh / websocket / refresh-after-delete paths — anywhere the visible set or order genuinely changes.

Cumulative gallery perf wins (v0.36 → v0.38)

Action on 700-entry library v0.36 v0.38
Type one search character full grid rebuild debounced (80 ms) + DocumentFragment batched
Click a tile to select full grid rebuild one tile's classList toggled
Shift-range select 100 tiles full grid rebuild 100 tiles' classes toggled
Arrow-key navigation full grid rebuild per keystroke two DOM mutations per keystroke
Bulk clear selection full grid rebuild N tiles' classes removed
Delete a tile (modal Save) full grid rebuild full rebuild (still — data changed)
Sort change full grid rebuild full rebuild (correct)

Backward compat

All changes internal — no socket / widget / workflow JSON shape changes.

Install / upgrade

cd ComfyUI/custom_nodes/ComfyUI-GrimmRibbity
git pull
# restart ComfyUI / hard-refresh browser tab