Skip to content

Gallery: Browse large collections with a sparse page cache (infinite scrolling) - #9683

Merged
joshistoast merged 34 commits into
invoke-ai:mainfrom
JPPhoto:webv2-sparse-page-cache
Oct 9, 2026
Merged

joshistoast merged 34 commits into
invoke-ai:mainfrom
JPPhoto:webv2-sparse-page-cache

Conversation

@JPPhoto

@JPPhoto JPPhoto commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Enables infinite scrolling through Galleries with more than 600 items. A bounded sparse page cache loads items as you scroll, supports jumping to distant positions, and reloads earlier pages when scrolling back. Numbered pagination remains available.

Details

Large Galleries previously relied on loading ordered item lists, which limited browsing and made distant navigation expensive. This adds shared, bounded sparse-page loading so users can scroll or jump through large Galleries while retaining item positions, recent local completions, and consistent selection across the Gallery, picker, Preview, and reveal flows.

Adds an item-location API and generated frontend contract to support resolving Gallery items into the sparse listing. Includes loading, empty, error, and retry behavior for page reads and numbered pagination.

Related Issues / Discussions

None.

QA Instructions

  • The changed Gallery data and Preview navigation browser suites pass 77/77, including shrink while the clamped page loads, missing/failed predecessor navigation, retry, and refreshed sparse absolute positions.
  • TypeScript, OXC, formatting, and architecture checks passed; architecture tests: 90/90. The webv2 unit suite passed 9,578/9,578.
  • Performance architecture budgets, project-file browser journey, and all 18 accessibility journeys passed.
  • The full Chromium batch passed 2,267/2,269. Two failures were in unchanged workflow editor and generation preset tests; both passed when rerun individually.
  • Manual review: browse beyond 600 items, jump to a distant position, page backward after cache eviction, open items in Preview and picker, and retry a failed page request.

Review

The latest two review findings are addressed. Count discovery no longer replaces a newer retained page total while a clamped page loads. Preview Left navigation resolves or retries an unresolved preceding page before entering starred or recent sections, and refreshed page data replaces retained data by offset so absolute positions stay current. Three independent reviews found no remaining blockers.

Earlier unrelated Gallery, picker, Preview, and full-suite findings remain documented in the development checklist and are excluded from this change.

Compatibility / Rollout

The item-location endpoint and generated API types are additive. No persisted-data migration or deployment ordering is required.

Checklist

  • The PR has a short but descriptive title, suitable for a changelog
  • Meaningful regression coverage added / updated where needed; obsolete tests/code removed
  • Persisted-state and API changes include required migrations / compatibility validation
  • Relevant performance/efficiency opportunities considered; material claims have evidence
  • Material review findings resolved and relevant checks rerun
  • Documentation added / updated (if applicable)
  • Updated What's New copy (if doing a release after this PR)

JPPhoto and others added 9 commits October 2, 2026 19:18
Share bounded 60-item page queries across Gallery, picker, Preview, and deep reveal. Add sparse grid navigation and filtered item-location API.

Update generated API contracts and Gallery guidance with focused backend and browser coverage.
Preserve sparse Gallery conditions alongside upstream workbench styling.
Keep non-removing mutations from changing listing totals and prune failed pages.

Bound starred-strip reads and preserve selection star state through page eviction.

Add accessible slot status, retry, and keyboard regressions for the sparse grid.
Map page loading and error states only to visible item ranges.
Add browser coverage for retrying failed cold page count discovery.
@github-actions github-actions Bot added api python PRs that change python files services PRs that change app services frontend PRs that change frontend files python-tests PRs that change python tests docs PRs that change docs labels Oct 5, 2026
@JPPhoto
JPPhoto requested review from joshistoast and removed request for Pfannkuchensack, blessedcoolant, dunkeroni and lstein October 5, 2026 01:20
@JPPhoto JPPhoto changed the title Gallery: Browse large collections with a sparse page cache Gallery: Browse large collections with a sparse page cache (infinite scrolling) Oct 5, 2026
@JPPhoto
JPPhoto requested a review from joshistoast October 8, 2026 03:23

@joshistoast joshistoast left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium regression on backward navigation

Refresh the preceding page after item relocation before section navigation.

