Zach’s ugly mug (his face) Zach Leatherman

Wait, WebP is actually worth it.

April 30, 2017 On Twitter (archived)

(This article has been translated to Russian: Погодите, а WebP вообще-то ничего!)

For my previous talk, I decided to do something a little different with my slides—I decided to self host them.

When I work on a talk, I create the slides in Keynote. After the talk has finished, I’ll post them on Speakerdeck. Speakerdeck is very ok. It operates how I’d expect a shallow copy of a dynamic slideshow to operate. I wanted to try to do a little better.

I definitely like the format, perhaps pioneered (at least in my experience) by Maciej Cegłowski. It’s a big giant two column format with slide images on the left and presenter notes on the right. I’ve also seen this done beautifully by Scott Jehl on the Filament Group lab.

So I dug deep into the Filament Group Slack archives and found a tool to generate images from Keynote slides, called Keynote Extractor. It works quite well. It extracted my Keynote slides into a simple directory with HTML, CSS, and PNG image files. The only problem was that the images were huge—a total of almost 18MB to be exact.

Devtools Screenshot showing 18MB download

ImageOptim

Okay, so maybe the images aren’t properly optimized. Let’s run them through ImageOptim and see how much that helps.

Devtools Screenshot showing 12MB download

Okay, 12MB—that’s an improvement, but obviously not good enough.

JPEG

Let’s convert the PNG images to JPEG. JPEG compression is magical and often better for realistic photos.

# Converts a directory of PNG files to JPG
# Added this to my .zshrc file (or .bash_profile)
# Install `imagemagick` with `brew install imagemagick`
function batchjpeg() {
	for i in *.png
	do
		convert "$i" "${i%.*}.jpg"
	done
}
Devtools Screenshot showing 4.5MB download

Getting better—4.5MB.

WebP

I must admit that I’ve carried a bias against WebP and thought it was a little silly in the past, mostly because it had limited browser support, which necessitated a JavaScript solution or a backend service to serve WebP images properly with fallbacks.

Then I ran across this tweet (thanks Eric!) a few days ago and decided to re-evaluate my position.

My initial reaction was leftover angst that pre-dated the <picture> element, which has since expanded to have pretty great browser support. <picture> gives us a simple no JavaScript, no backend way to serve WebP to browsers that support it. Looks like the only mild problem is on Opera Mini and the Android Browser, which support WebP but not <picture>—but they’ll just suffer a mild performance hit and get the JPG fallback.

It’s important to note that I converted the original PNG images to WebP (not from JPG), given that I converted at 80% quality.

# Converts a directory of image files to WebP
# Added this to my .zshrc file (or .bash_profile)
# Install `cwebp` using `brew install webp`
function batchwebp() {
	for file in *
	do
		cwebp -q 80 "$file" -o "${file%.*}.webp"
	done
}
Devtools Screenshot showing 1.5MB download

Wow. From 17.9MB down to 1.5MB total. That’s a 91.6% decrease.

For 52 individual image slides, this is a great result. Especially considering that I didn’t even resize the original images. At their max rendered width (496 pixels at their widest) and with a 1024 pixel natural image width, each image is at minimum 2.064516129x-Retina friendly.

Like Eric Lawrence in his tweet, I would now encourage you to try out WebP with <picture>! Shave off those KB, y’all.

Implementation Note

In the final product you see on my website, I cheated a little bit in that four of the slides are actually videos that only preload the metadata. Video metadata is likely to be a smaller footprint than a full resolution slide image. None of that matters in the analysis above, however—the screenshots were recreated without videos.

More Optimization Possibilities

Here are a few more things I could do to improve this even further if I wanted to expend the time. For this particular project, I don’t, but for professional work I probably would. But perhaps therein lies the danger with WebP. We implement an easy Chrome(-ish) only optimization and call it a day, when really this page needs more optimization for non-WebP browsers.

  • To make the entire slideshow page weight smaller, I could adjust the maximum rendered size of the slides to be smaller. I might even use a minimum of 1.5x-Retina instead of the 2.06x minimum I’m using now.
  • I could also use srcset with <picture> to serve smaller sources at smaller viewport sizes. I’d look to keep the Retina rating somewhat consistent at different viewport sizes.
  • Evaluate a compressive images approach with WebP and super low quality conversion values.
  • I could also look at possible savings from converting the text-only slides to use a webfont instead of an image.
  • Lazy loading the slides with JavaScript, which does not really have a good standards-based way to implement. It would require non-standard markup for the images to hide them from the preparser. That’s what AMP does, last I checked. It’d be a good exercise to think through how this might work with <picture>, too.

< Newer
Quick Demo: Animating on an Oval Path
Older >
What Are You Excited About?

Zach Leatherman IndieWeb Avatar for https://zachleat.com/is a builder for the web at IndieWeb Avatar for https://fontawesome.com/Font Awesome and the creator/maintainer of IndieWeb Avatar for https://www.11ty.devEleventy (11ty), an award-winning open source site generator. At one point he became entirely too fixated on web fonts. He has given 84 talks in nine different countries at events like Beyond Tellerrand, Smashing Conference, Jamstack Conf, CSSConf, and The White House. Formerly part of CloudCannon, Netlify, Filament Group, NEJS CONF, and NebraskaJS. Learn more about Zach »

10 Comments
  1. Jeremy Wagner Disqus

    02 May 2017
    Excellent article on WebP. I've also had much of the same success with it that you'd had here, and would heartily recommend it to anyone.
    1. zachleat Disqus

      04 May 2017
      Thanks Jeremy!
  2. George Liu Disqus

    02 May 2017
    You can definite reduce image size with webp and nginx can be configured to conditionally serve webp to supported browsers https://centminmod.com/webp/. I did webp benchmarks at https://github.com/centminm... as well :)
  3. Eric Portis Disqus

    02 May 2017
    It is fun and cool see exactly how and why you’re experimenting with this stuff. Why `cwebp -q 80`? Any subjective thoughts on how the ImageOptim PNG/Jpeg/WebP quality compares?
    1. zachleat Disqus

      05 May 2017
      Heh, that choice was arbitrary, for sure.Good questions! I’d like to look at the quality comparisons more—do you know of a good tool to do image diffs that works with WebP?
      1. Никита Е Disqus

        19 Oct 2017
  4. Kornel Disqus

    03 May 2017
    Have you tried using MozJPEG with "compressive images" preset? (Described here: https://calendar.perfplanet... )Even according to Google's own test WebP is only up to 30% smaller than JPEG, so if you're seeing a difference bigger than that, it's a warning sign. You should be able to get to similar file size range with well compressed JPEGs. Try re-saving them, or try the "high-DPI" setting here:https://imageoptim.com/mozjpeg
  5. Luke Cavanagh Disqus

    21 Jul 2017
    If only WebP was supported by Firefox and Edge.
  6. Christoph Disqus

    11 Nov 2017
    Can you help me with the batch script please?I put in into file and tried to run it via 'sh script' but I get an error: script: 4: script: Syntax error: "(" unexpected
    1. zachleat Disqus

      16 Nov 2017
      I put it into my .zshrc file but you may use a .bash_profile or something else to hold all of your reusable shell scripts. You can go down the dotfiles rabbit hole to see examples of how other people do it: https://dotfiles.github.io/
Shamelessly plug your related post

These are webmentions via the IndieWeb and webmention.io.

Sharing on social media?

This is what will show up when you share this post on Social Media:

How did you do this? I automated my Open Graph images. (Peer behind the curtain at the test page)