Skip to content

Commit 36fdbc2

Browse files
committed
Debounce PDF scale and extraction
1 parent ebff52d commit 36fdbc2

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

src/components/PDFViewer.tsx

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { useTTS } from '@/contexts/TTSContext';
99
import { usePDF } from '@/contexts/PDFContext';
1010
import TTSPlayer from '@/components/player/TTSPlayer';
1111
import { useConfig } from '@/contexts/ConfigContext';
12+
import { debounce } from '@/utils/pdf';
1213

1314
interface PDFViewerProps {
1415
zoomLevel: number;
@@ -17,6 +18,7 @@ interface PDFViewerProps {
1718
export 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);

src/utils/pdf.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,3 +259,15 @@ export function handleTextClick(
259259
}
260260
}
261261
}
262+
263+
// Add debounce utility at the top of the file
264+
export function debounce<T extends (...args: unknown[]) => unknown>(
265+
func: T,
266+
wait: number
267+
): (...args: Parameters<T>) => void {
268+
let timeout: NodeJS.Timeout;
269+
return (...args: Parameters<T>) => {
270+
clearTimeout(timeout);
271+
timeout = setTimeout(() => func(...args), wait);
272+
};
273+
}

0 commit comments

Comments
 (0)