Who has the fastest F1 website in 2021? Part 2
Ohhh, you've come back for more? Excellent. I was worried it was just going to be me sat here, typing to myself.
This is part 2 in a multi-part series looking at the loading performance of F1 websites. Not interested in F1? It shouldn't matter. This is just a performance review of 10 recently-built/updated sites that have broadly the same goal, but are built by different teams, and have different performance issues.
- Part 1: Methodology & Alpha Tauri
- ➡️ Part 2: Alfa Romeo
- Part 3: Red Bull
- Part 4: Williams
- Part 5: Aston Martin
- Part 6: Ferrari
- Part 7: Haas
- Part 8: McLaren
- Bonus: Google I/O
- …more coming soon…
The video above shows how users would experience the site on a low-end phone on a good 3G connection. Alternatively, scroll along the timeline above.
A loading spinner doesn't count as a first content render. A loading spinner is just an apology for being slow 😀. Interestingly the vast majority of the performance lost here is down to one easily fixable issue:
- 1.5 second delay to content-render caused by other-server sequential CSS.
- 2.5 second delay to primary image caused by poor image compression.
Remember, some of those delays overlap.
Here's the waterfall:
<head> which isn't great (row 4, which is modernizer), but it's pretty small, and ready after around 5.5 seconds. The real problem is down on row 72; that's another render-blocking script.
The long thin light-yellow bit means the browser knew about the resource for a long time, but chose to download other things first. We can confirm that in the network panel of Chrome DevTools:
It has a 'low' prioirty, but it's a render-blocking script! Why did Chrome choose to download it so late? Well, the problem is, the browser doesn't know it's render-blocking.
Usually when we talk about render-blocking scripts, we mean a script that appears before the content in the source, and doesn't have one of the following attributes:
async: Don't block the parser. Execute whenever loaded.
defer: Don't block the parser. Execute after the document has parsed, and in order with other
type="module": Load as a module, which implies
If you use one of the above, the script doesn't block the parser, and therefore doesn't block rendering.
However, the script we're talking about sits right at the end of the
<body>, and it does have
defer, so the browser assumes it isn't render-blocking, and queues it behind the images and other sub-resources.
It's only 'render-blocking' because the site inserts a loading screen that covers the whole page, and that late-loading script removes it.
The solution: Move that script into the
<head>. That's it.
The browser would still consider it low priority, but it should still queue in front of all those images. If not, a
<link rel="preload" as="script" href="…"> will convince Chrome to raise the priority.
Issue: Other-server sequential CSS
The problem is the CSS on row 7 (the script on row 6 isn't render-blocking). There are two problems here that we already encountered in part 1:
…but the ideal solution is different. In part 1 the solution was restricted by font-licencing, but since it's Google Fonts this time, it's open source, so we can do what we want.
The delay here is doubly sad because no fonts are actually downloaded. The web font they're using is "Roboto", which already ships on Android devices (it's the main Android font), so Android users get all the delay for nothing.
Google Fonts' CSS is smart; it serves the best CSS and font format for that particular browser, but since WOFF2 is well supported, we could just copy & paste the font CSS into the site's CSS, and avoid the request to the other server. You could also do this with the fonts themselves, keeping everything on one server.
Issue: Delayed primary image
That image is dropping in a bit late, which could be caused by a number of things. Back to the waterfall:
There it is on row 74. Browsers tend to discover
<img>s really early, and their downloads can start before the CSS is ready. So, it probably isn't a regular
<img>. If it was a CSS background, I'd still expect the download to start much earlier, but after the CSS.
<img alt="" data-aspectratio="1.78" data-sizes="auto" data-srcset="…ARRO_2021_C41_Rear.jpg 3072w, …ARRO_2021_C41_Rear-2360x1769.jpg 2360w, …ARRO_2021_C41_Rear-1800x1349.jpg 1800w, …ARRO_2021_C41_Rear-1400x1049.jpg 1400w, …ARRO_2021_C41_Rear-1075x806.jpg 1075w, …ARRO_2021_C41_Rear-830x622.jpg 830w, …ARRO_2021_C41_Rear-630x472.jpg 630w, …ARRO_2021_C41_Rear-480x360.jpg 480w" src="…ARRO_2021_C41_Rear-5x4.jpg" />
Issue: Large primary image
It looks like someone really cared about image sizes when they built this site, because they're fairly well optimised. However, one image is badly sized and compressed, and unfortunately it's the main one right at the top of the page.
I put it through Squoosh:
The compressed versions have a bit more smoothing compared to the original, but I don't think real users would notice, and it's worth it to get that image loaded as soon as possible.
How fast could it be?
Here's the site compared to my optimised version, where I've inlined the CSS, removed unused CSS, unblocked all script, and optimised the image:
It's a huge difference, but seriously, the current Alfa Romeo site is a couple of small fixes away from winning this contest.
We've got two results now, so we should probably get a scoreboard going…
Alpha Tauri narrowly keeps the lead. Let's see if that continues in the next part.