Improving Paint Metrics by Removing Unused Preloads

Last month, at Lazy Load, Paul Calvano gave a presentation where he dove deep into HTTP Archive to uncover some common performance mistakes. One of the issues he explored were sites that preloaded resources that never actually end up being used by the page.
The preload
hint is a way of indicating to the browser that a particular resource will be needed for that page, and that the browser should request it now, when the preload
hint is encountered, rather than waiting for later discovery. When used selectively and sparingly it can be a great way to help resources that the browser won’t discover in the HTML itself—a background image referenced in CSS, a JavaScript file injected by a script loader, etc—arrive much earlier.
Unfortunately, like anything, it can also be misused and the consequences can be significant.
One example Paul pointed out was the Festival Foods website. HTTP Archive data at the time showed that Festival Foods had a whopping 318 unused preloads.
One of WebPageTest’s new opportunities is to highlight unused preloads (thanks to some help from the Chrome team, who were kind enough to add an indicator to their trace events), and we also now have an experiment to remove those preloads, so I decided to fire off a test and dig a bit deeper.
Testing the site in WebPageTest (in Chrome, on an emulated Moto G4, over a 4G connection from Virginia) showed that the Festival Foods site was suffering from some very slow paint metrics:
- First Contentful Paint: 9.1s
- Largest Contentful Paint: 10.7s
- Speed Index: 10,375

Sure enough, WebPageTest reported that there were a lot of unused preloads—in this case, 381 of them.

The result was a very long waterfall.

What was happening here is that all of these preloads were being discovered by Chrome and requested early, since they all lived in the head
of the document. Instead of being able to move on and request critical resources that the rest of the page depended on, the browser was stuck trying to fetch 381 resources that it would never end up using at all.
anchorThe Experiment
It seemed a pretty safe bet that fetching 381 unused resources early on in the page load process would be impacting those visual metrics heavily, but thankfully we didn’t have to guess: there’s an experiment for that (Kinda catchy. Someone should make some sort of slogan like that.)
The Remove Unused Preloads experiment automatically removes all the unused preload elements from the page’s source and then tests to see what the impact is. We would have ran that experiment, but it turns out listing 381 different URL's makes for a very, very large script. Too large.
So instead, we used the custom Find/Replace text experiment and passed it a regular expression to remove all preloads.
<link[^>]*rel="preload"[^>]*>
We ran the experiment, and the result was pretty dramatic.

The paint metrics dropped dramatically. When compared to the control run (each experiment runs a control run to establish a solid baseline), First Contentful Paint, Largest Contentful Paint and Speed Index all dropped by around 6 seconds. As an unexpected side effect, we even saw the Cumulative Layout Shift metric drop dramatically.
The final visual metrics for the experiment still showed room for improvement, but were remarkably better.
- First Contentful Paint: 4.4s
- Largest Contentful Paint: 5.8s
- Speed Index: 5270
Not too bad for a single optimization.
anchorA Happy Ending
This story has a happy ending. It turns out the Festival Foods site got an update recently, and a new test shows there are no more unused preloads.

More importantly, the performance of the new site is much improved from the prior version, and the new metrics line up pretty well with the experiment results.

On the updated site, when tested under the same conditions as the original tests, First Contentful Paint and Largest Contentful Paint both fire around 3.4s and the Speed Index was 5,082.
anchorBetter for all users
It’s always more exciting when you can see improvements for all your users, not just users of a single browser engine, and this optimization certainly fits the bill.
While we’re unable to surface exactly which resources are derived from unused preloads in Firefox or Safari at the moment, a before and after comparison in Firefox (I didn’t have a Safari test handy of the before situation) shows the cleanup had a dramatic improvement there as well. First Contentful Paint improved from 5.1s to 1.6s and Speed Index improved from 7,558 to 2,963.

anchorAlways Be Testing
The preload
hint can be very helpful, but it’s important to make sure that we’re not abusing it, and that we’re only using it for resources we know we need for the current page. Re-running Paul’s original query against the latest HTTP Archive data shows 571,784 pages with unused preloads. In other words, it’s a pretty widespread issue.
Keep in mind that your mileage may vary. It’s unlikely your sites have hundreds of unused preloads, and I’d be willing to wager that very few of you could shave 5 or 6 seconds off your paint metrics simply by removing them. Be careful to test your site and experiment to see how significant the potential improvement is for your own site.
Tim Kadlec is the Director of Engineering for WebPageTest, a web performance consultant, and trainer focused on building a web everyone can use. He is the author of High Performance Images (O'Reilly, 2016) and Implementing Responsive Design: Building sites for an anywhere, everywhere web (New Riders, 2012). He writes about all things web at timkadlec.com.
@tkadlec