Remove context usage from ReaderPage

In case many chapters are rendered, even just the HOC wrapper component re-render due to the context change increases the render time.

Thus, getting rid of these HOC wrapper re-renders by moving the context usage up to the ReaderViewer decreases the render time.
This commit is contained in:
schroda
2025-02-03 15:57:44 +01:00
parent b01b23b069
commit 2ec42d962a
10 changed files with 93 additions and 23 deletions

View File

@@ -81,6 +81,11 @@ const BaseReaderChapterViewer = ({
scrollIntoView, scrollIntoView,
setReaderStateChapters, setReaderStateChapters,
resumeMode, resumeMode,
customFilter,
shouldStretchPage,
scrollbarXSize,
scrollbarYSize,
readerNavBarWidth,
}: Pick< }: Pick<
ReaderStatePages, ReaderStatePages,
| 'currentPageIndex' | 'currentPageIndex'
@@ -400,6 +405,12 @@ const BaseReaderChapterViewer = ({
readingDirection={readingDirection} readingDirection={readingDirection}
pageScaleMode={pageScaleMode} pageScaleMode={pageScaleMode}
pageGap={pageGap} pageGap={pageGap}
customFilter={customFilter}
shouldStretchPage={shouldStretchPage}
readerWidth={readerWidth}
scrollbarXSize={scrollbarXSize}
scrollbarYSize={scrollbarYSize}
readerNavBarWidth={readerNavBarWidth}
/> />
{((!isContinuousReadingModeActive && isCurrentChapter) || {((!isContinuousReadingModeActive && isCurrentChapter) ||
(isContinuousReadingModeActive && (isInitialChapter || isTrailingChapter))) && ( (isContinuousReadingModeActive && (isInitialChapter || isTrailingChapter))) && (

View File

@@ -8,7 +8,6 @@
import { ComponentProps, memo, useCallback } from 'react'; import { ComponentProps, memo, useCallback } from 'react';
import { SpinnerImage } from '@/modules/core/components/SpinnerImage.tsx'; import { SpinnerImage } from '@/modules/core/components/SpinnerImage.tsx';
import { ReaderService } from '@/modules/reader/services/ReaderService.ts';
import { import {
IReaderSettings, IReaderSettings,
ReaderCustomFilter, ReaderCustomFilter,
@@ -21,10 +20,7 @@ import {
getReaderImageStyling, getReaderImageStyling,
} from '@/modules/reader/utils/ReaderPager.utils.tsx'; } from '@/modules/reader/utils/ReaderPager.utils.tsx';
import { applyStyles } from '@/modules/core/utils/ApplyStyles.ts'; import { applyStyles } from '@/modules/core/utils/ApplyStyles.ts';
import { useReaderScrollbarContext } from '@/modules/reader/contexts/ReaderScrollbarContext.tsx';
import { MediaQuery } from '@/modules/core/utils/MediaQuery.tsx'; import { MediaQuery } from '@/modules/core/utils/MediaQuery.tsx';
import { withPropsFrom } from '@/modules/core/hoc/withPropsFrom.tsx';
import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx';
import { NavbarContextType } from '@/modules/navigation-bar/NavigationBar.types.ts'; import { NavbarContextType } from '@/modules/navigation-bar/NavigationBar.types.ts';
const getCustomFilterString = (customFilter: ReaderCustomFilter): string => const getCustomFilterString = (customFilter: ReaderCustomFilter): string =>
@@ -171,17 +167,4 @@ const BaseReaderPage = ({
); );
}; };
export const ReaderPage = withPropsFrom( export const ReaderPage = memo(BaseReaderPage);
memo(BaseReaderPage),
[ReaderService.useSettingsWithoutDefaultFlag, useReaderScrollbarContext, useNavBarContext],
[
'readingMode',
'customFilter',
'pageScaleMode',
'shouldStretchPage',
'readerWidth',
'scrollbarXSize',
'scrollbarYSize',
'readerNavBarWidth',
],
);

View File

@@ -61,6 +61,8 @@ import {
getReaderChapterViewResumeMode, getReaderChapterViewResumeMode,
} from '@/modules/reader/utils/Reader.utils.ts'; } from '@/modules/reader/utils/Reader.utils.ts';
import { noOp } from '@/lib/HelperFunctions.ts'; import { noOp } from '@/lib/HelperFunctions.ts';
import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx';
import { NavbarContextType } from '@/modules/navigation-bar/NavigationBar.types.ts';
const READING_MODE_TO_IN_VIEWPORT_TYPE: Record<ReadingMode, PageInViewportType> = { const READING_MODE_TO_IN_VIEWPORT_TYPE: Record<ReadingMode, PageInViewportType> = {
[ReadingMode.SINGLE_PAGE]: PageInViewportType.X, [ReadingMode.SINGLE_PAGE]: PageInViewportType.X,
@@ -92,6 +94,9 @@ const BaseReaderViewer = forwardRef(
shouldOffsetDoubleSpreads, shouldOffsetDoubleSpreads,
imagePreLoadAmount, imagePreLoadAmount,
pageGap, pageGap,
customFilter,
shouldStretchPage,
readerNavBarWidth,
setScrollbarXSize, setScrollbarXSize,
setScrollbarYSize, setScrollbarYSize,
isVisible: isOverlayVisible, isVisible: isOverlayVisible,
@@ -129,8 +134,11 @@ const BaseReaderViewer = forwardRef(
| 'shouldOffsetDoubleSpreads' | 'shouldOffsetDoubleSpreads'
| 'imagePreLoadAmount' | 'imagePreLoadAmount'
| 'pageGap' | 'pageGap'
| 'customFilter'
| 'shouldStretchPage'
> & > &
Pick<TReaderScrollbarContext, 'setScrollbarXSize' | 'setScrollbarYSize'> & Pick<TReaderScrollbarContext, 'setScrollbarXSize' | 'setScrollbarYSize'> &
Pick<NavbarContextType, 'readerNavBarWidth'> &
Pick<TReaderOverlayContext, 'isVisible' | 'setIsVisible'> & Pick<TReaderOverlayContext, 'isVisible' | 'setIsVisible'> &
Pick< Pick<
ReaderStateChapters, ReaderStateChapters,
@@ -329,6 +337,11 @@ const BaseReaderViewer = forwardRef(
setTransitionPageMode={setTransitionPageMode} setTransitionPageMode={setTransitionPageMode}
pageGap={pageGap} pageGap={pageGap}
imagePreLoadAmount={imagePreLoadAmount} imagePreLoadAmount={imagePreLoadAmount}
customFilter={customFilter}
shouldStretchPage={shouldStretchPage}
scrollbarXSize={scrollbarXSize}
scrollbarYSize={scrollbarYSize}
readerNavBarWidth={readerNavBarWidth}
/> />
); );
})} })}
@@ -347,6 +360,7 @@ export const ReaderViewer = withPropsFrom(
() => ({ updateCurrentPageIndex: ReaderControls.useUpdateCurrentPageIndex() }), () => ({ updateCurrentPageIndex: ReaderControls.useUpdateCurrentPageIndex() }),
useReaderTapZoneContext, useReaderTapZoneContext,
useReaderStateChaptersContext, useReaderStateChaptersContext,
useNavBarContext,
], ],
[ [
'currentPageIndex', 'currentPageIndex',
@@ -367,6 +381,9 @@ export const ReaderViewer = withPropsFrom(
'shouldOffsetDoubleSpreads', 'shouldOffsetDoubleSpreads',
'imagePreLoadAmount', 'imagePreLoadAmount',
'pageGap', 'pageGap',
'customFilter',
'shouldStretchPage',
'readerNavBarWidth',
'transitionPageMode', 'transitionPageMode',
'setScrollbarXSize', 'setScrollbarXSize',
'setScrollbarYSize', 'setScrollbarYSize',

View File

@@ -26,6 +26,13 @@ const BaseBasePager = ({
isCurrentChapter, isCurrentChapter,
isPreviousChapter, isPreviousChapter,
isNextChapter, isNextChapter,
customFilter,
pageScaleMode,
shouldStretchPage,
readerWidth,
scrollbarXSize,
scrollbarYSize,
readerNavBarWidth,
}: Omit<ReaderPagerProps, 'pageLoadStates' | 'retryFailedPagesKeyPrefix'> & }: Omit<ReaderPagerProps, 'pageLoadStates' | 'retryFailedPagesKeyPrefix'> &
Pick<IReaderSettings, 'readingMode' | 'imagePreLoadAmount'> & { Pick<IReaderSettings, 'readingMode' | 'imagePreLoadAmount'> & {
createPage: ( createPage: (
@@ -34,6 +41,14 @@ const BaseBasePager = ({
shouldLoad: boolean, shouldLoad: boolean,
shouldDisplay: boolean, shouldDisplay: boolean,
setRef: (pagesIndex: number, element: HTMLElement | null) => void, setRef: (pagesIndex: number, element: HTMLElement | null) => void,
readingMode: ReaderPagerProps['readingMode'],
customFilter: ReaderPagerProps['customFilter'],
pageScaleMode: ReaderPagerProps['pageScaleMode'],
shouldStretchPage: ReaderPagerProps['shouldStretchPage'],
readerWidth: ReaderPagerProps['readerWidth'],
scrollbarXSize: ReaderPagerProps['scrollbarXSize'],
scrollbarYSize: ReaderPagerProps['scrollbarYSize'],
readerNavBarWidth: ReaderPagerProps['readerNavBarWidth'],
) => ReactNode; ) => ReactNode;
slots?: { boxProps?: BoxProps }; slots?: { boxProps?: BoxProps };
}) => { }) => {
@@ -93,6 +108,14 @@ const BaseBasePager = ({
pagesIndexesToRender.includes(pagesIndex), pagesIndexesToRender.includes(pagesIndex),
[ReaderTransitionPageMode.NONE, ReaderTransitionPageMode.BOTH].includes(transitionPageMode), [ReaderTransitionPageMode.NONE, ReaderTransitionPageMode.BOTH].includes(transitionPageMode),
setRef, setRef,
readingMode,
customFilter,
pageScaleMode,
shouldStretchPage,
readerWidth,
scrollbarXSize,
scrollbarYSize,
readerNavBarWidth,
), ),
)} )}
</Box> </Box>

View File

@@ -58,7 +58,7 @@ const BaseReaderDoublePagedPager = ({
return ( return (
<BasePager <BasePager
{...props} {...props}
createPage={(page, pagesIndex, shouldLoad, shouldDisplay) => { createPage={(page, pagesIndex, shouldLoad, shouldDisplay, _setRef, ...baseProps) => {
const { primary, secondary } = page; const { primary, secondary } = page;
const currentSecondaryPageIndex = getNextIndexFromPage(currentPage); const currentSecondaryPageIndex = getNextIndexFromPage(currentPage);
@@ -80,6 +80,7 @@ const BaseReaderDoublePagedPager = ({
shouldDisplay && isPrimaryPage && shouldLoad, shouldDisplay && isPrimaryPage && shouldLoad,
currentPage.primary.index, currentPage.primary.index,
totalPages, totalPages,
...baseProps,
pageLoadStates[primary.index].error ? retryFailedPagesKeyPrefix : undefined, pageLoadStates[primary.index].error ? retryFailedPagesKeyPrefix : undefined,
hasSecondaryPage ? getPagePosition('first', themeDirection, readingDirection) : undefined, hasSecondaryPage ? getPagePosition('first', themeDirection, readingDirection) : undefined,
hasSecondaryPage, hasSecondaryPage,
@@ -96,6 +97,7 @@ const BaseReaderDoublePagedPager = ({
shouldDisplay && isSecondaryPage && shouldLoad, shouldDisplay && isSecondaryPage && shouldLoad,
currentSecondaryPageIndex, currentSecondaryPageIndex,
totalPages, totalPages,
...baseProps,
pageLoadStates[secondary.index].error ? retryFailedPagesKeyPrefix : undefined, pageLoadStates[secondary.index].error ? retryFailedPagesKeyPrefix : undefined,
getPagePosition('second', themeDirection, readingDirection), getPagePosition('second', themeDirection, readingDirection),
true, true,

View File

@@ -29,7 +29,7 @@ const BaseReaderHorizontalPager = ({
return ( return (
<BasePager <BasePager
{...props} {...props}
createPage={(page, pagesIndex, shouldLoad, _, setRef) => createPage={(page, pagesIndex, shouldLoad, _, setRef, ...baseProps) =>
createReaderPage( createReaderPage(
page, page,
pagesIndex, pagesIndex,
@@ -41,6 +41,7 @@ const BaseReaderHorizontalPager = ({
true, true,
currentPageIndex, currentPageIndex,
totalPages, totalPages,
...baseProps,
pageLoadStates[page.primary.index].error ? retryFailedPagesKeyPrefix : undefined, pageLoadStates[page.primary.index].error ? retryFailedPagesKeyPrefix : undefined,
undefined, undefined,
undefined, undefined,

View File

@@ -23,7 +23,7 @@ const BaseReaderPagedPager = ({
return ( return (
<BasePager <BasePager
{...props} {...props}
createPage={(page, pagesIndex, shouldLoad, shouldDisplay) => createPage={(page, pagesIndex, shouldLoad, shouldDisplay, _setRef, ...baseProps) =>
createReaderPage( createReaderPage(
page, page,
pagesIndex, pagesIndex,
@@ -35,6 +35,7 @@ const BaseReaderPagedPager = ({
shouldDisplay && shouldLoad && currentPageIndex === page.primary.index, shouldDisplay && shouldLoad && currentPageIndex === page.primary.index,
currentPageIndex, currentPageIndex,
totalPages, totalPages,
...baseProps,
pageLoadStates[page.primary.index].error ? retryFailedPagesKeyPrefix : undefined, pageLoadStates[page.primary.index].error ? retryFailedPagesKeyPrefix : undefined,
) )
} }

View File

@@ -26,7 +26,7 @@ const BaseReaderVerticalPager = ({
return ( return (
<BasePager <BasePager
{...props} {...props}
createPage={(page, pagesIndex, shouldLoad, _, setRef) => createPage={(page, pagesIndex, shouldLoad, _, setRef, ...baseProps) =>
createReaderPage( createReaderPage(
page, page,
pagesIndex, pagesIndex,
@@ -38,6 +38,7 @@ const BaseReaderVerticalPager = ({
true, true,
currentPageIndex, currentPageIndex,
totalPages, totalPages,
...baseProps,
pageLoadStates[page.primary.index].error ? retryFailedPagesKeyPrefix : undefined, pageLoadStates[page.primary.index].error ? retryFailedPagesKeyPrefix : undefined,
undefined, undefined,
undefined, undefined,

View File

@@ -13,6 +13,7 @@ import { ReaderService } from '@/modules/reader/services/ReaderService.ts';
import { ReaderStatePages } from '@/modules/reader/types/ReaderProgressBar.types.ts'; import { ReaderStatePages } from '@/modules/reader/types/ReaderProgressBar.types.ts';
import { TMangaReader } from '@/modules/manga/Manga.types.ts'; import { TMangaReader } from '@/modules/manga/Manga.types.ts';
import { useAutomaticScrolling } from '@/modules/core/hooks/useAutomaticScrolling.ts'; import { useAutomaticScrolling } from '@/modules/core/hooks/useAutomaticScrolling.ts';
import { NavbarContextType } from '@/modules/navigation-bar/NavigationBar.types.ts';
export enum ProgressBarType { export enum ProgressBarType {
HIDDEN, HIDDEN,
@@ -259,7 +260,19 @@ export interface ReaderPagerProps
| 'pageLoadStates' | 'pageLoadStates'
| 'retryFailedPagesKeyPrefix' | 'retryFailedPagesKeyPrefix'
>, >,
Pick<IReaderSettings, 'readingMode' | 'imagePreLoadAmount' | 'readingDirection' | 'pageScaleMode' | 'pageGap'> { Pick<
IReaderSettings,
| 'readingMode'
| 'imagePreLoadAmount'
| 'readingDirection'
| 'pageScaleMode'
| 'pageGap'
| 'customFilter'
| 'shouldStretchPage'
| 'readerWidth'
>,
Pick<TReaderScrollbarContext, 'scrollbarXSize' | 'scrollbarYSize'>,
Pick<NavbarContextType, 'readerNavBarWidth'> {
onLoad?: (pagesIndex: number, url: string, isPrimary?: boolean) => void; onLoad?: (pagesIndex: number, url: string, isPrimary?: boolean) => void;
onError?: (pageIndex: number, url: string) => void; onError?: (pageIndex: number, url: string) => void;
imageRefs: MutableRefObject<(HTMLElement | null)[]>; imageRefs: MutableRefObject<(HTMLElement | null)[]>;

View File

@@ -16,6 +16,7 @@ import {
ReaderTransitionPageMode, ReaderTransitionPageMode,
ReadingDirection, ReadingDirection,
ReadingMode, ReadingMode,
TReaderScrollbarContext,
} from '@/modules/reader/types/Reader.types.ts'; } from '@/modules/reader/types/Reader.types.ts';
import { applyStyles } from '@/modules/core/utils/ApplyStyles.ts'; import { applyStyles } from '@/modules/core/utils/ApplyStyles.ts';
import { import {
@@ -33,6 +34,7 @@ import { DirectionOffset } from '@/Base.types.ts';
import { getOptionForDirection } from '@/modules/theme/services/ThemeCreator.ts'; import { getOptionForDirection } from '@/modules/theme/services/ThemeCreator.ts';
import { READING_DIRECTION_TO_THEME_DIRECTION } from '@/modules/reader/constants/ReaderSettings.constants.tsx'; import { READING_DIRECTION_TO_THEME_DIRECTION } from '@/modules/reader/constants/ReaderSettings.constants.tsx';
import { coerceIn } from '@/lib/HelperFunctions.ts'; import { coerceIn } from '@/lib/HelperFunctions.ts';
import { NavbarContextType } from '@/modules/navigation-bar/NavigationBar.types.ts';
type CSSObject = ReturnType<Theme['applyStyles']>; type CSSObject = ReturnType<Theme['applyStyles']>;
@@ -292,6 +294,14 @@ export const createReaderPage = (
display: boolean, display: boolean,
currentPageIndex: number, currentPageIndex: number,
totalPages: number, totalPages: number,
readingMode: IReaderSettings['readingMode'],
customFilter: IReaderSettings['customFilter'],
pageScaleMode: IReaderSettings['pageScaleMode'],
shouldStretchPage: IReaderSettings['shouldStretchPage'],
readerWidth: IReaderSettings['readerWidth'],
scrollbarXSize: TReaderScrollbarContext['scrollbarXSize'],
scrollbarYSize: TReaderScrollbarContext['scrollbarYSize'],
readerNavBarWidth: NavbarContextType['readerNavBarWidth'],
retryKeyPrefix?: string, retryKeyPrefix?: string,
position?: 'left' | 'right', position?: 'left' | 'right',
isDoublePage?: boolean, isDoublePage?: boolean,
@@ -316,6 +326,14 @@ export const createReaderPage = (
retryKeyPrefix={retryKeyPrefix} retryKeyPrefix={retryKeyPrefix}
marginTop={marginTop} marginTop={marginTop}
isLoaded={isLoaded} isLoaded={isLoaded}
readingMode={readingMode}
customFilter={customFilter}
pageScaleMode={pageScaleMode}
shouldStretchPage={shouldStretchPage}
readerWidth={readerWidth}
scrollbarXSize={scrollbarXSize}
scrollbarYSize={scrollbarYSize}
readerNavBarWidth={readerNavBarWidth}
/> />
); );