Add coverage for stale cached ordering.
@JPPhoto
JPPhoto requested a review from joshistoast October 8, 2026 10:43
JPPhoto and others added 18 commits October 8, 2026 13:04
Keep page retry controls visible and keyboard navigation correct across unloaded gallery pages.
Fence stale range selection while sparse pages and ordered names hydrate.
Wait for a pending or failed next page before Preview steps past a page end, as for preceding pages.
Reconcile the selection's retained star flags with star patches and their rollbacks from any surface.
Stamp Gallery ranges with the current listing; only deletion successors keep the host's query.
Ctrl/Cmd-click and the toggle hotkey pass the page of the item that becomes primary, as clicks and ranges do.
Share the current-listing query between selection reducers.
Pin a reveal's verified page in the sparse listing so its fresher total replaces a stale count.
Indexed reveals skip the count bound; keyboard navigation keeps it.
Arrow steps wait for positions on pages still loading, and drop the step if the page settles without the item.
Navigation entries cover each run of subscribed pages instead of every position between distant ones.
…y whose successor is unloaded

Resolve the next primary by ref when its page has left the viewport, fenced by account, filter, and selection.
Lookups abort with the grid; a failed lookup still toggles.
…oll across count updates

Items that stay selected keep their retained star flags and pending patch records.
The picker reveals its highlight when it moves or reflows, not when a page changes the count.
… reads

Optimistic removals now lower the total on every cached page of a listing, and paginated pages check disagreeing totals with a refetch instead of flipping between clamped pages.
A verified Find in Gallery page opens past a stale count, a cancelled locator read is retried, and a failed page is read again when it returns to view.
… pages

Arrow steps into an unloaded page keep the origin page subscribed and check the persisted primary, which also anchors Shift+arrow runs.
Unloaded members of a starred-only selection count as starred for the star command and bulk menu; select-all stamps its page.
Reveals use Preview's index only within the grid's listing; evicted focus moves to a tile in view; the strip fallback stays off where no strip applies.
…e listing

Preview steps off sessions onto the listing's start, loads the page past a relocated page-end selection, swipes to a pending neighbor while relocating, shows absolute positions, and fences ordered refs on the listing.
The picker keeps subscribed pages while arrowing and holds its highlight by item key; ranked steps stamp the grid's board.
A deletion's successor still applies after the optimistic removal clears the host selection.
A deletion's successor applies only while the persisted selection is still what the removal left, and a confirmed delete lowers totals only on pages still holding the item.
Starred-only treats unloaded selected items as starred only for a selection made there; failed pages read without observers are forgotten; listing identity has one helper.
Far step origins no longer widen the grid's subscribed range, and each picker move reveals its highlight.
Editor routes grow about 37 KB of script for sparse paging and its fixes, with unchanged source sets and requests.
The rest of the growth since the last capture comes from main.
…ches/59558-1791579316/590ee2a71380917e73f55cb2e1c443fafd28ba46
…eir board, and cache virtualizer snapshots

A delete whose items the server rejects restores what the optimistic removal cleared, as a thrown failure does.
Images opened from the command palette navigate within their own board, and Preview shows no position until it locates them.
The virtualizer reads its memoized getters before copying the instance, so consecutive snapshots compare equal.
@github-actions github-actions Bot added the frontend-deps PRs that change frontend dependencies label Oct 9, 2026
@joshistoast
joshistoast enabled auto-merge (squash) October 9, 2026 22:47
@joshistoast
joshistoast merged commit eb25293 into invoke-ai:main Oct 9, 2026
16 of 17 checks passed
@JPPhoto
JPPhoto deleted the webv2-sparse-page-cache branch October 10, 2026 01:01
Pfannkuchensack added a commit to Pfannkuchensack/InvokeAI that referenced this pull request Oct 10, 2026
Ports invoke-ai#9683's gallery item location onto the gallery queries (ROW_NUMBER over both halves, in the name listing's order) and its router test onto the layer.
Re-locks uv.lock from main's with the layer's sqlalchemy, alembic and pymysql (uv 0.11.28, no user index).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api docs PRs that change docs frontend PRs that change frontend files frontend-deps PRs that change frontend dependencies python PRs that change python files python-tests PRs that change python tests services PRs that change app services

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants