My Blog Just Got Faster: Cloudflare Workers and AVIF Support

Tagged withdev

Did I mention that this website is fast? Oh yeah, I did, multiple times.

Few reasons (from ordinary to the first signs of creeping insanity):

  • πŸ“„ Static site
  • ☁️ Cached on Cloudflare CDN
  • πŸ”— ️HTTP/2 and HTTP/3 support
  • 🚫 No web fonts (sadly)
  • βœ… Edge-worker powered analytics (no Google Analytics)
  • 🌸 Avoiding JavaScript whenever possible; CSS covers 90% of my use-cases.
  • πŸ–ΌοΈ Image width and height specified in HTML to avoid page reflows.
  • πŸ‘πŸ» Inlined, optimized SVG graphics and hand-rolled CSS
  • πŸš… Static WASM search (lazy loaded)
  • 🏎️ The entire homepage is <10K (brotli-compressed), including graphics, thus should fit into the first HTTP round-trip.
  • πŸ’Ÿ Heck, even the favicon is optimized for size. Update: I'm using an SVG icon now thanks to this article.

Then again, it's 2020: everyone is optimizing their favicons, right? ...right!?

Well, it turns out most other sites don't think about their user's data plans as much as I do. Actually, that's an understatement: they don't care at all. But to me, lean is beautiful!

Wait, What About Images?

I prefer SVG for diagrams and illustrations. Only if it's a photo, I'll use JPEG or WebP.

To be honest with you, I never really liked WebP. The gist is that it might not even be smaller than JPEGs compressed with MozJPEG. There is a lengthy debate on the Mozilla bug tracker if you want to read more. To this day, Safari doesn't support WebP.

Hello AVIF πŸ‘‹

Meet AVIF, the new next-gen image compression format. Check this out:

[ReachLightSpeed.com](https://reachlightspeed.com/blog/using-the-new-high-performance-avif-image-format-on-the-web-today/)
Source: ReachLightSpeed.com

It's already supported by Chrome 85 and Firefox 80.
Then it hit me like a hurricane πŸŒͺ️:

😲 Holy smokes, AVIF is supported by major browsers now!?
I want this for my blog!

Yes and no.

I'm using Zola for my blog, and AVIF support for Zola is not yet there, but I want it now! So I whipped up an ugly Rust script (as you do) that creates AVIF images from my old JPEG and PNG images. I keep the original raw files around just in case.

Under the hood, it calls cavif by Kornel LesiΕ„ski.

Data Savings

The results of AVIF on the blog were nothing short of impressive:

Total image size for [endler.dev/2020/sponsors](https://endler.dev/2020/sponsors)
Total image size for endler.dev/2020/sponsors

Check Your Browser

But hold on for a sec... is your browser even capable of showing AVIF?

If that reads "yup," you're all set.
If that reads "nope," then you have a few options:

  • On Firefox: Open about:config from the address bar and search for avif.
  • On Chrome: Make sure to update to the latest version.
  • On Safari: I'm not sure what you're doing with your life. Try a real browser instead. 😏

Workaround I: Fallback For Older Browsers

HTML is great in that your browser ignores unknown new syntax. So I can use the <picture> element to serve the right format to you. (Look ma, no JavaScript!)

<picture>
  <source srcset="fancy_browser.avif" />
  <source srcset="decent_browser.webp" />
  <img src="meh_browser.jpg" />
</picture>

The real thing is a bit more convoluted, but you get the idea.

Workaround II: Wrong Content-Type On Github Pages

There was one ugly problem with Github and AVIF, though: Their server returned a Content-Type: application/octet-stream header.

This meant that the images did not load on Firefox.

There is no way to fix that on my side as Github is hosting my page. Until now! I wanted to try Cloudflare's Workers Sites for a long time, and this bug finally made me switch. Basically, I run the full website as an edge worker right on the CDN; no own web server is needed. What's great about it is that the site is fast everywhere now β€” even in remote locations β€” no more roundtrips to a server.

By running an edge worker, I also gained full control over the request- and response objects. I added this gem of a snippet to intercept the worker response:

if (/\.avif$/.test(url)) {
  response.headers.set("Content-Type", "image/avif");
  response.headers.set("Content-Disposition", "inline");
}

And bam, Bob's your uncle. Firefox is happy. You can read more about modifying response objects here.

Another side-effect of Workers Sites is that a production deployment takes one minute now.

Performance Results After Moving To Cloudflare

Website response time before
Website response time before
Source: KeyCDN
Website response time after
Website response time after
Source: KeyCDN

Page size and rating before
Page size and rating before
Source: Pingdom.com
Page size and rating after
Page size and rating after
Source: Pingdom.com

I don't have to hide from a comparison with well-known sites either:

Comparison with some other blogs I read
Comparison with some other blogs I read
Source: Speedcurve

Further reading

    Thanks for reading! I mostly write about Rust and my (open-source) projects. If you would like to receive future posts automatically, you can subscribe via RSS or email:

    Submit to HN Sponsor me on Github My Amazon wish list