If you’re looking to improve user-perceived load times of your web app and need a benchmark metric to gauge your progress, this blog will explain how measuring visual completeness can help focus your efforts on the optimizations that matter most.
But before we delve deeper into the topic of visual completeness, let’s do a quick overview of some key components in browser monitoring.
What is Real User Monitoring?
Real user monitoring (RUM), an important component of application performance monitoring (APM), focuses on how the end user of a system experiences the application interface. End users typically interact with a system via either a web or mobile application, or an edge/IoT device.
What is Browser Real User Monitoring?
What are Single-Page Applications?
Single-page applications have transformed the experience of building and consuming web apps in the last decade or so. They require no reloads when navigating within an application, allowing the user to go from one “virtual page” to another. By comparison, hard reloads in multiple-page applications have always disrupted user engagement.
Single-page applications use modern UI frameworks such as AngularJS, ReactJS, and Vue.
Navigation Timing and Resource Timing APIs
When you view a web page (such as this one), the browser maps the website name to an IP address. It then loads the page and starts to render it, adding elements to the page’s document object model (DOM). As it renders the page, the browser encounters code that asks it to load additional items, such as images, data (AJAX), styling information (CSS sheets), more code (JS libraries) and so on.
Almost all browser real user monitoring tools available today use navigation timing APIs for page-oriented metrics and resource timing APIs for metrics on individual document-dependent resource loads. These APIs are supported by all modern browsers—including Chrome, Firefox, and Safari—to monitor basic metrics on page loads, renditions and resource fetches. They can help you with questions like:
A. How much time did my page take to render content?
B. How much time did my page take to load overall?
C. How long did it take to load specific resources?
The following figure shows a breakdown of the numerous metrics offered by the navigation timing API at different steps of a browser processing a page load. The arrow labels indicate different metrics captured in the various steps.
Here’s a quick primer to help you understand these steps:
A. Prompt for unload: The browser prepares to navigate away from the existing page.
B. Redirect: Honors any redirects away from the desired address.
C. Internal cache lookup of the desired website address, in case the browser already knows where the website lives.
D. If the website address isn’t found in the cache, a domain name service (DNS) call is made to find it.
E. TCP network connection is established to send and receive data.
F. Request is made to fetch the desired web page.
G. The website or application server responds with the desired content (assuming the above steps are successful).
H. Processing of the downloaded content to render it on the browser.
Finally, the browser fires an onLoad event, a notification that all previous steps including processing are now complete. As an example, let’s revisit one of our questions above:
How much time did my page take to load overall?
Using the navigation timing from the chart above, we can compute this as:
pageLoadTime = loadEventEnd – unloadEventStart [Nav Timing v2, 2019]
pageLoadTime = loadEventEnd – navigationStart [obsolete, Nav Timing v1, 2012]
Why Browser Reported Metrics Are Insufficient
With the help of timing APIs, we can easily compute our page load time. But unfortunately this approach might not be enough, especially if you’re a stakeholder in a single-page application. Why? Because after the browser receives a response and starts to render content—but potentially long before the loadEventEnd is recorded—a site visitor might believe the app is ready to use. The user perceives the application is usable much earlier than the time the browser thinks the load is finished. This might be because the visible content “above the fold” or in the viewport may have loaded and the user might be thinking, “Well, I can start using this page now.”
As mentioned above, the term visually complete is the point in time when the browser has finished rendering viewable content in the viewport as compared to the entire page. For example, the visually complete time (VCT) for Page A (below) is 2 seconds. But for Page B, it’s 4 seconds.
As a stakeholder in your web app, it might make more sense to invest your engineering effort in optimizing your pages’ visually complete time, rather than the traditional page load time.
Bad vs. Good Approaches to Visual Completeness
One seemingly naive and unscalable (but highly accurate) approach to compute VCT is to use screenshots and image processing to determine when images stop changing for a certain amount of time. Unfortunately, this approach won’t scale in real-world production environments.
AppDynamics recently launched its awesome Browser RUM feature, which not only lets you view the metric for your page views, but also change to VCT (from the traditional end user response time) as the main metric in all out-of-box visualizations. AppDynamics utilizes a proprietary algorithm to calculate VCT, using the last visual change to the page in a browser window’s viewport. Go here to learn more about Visually Complete Time for SPA.