These Images Are Making Me Surly!
twitter: @malchata  —  Blog: jeremywagner.me
Slides: bit.ly/these-images-are-making-me-surly

Hi, I'm Jeremy

High-fiving a cartoon dog
  • I work for General Mills in Minnesota (Canada Junior)
  • I wrote a book for Manning last year on web performance (giveaway at the end of the talk!)
  • Hobbies include writing, guitar, running, and high-fiving cartoon dogs
The Truth or: Image Quality is Subjective

The web is

Image hell

Average image payload vs. average internet speed
Image sizes over time
Source: HTTP Archive, Akamai State of the Internet Report

We're

OBSESSED

With image quality

Can you tell the difference?

They're very refreshing!

Full Color PNG
90.7 KB

They're very refreshing!

8-bit PNG (192 colors)
27.5 KB

Designers and Developers

Have references for image quality

Users don't!

Belaboring the point

(This time with JPEGs!)

We don't have a big salad.

Quality Level 100
129.7 KB

WE DON'T HAVE BIG BOWLS.

Quality Level 40
25.4 KB

Factors for subjectivity

Image content

Scaling

Viewing distance

Screen size

Screen resolution/pixel density (e.g., Retina)

Physical limitations/handicaps

The gist:

Less is usually more

The Foundation or: Starting Off Right

Use the right format!

The wrong format can cost you!

Liar George

Full Color PNG
207 KB

Bawdy George

JPEG (Quality 40)
25.4 KB

One way to choose an image format:

Image Format Choice Flowchart

For lossy images...

Reign in quality!

The 💩 + 10 Rule

