high performance images: beautiful shouldn't mean slow

85
High Performance Images Beautiful shouldn’t mean Slow Guy Podjarny @guypod

Upload: guy-podjarny

Post on 28-Jul-2015

1.079 views

Category:

Technology


2 download

TRANSCRIPT

High Performance ImagesBeautiful shouldn’t mean Slow

Guy Podjarny @guypod

Average Web Page Weight(June ’15)

Not 37%

Images 63%

Source: HTTP Archive

Images On Average Page

Sep '12 Jun '13 Jun '14 Jun '15

696 KB891 KB

1,128 KB1,312 KB

50 Reqs 56 Reqs 55 Reqs 55 Reqs

Requests KB

+189%

Source: HTTP Archive

Images Impact Performance

0

4750

9500

14250

19000

Load Time, 3G Speed

With Images No Images

-30%

What Can you do?Image

Compression

Choose The Right Format

Control Quality

Image Loading

Use Responsive Images

Prioritize Critical Content

Image Operations

Encode Well

Transcode in Proxy

What Can you do?Image

Compression

Choose The Right Format

Control Quality

Image Loading

Use Responsive Images

Prioritize Critical Content

Image Operations

Encode Well

Transcode in Proxy

Image Compression

Average Resource Size

CSS

JS

JPEG

0 10 20 30 40

34 KB

16 KB

9 KB

RWD Sites Use Big Images

0

10

20

30

40

JPEG Size PNG Size

7.1 KB

20.8 KB

10 KB

31.6 KB

RWD Not RWD

Tip #1:

Pick The Right Format

Image Formats On The WebOther

2%GIF 23%

PNG 29%

JPEG 46%

GIF

28 Years Old (1987)

256 Colors

Supports “Simple” Transparency

Supports Animation

PNG

19 Years Old (1996)

8-32 bit color palettes

Alpha Transparency

Non-patented

Credit: Wikimedia

GIF -> PNG = 21% Savings

PNG File Size GIF File Size

Source: Styoan Stefanov, “Give PNG A Chance” (2009)

JPEG

23 years old (1992)

RGB Colors (24 bit)

No Transparency Support

A Lossy Format

Bitmap

JPEG

Bitmap≠

Bitmap

PNG

Bitmap=

Lossy Compression

Lossless Compression

JPEG

23 years old (1992)

RGB Colors (24 bit)

No Transparency Support

A Lossy Format

PNG -> JPG = MUCH SmallerPNG, 574 KB JPG, 110 KB

JPEG: No Transparency

JPEGPNG

WebP

0

3.75

7.5

11.25

15

File Size (KB)

JPEG (q75) WebP

9.9 KB

14.4 KB

0

0.825

1.65

2.475

3.3

Bytes Per Pixel

PNG WebP

2.42 bpp

3.27 bpp -26% -31%

Source: Google Studies

WebP Browser Support

New Image Formats

WebP JPEG XR JPEG 2000

SupportChrome, Opera,

Android 4.xIE 10+ Safari on

iOS, OS XSavings

(over JPEG)40-50% ~25% 15-20%

Mime Type image/webp image/vnd.ms-photo Soon: image/jxr image/jp2

Identification Accept: image/webp

Detect IE 10+

DetectSafari 5+

Using Custom Formats Client Side

<script src="picturefill.js"></script> <picture> <source type="image/webp" srcset="book.webp"> <source type="image/vnd.msphoto" srcset="book.jxr"> <img src="book.jpg" alt="a book"> </picture>

Using Custom Formats Server Side, Single URL

GET /book.jpg GET /book.jpg

OriginCDN/Cache

Using Custom Formats Server Side, Single URL

GET /book.jpg GET /book.jpg

GET /book.jpg Accept: image/webp

GET /book.webp

OriginCDN/Cache

Using Custom Formats Server Side, Single URL

GET /book.jxr

GET /book.jpg GET /book.jpg

GET /book.jpg Accept: image/webp

GET /book.webp

GET /book.jpg User-Agent: MSIE 10 Accept: image/jxr*

OriginCDN/Cache* Spartan

Tip #1:

Pick The Right Format

Tip #2:

Control Quality

JPEG Quality

High Quality

Low Quality

Quality: 90 Size: 66 KB

Quality: 75 Size: 37 KB

Quality: 40 Size: 21 KB

Quality: 25 Size: 16 KB

Quality: 90 Size: 66 KB

Quality: 75 Size: 37 KB

Quality: 40 Size: 21 KB

Quality: 25 Size: 16 KB

Quality Scale Is Per Format

Source: Nick Doyle Performance Calendar

Sim

ilarit

y

0.00

0.06

0.13

0.19

0.25

Quality

0 25 50 75 100

JPEGJPEG XRWebP

Detecting Excessive Quality WebPageTest

