Why TTVC beats a single-milestone view

Performance teams often anchor on a handful of load milestones—TTFB, FCP, LCP, or TTI. Each has a place, but each tells only part of the story. Focusing narrowly on LCP, for example, led Dropbox to prioritize the largest visible element at the expense of secondary content, sometimes causing layout shifts and unstable pages.

Time to Visually Complete (TTVC) takes a different approach: a page is visually complete when no further visible paint events occur without user input. It's a straightforward concept, meaningful to users, and it implicitly rewards layout stability. At Dropbox, adopting TTVC as the primary metric helped align teams on a more objective, user-focused definition of load performance.

Field measurement without a lab

Lab tests give you controlled, reproducible numbers, but they can't capture the variability of real devices and network conditions. Field measurement—Real User Monitoring—does, but existing tools didn't offer TTVC in the field. The gap: browsers don't report when visual completeness happens, so the metric couldn't be captured retroactively from real sessions.

The solution combines two modern browser APIs, MutationObserver and IntersectionObserver, to approximate this milestone with minimal overhead. The resulting open-source library, @dropbox/ttvc, implements three core pieces:

  • requestAllIdleCallback: Wraps requestIdleCallback with load-event instrumentation to detect periods when both network and main thread are idle.
  • InViewportMutationObserver: Uses MutationObserver to enqueue DOM mutations, then IntersectionObserver to filter to those visible in the viewport, keeping the most recent timestamp.
  • InViewportImageObserver: Similar structure, but source events come from a capture-phase load listener on the document, filtered through IntersectionObserver.

Observing DOM mutations and image loads covers the vast majority of visible updates in practice, while keeping overhead low. The library records the latest visible update timestamp, and reports it once the browser has been idle for at least two seconds.

Handling edge cases

Field conditions introduce ambiguity that lab tests avoid. The library accounts for them explicitly:

  • User interaction: After a click, touch, or keydown, visual changes may result from user input, so the measurement is aborted and TTVC is not reported. Scroll events are excluded since programmatic scrolling on load is common.
  • Background tabs: If a page loads in a background tab, execution and resource fetching may be throttled. Rather than report misleadingly long times, the measurement is discarded.
  • Viewport differences: Because IntersectionObserver tracks what's actually visible, the measured content varies by device and scroll position—which is the point of field testing.

Using the library

The package is available on npm and GitHub. The API has two primary methods: call init() early in page load to start instrumentation, then subscribe to metric events with getTTVC().

CPU and asset loading are monitored automatically. For AJAX-driven pages, two helper functions let you instrument requests to avoid premature idle detection, for example wrapping the native fetch API.

TTVC also maps cleanly onto single-page app navigation. The library supports triggering a fresh measurement when a new SPA navigation begins, so the same metric works for both traditional loads and client-side routes. Full API details and usage patterns are in the official documentation.

Using TTVC in production

Until browsers can report TTVC natively, JavaScript is the only way to compute the metric in real time. Dropbox has packaged its implementation as @dropbox/ttvc, available on npm and GitHub, so that other teams can integrate this objective, user-focused milestone into their own performance monitoring pipelines.

The library is still beta software, but Dropbox has already begun using TTVC targets in its quarterly planning. The team welcomes bug reports and contributions aimed at improving the accuracy and performance of the library.

The path forward

A browser-native TTVC implementation would always be faster and more accurate than anything computed with JavaScript. Dropbox hopes browser vendors will eventually consider reporting TTVC directly. In the meantime, the open-source library offers a practical way to measure the metric today.

Footnotes:

1 Nielsen Norman Group on response-time limits: https://www.nngroup.com/articles/response-times-3-important-limits/
2 Tracking only DOM mutations could report TTVC prematurely on pages with abundant image content, such as a photo gallery or the Netflix homepage.