Skip to content

SpeedPart of: Page speed

Reading a waterfall chart and filmstrip: where the seconds go

A request waterfall shows every file a page loads and when; the filmstrip shows what the visitor saw meanwhile. Learn the anatomy of a bar, the six patterns behind most slow pages, how to match frames to metrics, and what to fix first.

getReport teamUpdated 15 Oct 202616 min read

A waterfall chart is the page load drawn as a timeline: one row per file, a bar from the moment the browser asked for it to the moment the last byte arrived, in the order the requests started. It is the one view that shows why a page is slow rather than that it is slow, and most of its patterns can be read in a minute once you know what to look for. The filmstrip beside it shows what the visitor was looking at meanwhile. This guide covers where to get both, what the parts of a bar mean, the six shapes that explain most slow pages, how to match filmstrip frames to the metrics, and the order to fix things in. It is part of the page speed guide.

Quick answer

  • Read a waterfall top to bottom and left to right. The first bar is the HTML; everything under it waited for something above it.
  • A long first bar is the server. A staircase is a dependency chain. A wide gap before the big image is late discovery. Many thin bars from one host is HTTP/1.1. A short bar followed by another to the same page is a redirect.
  • The vertical lines mark when the page became usable: DOMContentLoaded and Load in DevTools, plus First and Largest Contentful Paint in WebPageTest.
  • Fix in this order: redirects, server response, render-blocking files, the LCP image's discovery, third parties, then connection count.
  • In the filmstrip, the first non-blank frame is FCP, the frame where the main element lands is LCP, and frames where things move are layout shifts.
  • The speed test shows the filmstrip and a waterfall of every request under the metrics (the first 30, the rest one click away), with the document, render-blocking files and large images coloured, plus the page size, requests by type and domain, and the page ready, onload and fully loaded times.

Why the waterfall matters

Metrics tell you the outcome (LCP 4.1 s) and Lighthouse insights a probable cause ("Render-blocking requests"). The waterfall shows the mechanism: the HTML took 900 ms, two stylesheets and a tag manager blocked for 700 ms, and the hero was requested only after a slider script ran. Each is a different fix, and only the waterfall tells them apart.

Where to get one

  • Chrome DevTools → Network. Reload with the panel open. The Waterfall column is on the right; hover a bar for the timing breakdown. Tick "Disable cache" and set throttling to "Slow 4G" to see what a phone visitor sees.
  • WebPageTest. The most detailed waterfall available, with connection view, priority, and the FCP/LCP lines drawn over it, from real locations and devices.
  • getReport's speed test. The filmstrip and the waterfall of the same Lighthouse run, under the lab and field tables: every request by start time, each with its transfer size, the first 30 shown and the rest behind "Show all".
  • PageSpeed Insights shows metrics, insights and a filmstrip of the Lighthouse run, but no per-request timeline.
  • Chrome DevTools → Performance with "Screenshots" ticked records a filmstrip at the top of the trace, on your own connection unless you throttle.

How getReport checks it

The speed module keeps the request list from the Lighthouse run and draws it as a waterfall: document in blue, render-blocking files in amber, images over 200 KB in red, everything else grey, with the transfer size beside each name. Four findings read the same data and name the pattern for you:

The last one comes from the best-practices module, which records the protocol each response used in a Chromium load; the HTTP/2 test shows the detail per protocol.

The protocol details table of the HTTP/2 test: the ALPN row showing which protocol the server negotiated, the HTTP/3 and Alt-Svc rows, the TLS version and cipher, and chips counting the responses per protocol from the browser run
If any responses are counted under http/1.1, those hosts are the ones producing thin, queued bars in the waterfall.

The anatomy of a bar

In DevTools, hovering a bar shows the phases. From left to right:

PhaseWhat is happening
Queueing / StalledThe browser has the request but has not sent it: waiting for a free connection (HTTP/1.1 allows six per host), for a higher-priority request, or for the connection below
DNS lookupTurning the hostname into an address. Once per host per page, cached afterwards
Initial connectionThe TCP handshake, one round trip
SSL / TLSThe TLS handshake, one to two round trips
Request sentSending the request headers, usually a millisecond
Waiting (TTFB)Sent, nothing back yet: the server is thinking, or the network is slow
Content downloadBytes arriving