Detecting Excessive Quality PageSpeed Insights

Tip #2:

Control Quality

SIZE Doesn’t matter

It’s all about

TECHNIQUE

Tip #3:

Size Images To Device

Download & Shrink

102 KB 1876 × 520

(975,520 pixels)

Download & Shrink

866px

240px

1876px

520px

.hp07img {width: 100%}

Download & Shrink

866px

240px

1876px

520px

207,840 pixels

975,520 pixels

79% wasted pixels (~770K)

Download & Shrink

866px

240px

1876px

520px

35,345 Bytes

110,744 Bytes

79% wasted pixels 68% wasted bytes

(~75KB)

Download & Shrink

866px

240px

1876px

520px

79% wasted pixels 68% wasted bytes

79% wasted memory (3MB)

831K Mem Bytes

975,520 * 4(RGBA) = 3.9M Memory Bytes

55 IMAGES

On an Average Page

“...25% of new Android phones have only 512MB of RAM.”

–Jen Fitzpatrick VP of product management for Google Maps

Download & Shrink Processing Times

Source: Tim Kadlec, “Mobile Image Processing”

Implementing Responsive Images

<img src="small.jpg" srcset="large.jpg 1024w, medium.jpg 640w, small.jpg 320w" sizes="(min-width: 36em) 33.3vw, 100vw" alt="A rad wolf">

Implementing Responsive Images

<img src="small.jpg" srcset="large.jpg 1024w, medium.jpg 640w, small.jpg 320w" sizes="(min-width: 36em) 33.3vw, 100vw" alt="A rad wolf"> Hint, Hint…

Implementing Responsive Images

<img src="small.jpg" srcset="large.jpg 1024w, medium.jpg 640w, small.jpg 320w" sizes="(min-width: 36em) 33.3vw, 100vw" alt="A rad wolf"> Hint, Hint…

Implementing Responsive Images

<picture> <source media="(min-width: 40em)"

srcset="big.jpg 1x, big-hd.jpg 2x"> <source srcset="small.jpg 1x, small-hd.jpg 2x"> <img src="fallback.jpg" alt=""> </picture>

Implementing Responsive Images

<picture> <source media="(min-width: 40em)"

srcset="big.jpg 1x, big-hd.jpg 2x"> <source srcset="small.jpg 1x, small-hd.jpg 2x"> <img src="fallback.jpg" alt=""> </picture> Use Picturefill

Which Breakpoints To Use? What Are your Users Using?

Which Breakpoints To Use? How Big & Complex Are Your Images?

Source: Jason Grigsby, “Sensible Jumps In Responsive Image File Sizes”

Width Height File Size

1 320 213 25K2 453 302 44K3 579 386 65K4 687 458 85K5 786 524 104K6 885 590 124K7 975 650 142K8 990 660 151K

Which Breakpoints To Use? How Big & Complex Are Your Images?

Source: Jason Grigsby, “Sensible Jumps In Responsive Image File Sizes”

point # Width Height File Size

1 320 213 9.0K

2 731 487 29K

3 990 660 40K

Tip #3:

Size Images To Device

Tip #4:

Prioritize Critical Images

Below The Fold

Etsy 82%

Velocity 91%

Guardian 92%

Page Content

Not Visible 62%

Visible 38%

On A Typical Page & Desktop Screen…

Image Requests

Not Visible 80%

Visible 20%

Download & Hide

Download & Hide

img {display: none}

Download & Hide

Image Requests 79 78

Image Weight 2,258 KB 2,251 KB

Lazy Load Images

<img src="book.jpg" alt="A Book">

<img src="1px.gif" data-src="book.jpg" alt="A Book" onload="loadImage(this)">

Lazy Load Images<script> function loadImage(img) { var dataSrc = imgs[i].getAttribute("data-src"); if (dataSrc && isAboveTheFold(img)) { img.onload = null; img.src = dataSrc; } } </script> <img src="1px.gif" data-src="book.jpg" alt="A Book" onload="loadImage(this)">

Lazy Load Images<script> function loadImage(img) { var dataSrc = imgs[i].getAttribute("data-src"); if (dataSrc && isAboveTheFold(img)) { img.onload = null; img.src = dataSrc; } } // Repeat check on viewport changes (scroll, resize...) </script> <img src="1px.gif" data-src="book.jpg" alt="A Book" onload="loadImage(this)">

Defer Load Images<script> function loadImage(img, force) { var dataSrc = imgs[i].getAttribute("data-src"); if (dataSrc && (force || isAboveTheFold(img)) ) { img.onload = null; img.src = dataSrc; } else if (deferOthers) { window.addEventListener("load",

function() { loadImage(img,true)}); }} </script>

The Infamous

PRELOADER

