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.

  1. Part 1: Methodology & Alpha Tauri
  2. ➡️ Part 2: Alfa Romeo
  3. Part 3: Red Bull
  4. Part 4: Williams
  5. Part 5: Aston Martin
  6. Part 6: Ferrari
  7. Part 7: Haas
  8. Part 8: McLaren
  9. Bonus: Google I/O
  10. …more coming soon…

Alfa Romeo

Link
First run
16.1s (raw results)
Second run
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 other defer scripts.
  • type="module": Load as a module, which implies defer 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

Scorevs 2019
Alpha Tauri
22.1+9.3Leader
Alfa Romeo
23.4+3.3+1.3

Alpha Tauri narrowly keeps the lead. Let's see if that continues in the next part.

  1. Part 1: Methodology & Alpha Tauri
  2. ➡️ Part 2: Alfa Romeo
  3. Part 3: Red Bull
  4. Part 4: Williams
  5. Part 5: Aston Martin
  6. Part 6: Ferrari
  7. Part 7: Haas
  8. Part 8: McLaren
  9. Bonus: Google I/O
  10. …more coming soon…

View this page on GitHub

Comments powered by Disqus

Jake Archibald in a garden with a black cat

Hello, I'm Jake and that's me there. The one that isn't a cat. I'm a developer of sorts.

Elsewhere

Contact

Feel free to throw me an email, unless you're a recruiter, or someone trying to offer me 'sponsored content' for this site, in which case write your request on a piece of paper, and fling it out the window.