@@ -9,6 +9,7 @@ import { useTTS } from '@/contexts/TTSContext';
99import { usePDF } from '@/contexts/PDFContext' ;
1010import TTSPlayer from '@/components/player/TTSPlayer' ;
1111import { useConfig } from '@/contexts/ConfigContext' ;
12+ import { debounce } from '@/utils/pdf' ;
1213
1314interface PDFViewerProps {
1415 zoomLevel : number ;
@@ -17,6 +18,7 @@ interface PDFViewerProps {
1718export function PDFViewer ( { zoomLevel } : PDFViewerProps ) {
1819 const [ containerWidth , setContainerWidth ] = useState < number > ( 0 ) ;
1920 const containerRef = useRef < HTMLDivElement > ( null ) ;
21+ const scaleRef = useRef < number > ( 1 ) ;
2022
2123 // Config context
2224 const { viewType } = useConfig ( ) ;
@@ -124,7 +126,7 @@ export function PDFViewer({ zoomLevel }: PDFViewerProps) {
124126 ? ( currDocPage % 2 === 0 ? currDocPage : currDocPage + 1 )
125127 : null ;
126128
127- // Modify scale calculation to account for view type
129+ // Modify scale calculation to be more efficient
128130 const calculateScale = useCallback ( ( width = pageWidth , height = pageHeight ) : number => {
129131 const margin = viewType === 'dual' ? 48 : 24 ; // adjust margin based on view type
130132 const containerHeight = window . innerHeight - 100 ;
@@ -147,19 +149,34 @@ export function PDFViewer({ zoomLevel }: PDFViewerProps) {
147149 return baseScale * ( zoomLevel / 100 ) ;
148150 } , [ containerWidth , zoomLevel , pageWidth , pageHeight , viewType ] ) ;
149151
150- // Add resize observer effect
152+ // Add memoized scale to prevent unnecessary recalculations
153+ const currentScale = useCallback ( ( ) => {
154+ const newScale = calculateScale ( ) ;
155+ if ( Math . abs ( newScale - scaleRef . current ) > 0.01 ) {
156+ scaleRef . current = newScale ;
157+ }
158+ return scaleRef . current ;
159+ } , [ calculateScale ] ) ;
160+
161+ // Modify resize observer effect to use debouncing
151162 useEffect ( ( ) => {
152163 if ( ! containerRef . current ) return ;
153164
165+ const debouncedResize = debounce ( ( width : unknown ) => {
166+ setContainerWidth ( Number ( width ) ) ;
167+ } , 150 ) ; // 150ms debounce
168+
154169 const observer = new ResizeObserver ( entries => {
155170 const width = entries [ 0 ] ?. contentRect . width ;
156171 if ( width ) {
157- setContainerWidth ( width ) ;
172+ debouncedResize ( width ) ;
158173 }
159174 } ) ;
160175
161176 observer . observe ( containerRef . current ) ;
162- return ( ) => observer . disconnect ( ) ;
177+ return ( ) => {
178+ observer . disconnect ( ) ;
179+ } ;
163180 } , [ ] ) ;
164181
165182 return (
@@ -184,7 +201,7 @@ export function PDFViewer({ zoomLevel }: PDFViewerProps) {
184201 renderAnnotationLayer = { true }
185202 renderTextLayer = { i + 1 === currDocPage }
186203 className = "shadow-lg"
187- scale = { calculateScale ( ) }
204+ scale = { currentScale ( ) }
188205 onLoadSuccess = { ( page ) => {
189206 setPageWidth ( page . originalWidth ) ;
190207 setPageHeight ( page . originalHeight ) ;
@@ -202,7 +219,7 @@ export function PDFViewer({ zoomLevel }: PDFViewerProps) {
202219 renderAnnotationLayer = { true }
203220 renderTextLayer = { leftPage === currDocPage }
204221 className = "shadow-lg"
205- scale = { calculateScale ( ) }
222+ scale = { currentScale ( ) }
206223 onLoadSuccess = { ( page ) => {
207224 setPageWidth ( page . originalWidth ) ;
208225 setPageHeight ( page . originalHeight ) ;
@@ -216,7 +233,7 @@ export function PDFViewer({ zoomLevel }: PDFViewerProps) {
216233 renderAnnotationLayer = { true }
217234 renderTextLayer = { rightPage === currDocPage }
218235 className = "shadow-lg"
219- scale = { calculateScale ( ) }
236+ scale = { currentScale ( ) }
220237 onLoadSuccess = { ( page ) => {
221238 setPageWidth ( page . originalWidth ) ;
222239 setPageHeight ( page . originalHeight ) ;
0 commit comments