(It's gold!)

Directions:

1. Begin adjusting quality towards 0

2. Stop when image appears as if rubbed with greasy deli ham

3. Adjust by 10* away from 0

*Your experience may vary

For lossless images...

Quantize!

Quantization in Theory

Quantization in Theory

Quantization in Practice

Jiffy Park

Full Color PNG
81.7 KB

Jiffy Park

8-bit PNG (128 colors)
25.9 KB

Simplify vector artwork!

Simplifying works!

Before simplification (184 bytes):

<path class="st0" d="M6.7,0.1C2.5,10.3,1.1,24.7,1.1,24.7s-2,22.1-0.3,33.1c0,0,3.1,22.1,16,27.3s25.7,2.3,29.4,0.6 s16.2-10.4,19.1-20.2c2.8-9.8,1.8-21.7,0.9-29.7c0,0-2.1-23.1-9.5-35.8"/>

After simplification (109 bytes):

<path class="st0" d="M7.8,0.1C-1.7,23.4-8,80.5,25.1,87.2c22,4.5,41.7-10.1,43-32.7c1-17-1.6-39.6-10.3-54.5"/>

~40% decrease in code

Compress your

SVGs

SVG Compression Works!

SVG Compression Ratios

Mind your

image sizes!

Got big images?

Big images, big problems

You've got big problems!

Respect users!

Don't force users to download giant images!

Use srcset:

<img src="small.jpg"
     srcset="small.jpg 384w,
             medium.jpg 768w,
             large.jpg 1152w"
     alt="Descriptive alt text!">

Using the <picture> element:

<picture>
    <source srcset="small.webp 384w,
                    medium.webp 768w,
                    large.webp 1152w"
            type="image/webp">
    <source srcset="small.jpg 384w,
                    medium.jpg 768w,
                    large.jpg 1152w"
            type="image/jpeg">
    <img src="small.jpg" alt="Descriptive alt text!">
</picture>
The Fix-Up or: Learn to Love Image Optimizers

JPEG Optimizers

(There's a lot of them)

Test JPEG

Test Image

2048x1536, 1,998.5 KB

JPEG Optimizer Shootout*

Optimizer Time Size (KB)
(Source image) n/a 1,998.50
mozjpeg (3.2) 0m  0.37s 908.44
guetzli** 6m 32.62s 776.49
jpeg-recompress 0m 12.74s 742.85
*Target/export quality is 84 due to Guetzli limitations
**Can only encode baseline JPEGs

Which JPEG optimizer is best?

When quality is paramount and time is no object

Use Guetzli

When configurability is desired

Use jpeg-recompress

For everything else

There's mozjpeg

PNG Optimizers

(There's also a lot of them)

Test PNG

Test Image

1024x892, 484 KB, Full Transparency

PNG Optimizer Shootout

Optimizer Time Size (KB)
(Source image) n/a 484.00
optipng 0m 54.034s** 474.03
pngcrush 0m 13.793s 473.59
zopflipng 2m  7.324s 442.44
pngquant* 0m  0.486s 150.72
pngnq* 0m  2.336s 149.49
*Quantizing optimization (256 colors)
**Most aggressive/CPU-intensive settings used

Which PNG optimizer is best?

Don't know which optimizer to use?

Use quantizing optimizers like pngquant and pngnq

Is quantizing optimization unacceptable?

Use zopflipng

Does zopflipng take too long?

Use optipng or pngcrush

SVG Optimizers

(Just kidding, SVGO is the only one)

Experimenting with SVGO

Method Size (KB)
Unoptimized 44.58
Minified 43.13
SVGO (defaults) 38.31
SVGO (--precision 1) 30.21

Bulk optimization in bash

Use find to find images:
find ./ -type f -name '*.jpg'
Pass found files to find's -exec parameter:
find ./ -type f -name '*.jpg' -exec jpeg-recompress {} {} \;

Bulk optimization in bash

xargs FTW!

find ./ -type f -name '*.jpg' | xargs -P 32 -I {} jpeg-recompress {} {}
Processes 32 images at a time

Warning!

Files will get clobbered! Back up original images!

Automate optimization with gulp

const gulp = require("gulp");
const imagemin = require("gulp-imagemin");

const optimizeImages = ()=>{
  let src = "src/img/**/*.{jpg,png,gif,svg}";
  let dest = "dist/img";

  return gulp.src(src)
    .pipe(imagemin())
    .pipe(gulp.dest(dest));
};

exports.optimizeImages = optimizeImages;

Automate optimization with webpack

const ImageMinPlugin = require("imagemin-webpack-plugin").default;

module.exports = {
  // Skipping past entry point(s)/loaders to plugin config...
  plugins: [
    new ImageMinPlugin({
      test: "../**/*.{jpg,svg,png,gif}",
      maxConcurrency: 16
    })
  ]
};

Remember:

Always examine optimized image output!

The Yada Yada or: The Miscellany

WebP

is for performance!

Advantages of WebP

Offers lower file sizes at reasonable quality

Available with both lossless and lossy compression modes

Capable of full transparency (even with lossy compression)

Widely supported (Blink-based browsers)

Can be animated!

Disavantages of WebP

Not supported in all browsers

Extra effort to maintain WebP assets in parallel with established formats

Image artifacts can be quite noticeable

Decode time is slower than established formats

The state of WebP support

The state of WebP support

Lossy WebP

A george divided against itself

JPEG (Quality 40)
25.4 KB

Cannot stand!

Lossy WebP (Quality 65)
16.59 KB

36% reduction in file size

Lossless WebP

Jiffy Park

8-bit PNG (128 colors)
25.9 KB

Jiffy Park

Lossless WebP
23.21 KB

11% reduction in file size

WebP with a fallback

<picture>
  <source srcset="my-awesome-webp-image.webp" type="image/webp">
  <source srcset="regular-jpeg-image.jpg" type="image/jpeg">
  <!-- <img> is a fallback for when <picture> isn't supported -->
  <img src="regular-jpeg-image.jpg">
</picture>

Have your cake and eat it too!

Don't lean on Photoshop...

Use CSS Effects!

CSS Filters in Action

filter: none;

CSS Blend Modes in Action

background-blend-mode: normal;

All of the effects!

filter: none;
background-blend-mode: normal;

Resources (Part I)

Resources (Part II)

The Finale

Thank you!

twitter: @malchata  —  Blog: jeremywagner.me

Web Performance in Action

Web Performance in Action

Save 42% with code sswagner