HTML Parser<html> <head> <script src="main.js"></script> <link src="styles.css" type="text/css"> </head> <body> <img src="book.jpg"/> <img src="bag.jpg"/> </body> </html>

HTML Parser

main.js

styles.css

book.jpg

bag.jpg

7

<html> <head> <script src="main.js"></script> <link src="styles.css" type="text/css"> </head> <body> <img src="book.jpg"/> <img src="bag.jpg"/> </body> </html>

HTML Parser & Pre-parser

main.js

styles.css

book.jpg

bag.jpg

<html> <head> <script src="main.js"></script> <link src="styles.css" type="text/css"> </head> <body> <img src="book.jpg"/> <img src="bag.jpg"/> </body> </html>

HTML Parser & Pre-parser

main.js

styles.css

book.jpg

bag.jpg

<html> <head> <script src="main.js"></script> <link src="styles.css" type="text/css"> </head> <body> <img src="book.jpg"/> <img src="bag.jpg"/> </body> </html>

HTML Parser & Pre-parser

main.js

styles.css

book.jpg

bag.jpg

11

<html> <head> <script src="main.js"></script> <link src="styles.css" type="text/css"> </head> <body> <img src="book.jpg"/> <img src="bag.jpg"/> </body> </html>

Who Initiates Image Downloads?

CSS 20%

HTML Parser 37%

Pre-parser 43%

Source: Ilya Grigorik, HTTP Archive

HTML Parser & Pre-parser… <img src="1px.gif" data-src=“book.jpg" onload="loadImage(this)"/> <img src="bag.jpg" data-src="bag.jpg" onload="loadImage(this)"/> …

main.js

styles.css

book.jpg

bag.jpg

11

Excess Images

Pre-Parser Boost

Protip #1: LQIP Low Quality Image Placeholders

<img src=“LowQ.jpg” data-src=”HighQ.jpg” onload=“loadImage(this)”/>

Protip #1: LQIP Low Quality Image Placeholders

LowQ.jpg Quality: 25 Size: 16 KB

<img src=“LowQ.jpg” data-src=”HighQ.jpg” onload=“loadImage(this)”/>

Protip #1: LQIP Low Quality Image Placeholders

LowQ.jpg Quality: 25 Size: 16 KB

<img src=“LowQ.jpg” data-src=”HighQ.jpg” onload=“loadImage(this)”/>

HighQ.jpg Quality: 90 Size: 66 KB

Protip #2: Selective Lazy Load

<img class="responsive-img" sizes="(min-width: 980px) 460px, (min-width: 740px) 340px, 100%" srcset="/w-460/<id>/500.jpg 460w, /w-340/<id>/500.jpg 340w,

/w-445/<id>/500.jpg 445w, /w-605/<id>/620.jpg 605w" src="/w-300/<id>/500.jpg">

Protip #2: Selective Lazy Load

<img class="js-lazy-loaded-image responsive-img"

data-srcset="/w-220/<id>/1000.jpg 220w,

/w-160/<id>/1000.jpg 160w, /w-127/<id>/1000.jpg 127w"

data-sizes="(min-width: 980px) 220px,

(min-width: 740px) 160px, 127px" src="data:image/gif;base64,R0lGODlhAQABAAAAACH 5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">

Protip #2: Selective Lazy Load

JS Disabled

<img class="js-lazy-loaded-image responsive-img"

data-srcset="/w-220/<id>/1000.jpg 220w,

/w-160/<id>/1000.jpg 160w, /w-127/<id>/1000.jpg 127w"

data-sizes="(min-width: 980px) 220px,

(min-width: 740px) 160px, 127px" src="data:image/gif;base64,R0lGODlhAQABAAAAACH 5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">

Tip #4:

Prioritize Critical Images

Image Operations

Tip #5: Encode WellQuality Curve is NOT a Standard

“Save For Web” is NOT just quality

Decoding Is Standard, Encoding Is Not

Notable Deltas: Chroma Subsampling, Per-Region Quality, Lossy PNG, SSIM-Based Quality…

If you use one tool: ImageOptim (benchmark)

Tip #6: Image Management Service

5 breakpoints * 2 Pixel Ratios * 3 Views *5 thumbnails * 100,000 Products/Articles…

And tomorrow?

/q75/w120/book.jpg GET /book.jpg

OriginTranscoder

<Big, High Res Img><Right-Sized Img>

Image Compression

Choose The Right Format

Control Quality

Image Loading

Use Responsive Images

Prioritize Critical Content

Image Operations

Encode Well

Transcode in Proxy

Enforce a Performance Budget

Thank You! Guy Podjarny

@guypod

Guy Podjarny, Tobias Baldauf & Mike McCall

High Performance ImagesSHRINK, LOAD, AND DELIVER IMAGES FOR SPEED

Book Preview (developer.akamai.com/stuff)