[PDF Reader] Text selection becomes progressively laggy after page navigation on high-DPI Windows display (200% scaling)
Describe the bug
Text selection in the built-in PDF reader becomes progressively laggy after navigating through multiple pages when the PDF is zoomed in on a high-DPI Windows display. The lag worsens as more pages are navigated.
Steps to reproduce
- Open a multi-page PDF in Zotero's built-in reader
- Zoom in to 150% or higher (using the PDF reader's zoom control)
- Select text on the current page → selection is smooth
- Navigate forward/backward through several pages
- Try selecting text again → selection is now severely laggy, cursor stutters
- Continue navigating more pages → lag gets progressively worse
Expected behavior
Text selection should remain smooth regardless of how many pages have been navigated.
Actual behavior
Text layer DOM from previously viewed pages appears to accumulate without proper cleanup, causing CPU-side hit-testing to traverse an ever-growing number of <span> elements. Under 200% Windows display scaling, each page generates significantly more spans, compounding the problem.
Key observations
- ✅ Smooth: 200% Windows scaling + PDF at default zoom (fit page) — even after navigating many pages
- ✅ Smooth: 100% Windows scaling + PDF at any zoom level — even after navigating many pages
- ❌ Laggy: 200% Windows scaling + PDF zoomed in + after navigating several pages
- The more pages navigated, the worse the lag
- Zooming out and back in temporarily helps (likely forces text layer rebuild)
Environment
| OS | Windows 11 |
| Zotero | 9.0.6 |
| pdf.js | 5.4.0 (from resource/reader/pdf/build/pdf.mjs) |
| Display | 16" 3200×2000 |
| Windows scaling | 200% |
| CPU | Intel Core Ultra 9 185H |
| GPU | Intel Arc Graphics + NVIDIA RTX 4060 Laptop |
Workarounds attempted
| Approach | Result |
|---|---|
| Safe Mode (all plugins disabled) | ❌ Still reproduces |
layers.acceleration.disabled = false |
❌ No effect |
gfx.webrender.all = true |
❌ No effect |
layout.css.devPixelsPerPx = 1.0 / 2.0 |
❌ No effect |
general.smoothScroll = false |
❌ No effect |
| Dedicated GPU (RTX 4060) via Windows Graphics Settings | ❌ No effect |
CSS injection (content-visibility: auto, contain: layout style paint) via userContent.css |
❌ No effect |
| CPU priority / affinity adjustment | ❌ No meaningful effect |
| "Override high DPI scaling behavior → System" (Compatibility settings) | ✅ Smooth at any zoom — but UI becomes blurry due to Windows bitmap stretching |
Root cause analysis
DOM hit-testing in browsers is a CPU-only, single-threaded operation that cannot be offloaded to GPU. The issue appears to be a compounding effect of:
- High DPI → more
<span>elements per page in the text layer - PDF zoom-in → larger visible text area with more spans
- Page navigation → text layer DOM from previously viewed pages may not be cleaned up, causing accumulation
This creates an ever-growing DOM tree that the browser must traverse on every mouse movement for hit-testing.
Related
- mozilla/pdf.js#15131 — "Don't recompute the text layer when zooming" (fixed via PR #15722)
- zotero/zotero#4809 — Slow PDF rendering (open)
Suggestions
- Investigate whether text layer DOM from previously viewed pages is properly cleaned up
- Consider virtualizing off-screen text layer spans (
pointer-events: noneor removal) - Optimize text layer DOM structure for high-DPI scenarios
Source: zotero/zotero