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…
Alfa Romeo
- Link
- First run
-
16.1s (raw results)
- Second run
-
7.3s (raw results)
- Total
-
23.4s
- 2019 total
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.
Possible improvements
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:
- 10 second delay to content-render caused by low priority render-blocking JavaScript.
- 1.5 second delay to content-render caused by other-server sequential CSS.
- 11 second delay to primary image caused by blocking request on JavaScript.
- 2.5 second delay to primary image caused by poor image compression.
Remember, some of those delays overlap.
Key issue: Low priority render-blocking JavaScript
Here's the waterfall:
There's some render-blocking JavaScript in the <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' priority, 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 otherdefer
scripts.type="module"
: Load as a module, which impliesdefer
by default.
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.
An even better solution would be to avoid a JavaScript dependency for the initial render, which is very possible for content like this. Then, the JavaScript can load lazily, and gradually enhance elements.
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.
The telltale sign is row 72, which is the late-loading JavaScript I covered earlier. The image only starts downloading once the JavaScript has finished downloading, which suggests the download of the image is dependant on the JavaScript. Although, we don't have to guess, because Chrome DevTools can tell us:
And there we go, the 'initiator' column confirms the image loading was triggered by the late-loading JavaScript. Taking a look at the source:
<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"
/>
Aha! data
attributes! The browser doesn't really do anything with these, they're just somewhere developers can put arbitrary data. The site is using some sort of JavaScript polyfill for responsive images. Also, as a fallback, it's downloading a 5x4 image 🙃.
Today, responsive images are well supported, so there's no reason to use JavaScript for this, just use real responsive images.
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:
- Original
- Optimised
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…
Scoreboard
Score | vs 2019 | |||
---|---|---|---|---|
Alpha Tauri | 22.1 | +9.3 | Leader | |
Alfa Romeo | 23.4 | +3.3 | +1.3 |
Alpha Tauri narrowly keeps the lead. Let's see if that continues in the next part.
- 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…