From 685bd9b9da764a89f1f1d488e6e16a7806c23c35 Mon Sep 17 00:00:00 2001 From: frozenKelp Date: Tue, 9 Jun 2026 16:15:31 +0530 Subject: [PATCH] fix: revoke page blob URLs on chapter change and reader close --- src/lib/components/reader/Reader.svelte | 7 ++++++- src/lib/components/reader/lib/chapterLoader.ts | 17 ++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/lib/components/reader/Reader.svelte b/src/lib/components/reader/Reader.svelte index ee6c45b..5c6953e 100644 --- a/src/lib/components/reader/Reader.svelte +++ b/src/lib/components/reader/Reader.svelte @@ -14,6 +14,7 @@ import { historyState } from "$lib/state/history.svelte"; import { getAdapter } from "$lib/request-manager"; import { setReading, clearReading } from "$lib/core/discord"; + import { revokeBlobUrl } from "$lib/core/cache/imageCache"; import type { ReaderSettings } from "$lib/state/reader.svelte"; import ReaderControls from "$lib/components/reader/ReaderControls.svelte"; import PageView from "$lib/components/reader/PageView.svelte"; @@ -216,9 +217,13 @@ ? () => goForward(style, adjacent, lastPage, maybeMarkCurrentRead, startAtLast) : () => goBack(style, adjacent, startAtLast)); - // clear Discord presence before closing + // clear Discord presence and free page blob textures before closing function handleCloseReader() { clearReading().catch(() => {}); + for (const url of readerState.pageUrls) revokeBlobUrl(url); + for (const strip of readerState.stripChapters) { + for (const url of strip.urls) revokeBlobUrl(url); + } readerState.closeReader(); } diff --git a/src/lib/components/reader/lib/chapterLoader.ts b/src/lib/components/reader/lib/chapterLoader.ts index 16c6f62..9eee8ea 100644 --- a/src/lib/components/reader/lib/chapterLoader.ts +++ b/src/lib/components/reader/lib/chapterLoader.ts @@ -1,7 +1,7 @@ -import { readerState } from "$lib/state/reader.svelte"; -import { fetchPages } from "./pageLoader"; -import { cancelQueuedFetches } from "$lib/core/cache/imageCache"; -import { clearResolvedUrlCache } from "$lib/core/cache/pageCache"; +import { readerState } from "$lib/state/reader.svelte"; +import { fetchPages } from "./pageLoader"; +import { cancelQueuedFetches, revokeBlobUrl } from "$lib/core/cache/imageCache"; +import { clearResolvedUrlCache } from "$lib/core/cache/pageCache"; export function scheduleResumeDismiss() { setTimeout(() => { readerState.resumeFading = true; }, 1500); @@ -21,7 +21,14 @@ export async function loadChapter( abortCtrl.current = ctrl; cancelQueuedFetches(); - if (useBlob) clearResolvedUrlCache(); + if (useBlob) { + clearResolvedUrlCache(); + // revoke blob URLs for all loaded pages so the GPU can release their textures + for (const url of readerState.pageUrls) revokeBlobUrl(url); + for (const strip of readerState.stripChapters) { + for (const url of strip.urls) revokeBlobUrl(url); + } + } startAtLastPage.current = false; markedRead.clear();