Using WebPageTest - Notes from the book by Marcel Duran; Andy Davies; Rick Viscomi

Finding the right metrics

“For example, think about the last time you read a news article online. As the page loaded, what were you waiting for? The most probable answer is that you were waiting for the text content of the article itself. The DOMContentLoaded event, also reported by WebPageTest, is like the load event except that it doesn’t wait for images to be displayed. The timing of this event may be a more appropriate metric to track because the time to load the ancillary images should not necessarily be taken into account. The default metric is not always the most relevant to the page in test.”

Application-Specific Metrics

“You can log custom application-specific metrics to WebPageTest with the User Timing API. Using the YouTube example, when the video starts to play, that moment in time can be marked with a line of JavaScript:

performance.mark(‘playback-start’);

WebPageTest will capture these marks and make them available in test results.”

Synthetic testing vs RUM

Synthetic testing is done using tools like webpagestest.com where you control the testing conditions. RUM (Real Time User Monitoring) is happening in real users' browsers, in conditions we do not control.

The advantage of synthetic testing is that you can reliably replicate problems and debug them. The advantage of RUM is that it gives you a good image of how your app performs across many browsers, devices, network conditions.

They are both valuable and are used together in tunning performance. But for determining the overall speed of a page RUM is the best solution because it paints the story of real users.

Finding the culprits that slow down a web page

It’s a good idea to run a test multiple times and look at a median result to account for server or network fluctuations. You can see a median result sorted by some specific metric by attaching a parameter to the URL and choosing a specific metric from a long list of available options: https://www.webpagetest.org/result/210107_Di1D_212abc47a1a07af66803ff6c3aef646b/?medianMetric=render

Reading the waterfall diagram

The diagram visualizes the network activity. Each request has 5 main phases:

  • DNS lookup The time to resolve a domain name like tradus.com to its IP address; it’s similar to looking up a phone number in the phone book

  • Initial connection How long it takes for the browser to establish a connection; in the earlier metaphor, how long it takes until someone picks up the phone when you call them

  • SSL negotiation The time for the browser and the server to setup secure communication

  • Time to First Byte (TTFB) The time it takes for the server to prepare the response to the request.

  • Content Download The time it takes the server to send the entire content of the response.

There are several important page level events:

  • First paint The time it takes the browser to first start painting to the screen

  • DOM Content Loaded The time it takes the browser to build the DOM from the HTML text

  • On Load The time it takes the browser to build the DOM and download all images

  • First Contentful Paint (FCP) First Contentful Paint is an important, user-centric metric for measuring perceived load speed because it marks the first point in the page load timeline where the user can see anything on the screen—a fast FCP helps reassure the user that something is happening. The First Contentful Paint (FCP) metric measures the time from when the page starts loading to when any part of the page’s content is rendered on the screen. For this metric, “content” refers to text, images (including background images), elements, or non-white elements.

  • Largest Contentful Paint The Largest Contentful Paint (LCP) metric reports the render time of the largest image or text block visible within the viewport. Good LCP values are 2.5 seconds, poor values are greater than 4.0 seconds and anything in between needs improvement. To provide a good user experience, sites should strive to have Largest Contentful Paint occur within the first 2.5 seconds of the page starting to load.

  • Cummulative Layout Shift (CLS) Unexpected movement of page content usually happens because resources are loaded asynchronously or DOM elements get dynamically added to the page above existing content. The culprit might be an image or video with unknown dimensions, a font that renders larger or smaller than its fallback, or a third-party ad or widget that dynamically resizes itself.

  • Total Blocking Time (TBT) The Total Blocking Time (TBT) metric measures the total amount of time between First Contentful Paint (FCP) and Time to Interactive (TTI) where the main thread was blocked for long enough to prevent input responsiveness. The main thread is considered “blocked” any time there’s a Long Task—a task that runs on the main thread for more than 50 milliseconds (ms). We say the main thread is “blocked” because the browser cannot interrupt a task that’s in progress. So in the event that a user does interact with the page in the middle of a long task, the browser must wait for the task to finish before it can respond. If the task is long enough (e.g. anything above 50 ms), it’s likely that the user will notice the delay and perceive the page as sluggish or janky. The blocking time of a given long task is its duration in excess of 50 ms. And the total blocking time for a page is the sum of the blocking time for each long task that occurs between FCP and TTI.

In terms of the shape of the actual waterfall, ideally we have most requests left aligned meaning they go out at the same time as opposed to one of the after which would mean increased waiting time for assets to dowload.

The requests that are necessary to complete to be able to have a functional page form what’s called the critical rendering path (CRP). You want the slope of this path to be as close to vertical as possible.

Anti-patterns

Long First Byte Multiple things could take a long time at this stage: a slow DNS resolution, taking too much time to do the security negotiation or having the wrong server settings and therefore too slow of an initial connection. But most always the main culprit is the TTFB which is how fast the backend is able to return a response. This is usually slow because it involves database access.

The First Byte defines the low level from where you can start optimizing the frontend. If the First Byte is 1.5s no amount of frontend optimization will make things feel snappier.