Two things follow. The first request to a new host always pays DNS, connect and TLS (several round trips, easily 300-600 ms on a mobile connection) and later requests to the same host do not, which is why a page that talks to twelve hosts is slow before any content arrives. And the waiting phase on the first bar is the server's response time for the HTML; on static files it should be near zero.

The vertical lines in DevTools are DOMContentLoaded (blue) and Load (red); WebPageTest adds FCP and LCP. The report's waterfall draws no lines: its page ready (DOMContentLoaded) and onload times sit in the tiles above it, and the LCP time in the lab table, so find the bar that ends just before each.

The six patterns

1. A long first bar: the server

Sketch: the HTML bar is 1.5 s wide and mostly green; every other bar starts after it.

Nothing can start until the HTML arrives, so a slow first byte pushes every other bar right by the same amount. Causes: no page cache (WordPress rendering the page on every visit), a slow database query, an overloaded shared host, a distant server with no CDN. The TTFB finding names the number; the TTFB guide has the fixes. If the first bar is long but mostly orange and purple rather than green, it is the connection, not the server: a far-away origin or a TLS setup without session resumption.

2. A staircase: dependency chains

Sketch: a stylesheet bar, then a font bar that starts exactly where the stylesheet ends, then another; or a script, then a second script it loaded, then a fetch to an API.

Each step is a file the browser could not know about until it had parsed the previous one. CSS @import chains, web fonts referenced from a stylesheet, scripts that inject scripts, a framework bundle that fetches data before it can render. Each step is at least one round trip. Fixes: flatten @import into one file, preload the font so it starts alongside the stylesheet, preconnect to hosts you know will be needed, and render the first screen on the server so no API round trip stands between the visitor and the content. Preload, preconnect, prefetch explains which hint breaks which chain.

3. A wide gap before the big image: late discovery

Sketch: the document, stylesheets and scripts finish at 1.2 s; the hero image, the widest bar on the page, starts at 2.4 s.

The browser requests images as soon as it sees them in the HTML, so an image that starts late was not in the HTML: it was a CSS background-image (discovered only when the stylesheet is parsed and the element laid out), a lazy-loaded <img> that a script had to un-lazy, or a slider that built its slides with JavaScript. The LCP element line under the lab table tells you which image; the fix is to put it in the HTML as a plain <img> with fetchpriority="high", or to preload it when it must stay in CSS.

4. Many thin bars from one host, in batches of six: HTTP/1.1

Sketch: dozens of short bars from the same domain, each with a grey stalled phase, starting in groups; the seventh waits for the first to finish.

HTTP/1.1 allows six connections per host in Chrome, so the seventh request queues. HTTP/2 multiplexes everything over one connection and the batches disappear. The HTTP/2 finding counts the responses still on http/1.1; the fix is a server or CDN setting, described in HTTP/2 and HTTP/3. A third-party host still on HTTP/1.1 shows the same pattern for its own files.

5. Third-party bars in the middle of the critical path

Sketch: between the stylesheet and the first image, three bars to a tag manager, a consent platform and a chat widget, each paying its own DNS, connect and TLS.

They are not your content, but if they are scripts without defer they block the parser, and even with defer they compete for bandwidth and main-thread time before the LCP image. Recognise them by the hostname. Move them after the LCP image (load on interaction, or from the tag manager with a delay), and preconnect to the ones that must stay early. Third-party scripts covers each kind.

6. A short bar, then another for the same page: redirects

Sketch: the first bar is 200 ms with almost no download, followed by a second document bar; sometimes a third.

http:// to https://, then bare domain to www, then a trailing slash: each is a full round trip before the real request. On a mobile connection a chain of three can cost well over half a second before the server even starts working. The redirects finding lists the hops; the fix is a single rule that sends every variant straight to the final URL, and links (menus, ads, social profiles) that use the final URL directly.

Reading the filmstrip alongside the waterfall

The filmstrip is a row of screenshots from the same run, each stamped with its time. Where the waterfall shows what the browser was doing, the filmstrip shows what the person was looking at, and it maps directly onto four metrics:

