quintodrome/ui
Deluan Quintão 33e20d355e
fix(ui): cancel in-flight image requests on pagination, cache across remounts (#5249)
* feat(ui): cancel in-flight image requests on pagination and cache across remounts

When paginating quickly through list/grid views, image requests for previous
pages were never canceled, queuing on the server and blocking new images.
This adds a useImageUrl hook that loads images via fetch() with AbortController,
so requests are canceled when components unmount. A module-level cache (URL →
blob URL) with reference counting ensures React Admin refreshes display images
instantly without re-fetching.

* feat(ui): update AlbumListPagination to conditionally render based on albumListType

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(ui): abort all in-flight image fetches on pagination change

Pagination component now watches page/perPage via useListContext and
calls abortAllInFlight() when either changes, freeing the browser
connection pool immediately for the next page's data request.

Also adds empty placeholder style to CoverArtAvatar so it renders as a
clean transparent area while loading instead of the default person icon.

* Revert "feat(ui): abort all in-flight image fetches on pagination change"

This reverts commit 3bc09f9d0374aa63572a381e38a30e2f2cec4da8.

* fix(ui): limit concurrent image fetches to prevent connection pool saturation

With <img src>, the browser prioritizes API requests over image loads.
With fetch(), all requests compete equally for the HTTP/1.1 connection
pool (6 per origin), causing API requests to queue behind images and
making pagination feel unresponsive. Caps concurrent image fetches at
4 with a pending queue, leaving connections free for API requests.
Queued fetches for unmounted components are removed without ever
hitting the network.

* fix(ui): fix queued fetch not aborted on unmount

Set queued=false when doFetch executes from the pending queue, so
cleanup correctly calls controller.abort() instead of searching an
already-drained queue.

---------

Signed-off-by: Deluan <deluan@navidrome.org>
2026-03-25 21:30:40 -04:00
..
bin fix(ui): service worker crashing on precacheAndRoute (#3528) 2024-12-08 17:43:34 -05:00
build ci: create versions with goreleaser 2020-01-26 20:09:25 -05:00
public feat(ui): Add Nautiline like theme (#4909) 2026-01-20 12:11:47 -05:00
src fix(ui): cancel in-flight image requests on pagination, cache across remounts (#5249) 2026-03-25 21:30:40 -04:00
.eslintignore test: update test command to run without watch mode 2025-05-24 22:58:04 -04:00
.eslintrc build(ui): migrate from CRA/Jest to Vite/Vitest (#3311) 2024-09-28 11:54:36 -04:00
.gitignore fix(ui): PWA not updating properly in new Vite config (#3493) 2024-11-30 10:33:16 -05:00
embed.go Fix build 2021-07-20 20:22:15 -04:00
index.html feat(plugins): add JSONForms-based plugin configuration UI (#4911) 2026-01-19 20:51:00 -05:00
package-lock.json chore(deps): bump picomatch in /ui (#5248) 2026-03-25 18:24:46 -04:00
package.json fix(player): fix play next after transcoding changes 2026-03-17 12:15:03 -04:00
prettier.config.js build(ui): migrate from CRA/Jest to Vite/Vitest (#3311) 2024-09-28 11:54:36 -04:00
tsconfig.app.json build(ui): migrate from CRA/Jest to Vite/Vitest (#3311) 2024-09-28 11:54:36 -04:00
tsconfig.json build(ui): migrate from CRA/Jest to Vite/Vitest (#3311) 2024-09-28 11:54:36 -04:00
tsconfig.node.json build(ui): migrate from CRA/Jest to Vite/Vitest (#3311) 2024-09-28 11:54:36 -04:00
vite.config.js feat(plugins): add JSONForms-based plugin configuration UI (#4911) 2026-01-19 20:51:00 -05:00