When a recipient opens a Dataroom link, they shouldn't see “loading.” They should see the document. The gap between those two outcomes is everything: it's the difference between a deal that progresses and a tab that closes.
For most of 2025, our viewer first paint hovered around 480ms — fast by general web standards, slow for a document opening on a desk. By mid-2026 we cut it to 90ms. Here's how the work actually went.
The four bottlenecks
We profiled 100,000 sessions and bucketed first-paint into four causes: TLS & route setup, HTML hydration, asset fetching, and PDF.js initialization. The slowest of the four was always different per session, so we had to fix all of them.
- TLS & route: cold POPs and cross-region redirects added ~80ms.
- Hydration: React + RSC payloads were ~140KB gzipped; ~70ms to parse.
- Assets: PDF.js worker + sandbox + cmap files were a sequential fetch.
- PDF init: structured cloning the first page back to the main thread.
What worked
We pinned the viewer to a single domain on Cloudflare with HTTP/3 0-RTT enabled. We moved the route to an edge handler that serves a pre-rendered HTML skeleton with the document metadata inlined. The skeleton paints in under 30ms in 95% of sessions.
We shrunk the React bundle by 38% by removing client-side i18n (we ship locale-specific bundles instead) and replacing the PDF.js text layer with a custom render that doesn't need the sandbox or cmap files on the first paint.
The PDF.js worker pre-warms during the skeleton paint. By the time the user's eyes have tracked from the URL bar to the document area, the first page bitmap is already in the main thread.
Why it mattered for retention
Speed changes behavior. We A/B tested the new viewer against the old one for two weeks. The new viewer had:
- +18% session duration on first opens.
- +34% “forward to colleague” rate.
- +11% e-signature completion (signers don't bail mid-load).
90ms isn't a benchmark. It's a feeling — “the document opened” instead of “the document is opening.” That feeling shows up in every downstream metric we care about.
What's next
We're measuring streaming first-page bitmaps to see if we can get the first visible content to under 60ms. The honest answer is we don't know if it's perceptible past that point. But we're going to find out.