From ad7e7f17716cb5c63b8e4333cb831520a46a6b89 Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Thu, 4 Jun 2026 15:32:11 +0200 Subject: [PATCH] Improve image preloading of previous/next chapter pages The previous/next chapter only ever preloaded the first page, ignoring available preload contingent. I.e., if all leading/trailing pages of the current chapter were loaded, the reader did not keep preloading the previous/next chapters pages --- CHANGELOG.md | 1 + src/features/reader/Reader.types.ts | 1 + .../reader/viewer/ReaderChapterViewer.tsx | 2 ++ src/features/reader/viewer/ReaderViewer.tsx | 28 +++++++++++++++++++ .../reader/viewer/pager/ReaderPager.utils.tsx | 6 ++-- .../viewer/pager/components/BasePager.tsx | 13 ++++++++- 6 files changed, 48 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a40d82c..75b18b96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). - (**Source/Extension**) Rename language "All" to "Multi" - (**Reader**) Simplify changing settings in desktop sidebar - (**Reader**) Ignore tap zone clicks while window does not have focus +- (**Reader**) Improve preloading pages from the previous/next chapter ### Fixed diff --git a/src/features/reader/Reader.types.ts b/src/features/reader/Reader.types.ts index db1f4b5e..0e97c998 100644 --- a/src/features/reader/Reader.types.ts +++ b/src/features/reader/Reader.types.ts @@ -363,6 +363,7 @@ export interface ReaderPagerProps resumeMode: ReaderResumeMode; handleAsInitialRender: boolean; ref?: Ref; + currentChapterRemainingPages: number; } export enum PageInViewportType { diff --git a/src/features/reader/viewer/ReaderChapterViewer.tsx b/src/features/reader/viewer/ReaderChapterViewer.tsx index 1d30128c..5ef120e5 100644 --- a/src/features/reader/viewer/ReaderChapterViewer.tsx +++ b/src/features/reader/viewer/ReaderChapterViewer.tsx @@ -81,6 +81,7 @@ const BaseReaderChapterViewer = ({ minWidth, minHeight, scrollElement, + currentChapterRemainingPages, }: Pick & Omit & Pick< @@ -433,6 +434,7 @@ const BaseReaderChapterViewer = ({ isPreloadMode={isPreloadMode} resumeMode={resumeMode} handleAsInitialRender={scrollIntoView} + currentChapterRemainingPages={currentChapterRemainingPages} /> {showNextTransitionPage && ( diff --git a/src/features/reader/viewer/ReaderViewer.tsx b/src/features/reader/viewer/ReaderViewer.tsx index e4fb0a63..8d0b37f8 100644 --- a/src/features/reader/viewer/ReaderViewer.tsx +++ b/src/features/reader/viewer/ReaderViewer.tsx @@ -51,6 +51,7 @@ import { useReaderSettingsStore, } from '@/features/reader/stores/ReaderStore.ts'; import { STABLE_EMPTY_OBJECT } from '@/base/Base.constants.ts'; +import { getPage } from '@/features/reader/overlay/progress-bar/ReaderProgressBar.utils.tsx'; const READING_MODE_TO_IN_VIEWPORT_TYPE: Record = { [ReadingMode.SINGLE_PAGE]: PageInViewportType.X, @@ -290,10 +291,13 @@ const BaseReaderViewer = ({ const isCurrentChapter = chapter.id === currentChapter.id; const isPreviousChapter = chapter.id === chaptersToRender[currentChapterIndex + 1]?.id; const isNextChapter = chapter.id === chaptersToRender[currentChapterIndex - 1]?.id; + const isAdjacentChapterToCurrentChapter = isPreviousChapter || isNextChapter; + const isLeadingChapter = initialChapter.sourceOrder > chapter.sourceOrder; const isTrailingChapter = initialChapter.sourceOrder < chapter.sourceOrder; const isLastLeadingChapter = visibleChapters.lastLeadingChapterSourceOrder === chapter.sourceOrder; const isLastTrailingChapter = visibleChapters.lastTrailingChapterSourceOrder === chapter.sourceOrder; + const isPreloadMode = (isLastLeadingChapter && visibleChapters.isLeadingChapterPreloadMode) || (isLastTrailingChapter && visibleChapters.isTrailingChapterPreloadMode); @@ -306,6 +310,29 @@ const BaseReaderViewer = ({ const isChapterSizeSourceChapter = chapter.id === minChapterSizeSourceChapterId; + const currentChapterCurrentPageIndex = isAdjacentChapterToCurrentChapter + ? getReaderChapterViewerCurrentPageIndex( + currentPageIndex, + currentChapter, + currentChapter, + true, + isCurrentChapterReady, + initialChapter.sourceOrder > currentChapter.sourceOrder, + initialChapter.sourceOrder < currentChapter.sourceOrder, + visibleChapters, + ) + : -1; + const currentChapterCurrentPagesIndex = isAdjacentChapterToCurrentChapter + ? getPage(currentChapterCurrentPageIndex, pages).pagesIndex + : -1; + + const currentChapterRemainingLeadingPages = currentChapterCurrentPagesIndex; + const currentChapterRemainingTrailingPages = pages.length - 1 - currentChapterCurrentPagesIndex; + + const currentChapterRemainingPages = isNextChapter + ? currentChapterRemainingTrailingPages + : currentChapterRemainingLeadingPages; + return ( { }; const MIN_PREVIOUS_NEXT_CHAPTER_IMAGE_LOAD_AMOUNT = 0; -const MAX_PREVIOUS_NEXT_CHAPTER_IMAGE_LOAD_AMOUNT = 1; const getImagePreLoadAmount = ( isCurrentChapter: boolean, isPreviousChapter: boolean, isNextChapter: boolean, imagePreLoadAmount: number, + currentChapterRemainingPages: number, ): number => { if (isCurrentChapter) { return imagePreLoadAmount; @@ -546,7 +546,7 @@ const getImagePreLoadAmount = ( if (isPreviousChapter || isNextChapter) { return coerceIn( - MAX_PREVIOUS_NEXT_CHAPTER_IMAGE_LOAD_AMOUNT, + imagePreLoadAmount - currentChapterRemainingPages, MIN_PREVIOUS_NEXT_CHAPTER_IMAGE_LOAD_AMOUNT, imagePreLoadAmount, ); @@ -557,6 +557,7 @@ const getImagePreLoadAmount = ( const PREVIOUS_IMAGE_LOAD_AMOUNT = 2; export const getPageIndexesToLoad = ( + currentChapterRemainingPages: number, currentPageIndex: number, pages: ReaderStatePages['pages'], previousCurrentPageIndex: number, @@ -576,6 +577,7 @@ export const getPageIndexesToLoad = ( isPreviousChapter, isNextChapter, imagePreLoadAmount, + currentChapterRemainingPages, ); const directionInvert = previousCurrentPageIndex <= currentPageIndex && !isPreviousChapter ? 1 : -1; diff --git a/src/features/reader/viewer/pager/components/BasePager.tsx b/src/features/reader/viewer/pager/components/BasePager.tsx index 371f867f..9c6c232a 100644 --- a/src/features/reader/viewer/pager/components/BasePager.tsx +++ b/src/features/reader/viewer/pager/components/BasePager.tsx @@ -40,6 +40,7 @@ const BaseBasePager = ({ resumeMode, handleAsInitialRender, ref, + currentChapterRemainingPages, }: Omit & Pick & { createPage: ( @@ -67,6 +68,7 @@ const BaseBasePager = ({ const pagesIndexesToRender = useMemo( () => getPageIndexesToLoad( + currentChapterRemainingPages, currentPageIndex, pages, previousCurrentPageIndex.current, @@ -76,7 +78,16 @@ const BaseBasePager = ({ isPreviousChapter, isNextChapter, ), - [currentPageIndex, pages, imagePreLoadAmount, readingMode, isCurrentChapter, isPreviousChapter, isNextChapter], + [ + currentChapterRemainingPages, + currentPageIndex, + pages, + imagePreLoadAmount, + readingMode, + isCurrentChapter, + isPreviousChapter, + isNextChapter, + ], ); useEffect(() => { if (isCurrentChapter) {