Your PDF Viewer Works Until Someone Opens a 300-Page File
A PDF viewer can look perfectly fine during development.
You open a five-page document. The pages render correctly. Zoom works. Scrolling feels smooth.
Then someone uploads a 300-page technical manual, a large contract, or a scanned report with high-resolution images. Suddenly, the experience changes.
The browser becomes sluggish. Pages take too long to appear. Zooming feels delayed. Sometimes the interface becomes almost unusable.
The problem is not always the PDF itself. Sometimes, it is how the viewer handles rendering, memory, and the browser viewport.
Why large PDFs are different
A PDF is not simply a collection of images waiting to be displayed.
A document may contain text instructions, vector graphics, embedded fonts, images, annotations, and other objects. Rendering those elements requires work, and the cost varies significantly from one page to another.
A 300-page text document may behave very differently from a 30-page architectural drawing containing enormous images.
*This is why page count alone is not a reliable measure of rendering cost. *
Do not render every page at full resolution immediately
One common mistake is trying to render the entire document as soon as it loads.
If each page creates a canvas, that can quickly increase memory consumption. High-resolution canvases are particularly expensive.
A rough estimate for an RGBA canvas is:
width × height × 4 bytes
For example, a canvas measuring 1,500 × 2,000 pixels requires approximately 11.4 MiB of pixel memory before accounting for additional browser and rendering overhead.
Multiply that by dozens or hundreds of pages, and the cost becomes significant.
A better approach: Render visible pages first, then render nearby pages as the user scrolls. Release or reuse resources when appropriate.
Virtualisation and lazy rendering can help, but they should be designed around the viewer's actual interaction model.
Treat Zoom as a rendering problem
Zooming is more complicated than changing the CSS width of a canvas.
If the display size changes but the underlying rendering resolution does not, text and graphics may become blurry.
If every tiny zoom movement triggers an expensive rendering operation, the interface can feel slow.
A practical strategy is to separate the immediate visual response from the more expensive rendering work:
Update the viewport responsively.
Avoid triggering a new render for every intermediate input event.
Cancel obsolete rendering tasks where the rendering library supports it.
Render at the appropriate resolution after the zoom interaction settles.
The goal is to keep the interface responsive without sacrificing visual quality.
Keep the layers aligned.
A modern PDF viewer often needs more than a canvas.
It may also have a text layer for selection and search, an annotation layer for interactive elements, and controls for navigation.
These layers must agree on page dimensions, scale, rotation, and position.
If they do not, users may see text that is difficult to select, highlights that miss their targets, or annotations that drift after zooming.
Whenever the viewport changes, check that every interactive layer uses consistent coordinate transformations.
Measure the right things
Instead of testing only whether a document opens, measure the following:
Time until the first page becomes visible.
Time required to render a typical page. Responsiveness during rapid zooming and scrolling. Memory usage with large documents. Behaviour when users jump directly to a distant page. Recovery after switching between documents.
Test with different document types, not just different page counts.
A large scanned document, a vector-heavy engineering drawing, and a text-heavy report can expose very different problems.
Try it in a real React application
If you are building a document-heavy application, you do not necessarily need to build the entire viewing interface from scratch.
We have been working on TeamSync PDF Viewer, an open-source PDF viewer SDK for React applications, with document rendering, search, annotations, and other document interaction features.
GitHub repository: https://github.com/angelbot-ai/TeamSync-PDF-Viewer
You can inspect the implementation, try the project, and explore the integration options before deciding whether it fits your application.
One question for other developers
What becomes your biggest bottleneck when a PDF viewer handles large documents: canvas memory, rendering time, text-layer alignment, or zoom responsiveness?
I would be interested in hearing what you have encountered in production.
If the project looks useful for your work, consider giving the repository a star. If you try it, feedback and reproducible issues are especially valuable to an open-source project.
Top comments (1)
Nice post. The "page count is a poor predictor" point is the one I'd underline.
For us the bottleneck is memory, and almost always on scans. A 300-page text PDF is cheap next to a 20-page scan where every page is one big JPEG. The decoded image is what eats the budget, not the vector content, so we now check whether a page is a single image before deciding how to render it.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.