What you see in the framesMetricGood
The first frame that is not blankFirst Contentful Paint≤ 1.8 s
The frame where the biggest element (hero, headline, product photo) is fully visibleLargest Contentful Paint≤ 2.5 s
How quickly the frames fill up between those twoSpeed Index≤ 3.4 s
Frames where content moves without the visitor doing anythingCumulative Layout Shift≤ 0.1

Frames are samples, so each timestamp is accurate only to the interval between frames. A shift that happened and was undone between two frames is invisible but still counted; when the CLS finding names an element you cannot see moving, record a reload in the DevTools Performance panel, which marks each shift on the timeline. First Contentful Paint and Speed Index explains how Speed Index is computed from the frames.

Most filmstrips tell one of five stories, and each points at a waterfall pattern:

  1. Blank, blank, blank, then everything. The browser had nothing to draw until the HTML and every blocking file arrived. Check the first bar (pattern 1) and the amber bars (render-blocking files).
  2. Text early, images late. FCP is fine, LCP is not. The hero is too heavy or discovered late (pattern 3). If the space was not reserved, the same story also produces a layout shift.
  3. A jump when a font or banner arrives. The headline rewraps in the brand font, or a promo bar pushes everything down. Look for the font file's bar or the script that inserted the banner, often a third party. Cumulative Layout Shift has the fix for each case.
  4. A spinner or skeleton, then content. The HTML arrived nearly empty and JavaScript built the page after fetching data: a staircase ending in an API call (pattern 2). FCP looks good and misleads; LCP and Speed Index are late. Render the first screen on the server.
  5. An overlay over the fold. The page is finished, then a consent dialog, chat bubble or newsletter pop-up covers it. The metrics may look fine and the visitor still cannot use the page; keep overlays small and fixed-position.

For any frame, the bars that end just before its timestamp are what made it possible, and the bars still running are what the next frame is waiting for. Read together, "the page felt slow" becomes "the stylesheet blocked until 1.6 s, then the slider script requested the hero at 1.9 s", which is a ticket a developer can act on.

Reading priority and initiator

DevTools hides two columns that explain most surprises; right-click the column header and enable Priority and Initiator.

Priority is what the browser decided the file was worth: Highest for the document and stylesheets, High for scripts in <head> and fonts, Medium or Low for images depending on whether they are in the viewport, Lowest for prefetch. An LCP image at Low priority was not in the viewport when the browser decided, or was lazy-loaded; fetchpriority="high" overrides the guess. A script at Highest that does nothing for the first paint is a candidate for defer, which drops it to Low.

Initiator is who asked for the file: "Parser" for anything in the HTML, a stylesheet's name for fonts and background images, a script's name and line for anything requested by JavaScript. A staircase (pattern 2) reads as a chain of initiators; an LCP image whose initiator is a slider script (pattern 3) tells you where to fix it.

What to fix, in which order

Work from the cheapest fix with the widest effect to the narrowest: redirects (pattern 6), the first byte (pattern 1, a page cache or CDN moves every bar left), render-blocking files (Render-blocking resources), the LCP image's start time (pattern 3), chains (pattern 2), third parties (pattern 5), and HTTP/2 (pattern 4), which is last only because it is usually already on. Change one thing at a time and re-run, so the next waterfall and filmstrip show what it did.

Verify

  • Re-run the speed test after each change and compare waterfalls: the first bar shorter, no amber bars between the document and the hero, the hero image starting within a few hundred milliseconds of the document, no batches of six.
  • In DevTools with Slow 4G throttling, the LCP image's Priority column reads High and its Initiator reads Parser.
  • The HTTP/2 test's protocol table counts every response under h2 or h3.

Common mistakes

  • Reading the waterfall on fast Wi-Fi with a warm cache. Symptom: every bar is short and the page looks fine. Fix: "Disable cache" and Slow 4G throttling in DevTools, or use the report's throttled run.
  • Fixing the longest bar first. Symptom: a 3 MB video at the bottom is optimised while LCP does not move. Fix: work on the bars that finish before the LCP line; anything after it is not on the critical path.
  • Preloading everything. Symptom: twenty preload hints, LCP worse than before. Fix: preload only the LCP image and the one font the headline uses; preloads compete with each other.
Check your site before and after Check