High Performance Images: Beautiful Shouldn't Mean Slow


The Presentation inside:

Slide 0

High Performance Images Beautiful shouldn’t mean Slow @guypod


Slide 1

Average Web Page Weight
 (Sep ’15) Not 37% Images 63% @guypod Source: HTTP Archive


Slide 2

Images On Average Page 1,383 KB 1,128 KB 891 KB ~2x!!! 696 KB 50 Reqs 56 Reqs 55 Reqs 54 Reqs Sep '12 Jun '13 Jun '14 Sep '15 Requests @guypod Source: HTTP Archive KB


Slide 3

Images Impact Performance 19000 -30% 14250 9500 4750 0 With Images @guypod No Images Load Time, 3G Speed


Slide 4

What Can you do? @guypod


Slide 5

Image Compression @guypod


Slide 6

Image Loading @guypod


Slide 7

Operationalizing 
 Image Optimization @guypod


Slide 8

Image Compression @guypod


Slide 9

Average Resource Size CSS 9 KB JS 16 KB JPEG 37 KB 0 @guypod 10 20 30 40


Slide 10

RWD Sites Use Big Images 40 30 20 RWD Not RWD 31.6 KB 20.8 KB 10 10 KB 7.1 KB 0 JPEG Size @guypod PNG Size


Slide 11

Tip #1: 
 Pick The Right Format @guypod


Slide 12

Image Formats On The Web Other 2% GIF 23% JPEG 45% PNG 30% @guypod


Slide 13

GIF • 28 Years Old (1987) • 256 Colors • Supports “Simple” Transparency • Supports Animation • Patented (now expired) @guypod


Slide 14

PNG • 19 Years Old (1996) • 8-32 bit color palettes • Alpha Transparency • Not patented @guypod


Slide 15

GIF -> PNG = 21% Savings PNG File Size @guypod GIF File Size Source: Styoan Stefanov, “Give PNG A Chance” (2009)


Slide 16

JPEG • 23 years old (1992) • RGB Colors (24 bit) • No Transparency Support • A Lossy Format @guypod


Slide 17

JPEG Lossy 
 Compression Bitmap ≠ Bitmap PNG Lossless 
 Compression Bitmap @guypod = Bitmap


Slide 18

JPEG • 23 years old (1992) • RGB Colors (24 bit) • No Transparency Support • A Lossy Format @guypod


Slide 19

PNG -> JPG = MUCH Smaller PNG, 574 KB @guypod JPG, 110 KB


Slide 20

JPEG: No Transparency PNG @guypod JPEG


Slide 21

WebP 3.3 3.27 bpp -26% 2.475 15 14.4 KB -31% 11.25 2.42 bpp 9.9 KB 1.65 7.5 0.825 3.75 0 0 PNG WebP Bytes Per Pixel @guypod JPEG (q75) WebP File Size (KB) Source: Google Studies


Slide 22

WebP Browser Support @guypod


Slide 23

BPG • Less than 1 year old • Lossless & Lossy • Based on Video encoder HEVC • • • H.265, successor of H.264 Beat WebP & J2K in Mozilla Study Free (LGPL) @guypod Fabrice Bellard
 (Creator of ffmpeg)


Slide 24

FLIF • 0 years old • Lossless • Progressive • Responsive Friendly • No browser support • Free (GPL) @guypod Source: FLIF Creators Jon Sneyers & Harshad RJ


Slide 25

PNG vs Others @guypod Source: Cloudinary


Slide 26

New Format Bakeoff @guypod Source: Cloudinary


Slide 27

FLIF - 3rd Party Stats @guypod Source: Cloudinary


Slide 28

New Image Formats WebP JPEG XR JPEG 2000 Support Chrome, Opera,
 Android 4.x IE 10+ Safari on
 iOS, OS X Savings
 (over JPEG) 40-50% ~25% 15-20% Mime Type image/webp Identification Accept: image/ webp @guypod image/vnd.ms-photo Soon: image/jxr image/jp2 Detect 
 IE 10+ Detect
 Safari 5+


Slide 29

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> @guypod


Slide 30

Using Custom Formats Server Side, Single URL GET /book.jpg GET /book.jpg CDN/Cache @guypod Origin


Slide 31

Using Custom Formats Server Side, Single URL GET /book.jpg GET /book.jpg GET /book.webp GET /book.jpg Accept: image/webp CDN/Cache @guypod Origin


Slide 32

Using Custom Formats Server Side, Single URL GET /book.jpg GET /book.jpg GET /book.webp GET /book.jpg Accept: image/webp GET /book.jxr GET /book.jpg User-Agent: MSIE 10 * Spartan Accept: image/jxr* @guypod CDN/Cache Origin


Slide 33

Tip #1: 
 Pick The Right Format @guypod


Slide 34

Tip #2: 
 Control Quality @guypod


Slide 35

JPEG Quality Low 
 Quality @guypod High 
 Quality


Slide 36

Quality: 90
 Size: 66 KB Quality: 75
 Size: 37 KB Quality: 40
 Size: 21 KB Quality: 25
 Size: 16 KB @guypod


Slide 37

Quality: 90
 Size: 66 KB @guypod Quality: 75
 Size: 37 KB Quality: 40
 Size: 21 KB Quality: 25
 Size: 16 KB


Slide 38

Quality Scale Is Per Format 0.25 JPEG JPEG XR WebP Similarity 0.19 0.13 0.06 0.00 0 25 50 75 Quality @guypod Source: Nick Doyle Performance Calendar 100


Slide 39

Detecting Excessive Quality WebPageTest • Some stats about image quality on the web? @guypod


Slide 40

Detecting Excessive Quality PageSpeed Insights • Some stats about image quality on the web? @guypod


Slide 41

Tip #2: 
 Control Quality @guypod


Slide 42

SIZE Doesn’t matter
 It’s all about TECHNIQUE @guypod


Slide 43

Image Loading @guypod


Slide 44

Tip #3: 
 Size Images To Device @guypod


Slide 45

Download & Shrink 102 KB 1876 × 520
 (975,520 pixels) @guypod


Slide 46

Download & Shrink 1876px 520px 866px 240px .hp07img {width: 100%} @guypod


Slide 47

Download & Shrink 1876px 520px 975,520 pixels 866px 240px 207,840 pixels 79% wasted pixels (~770K) @guypod


Slide 48

Download & Shrink 1876px 520px 110,744 Bytes 866px 240px 79% wasted pixels 68% wasted bytes (~75KB) @guypod 35,345 Bytes


Slide 49

Download & Shrink 1876px 520px 975,520 * 4(RGBA) = 3.9M Memory Bytes 866px 79% wasted pixels 68% wasted bytes 79% wasted memory (3MB) @guypod 240px 831K Mem Bytes


Slide 50

54 IMAGES On an Average Page @guypod


Slide 51

“...25% of new Android phones 
 have only 512MB of RAM.” – Jen Fitzpatrick, Google Maps @guypod


Slide 52

Download & Shrink Processing Times @guypod Source: Tim Kadlec, “Mobile Image Processing”


Slide 53

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"> @guypod


Slide 54

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… @guypod


Slide 55

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… @guypod


Slide 56

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> @guypod


Slide 57

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> @guypod Use Picturefill


Slide 58

Which Breakpoints To Use? What Are your Users Using? @guypod


Slide 59

Which Breakpoints To Use? How Big & Complex Are Your Images? Width Height File Size 1 453 302 44K 579 386 65K 4 687 458 85K 5 786 524 104K 6 885 590 124K 7 975 650 142K 8 @guypod 25K 3 Your Analytics 213 2 • 320 990 660 151K Source: Jason Grigsby, 
 “Sensible Jumps In Responsive Image File Sizes”


Slide 60

Which Breakpoints To Use? How Big & Complex Are Your Images? point # Width Height File Size 1 Your Analytics @guypod 213 9.0K 2 731 487 29K 3 • 320 990 660 40K Source: Jason Grigsby, 
 “Sensible Jumps In Responsive Image File Sizes”


Slide 61

FLIF Progressive “Breakpoints” @guypod


Slide 62

FLIF Progressive “Breakpoints” 1969x1307 pixels 299,643 bytes @guypod


Slide 63

FLIF Progressive “Breakpoints” 1969x1307 pixels All 299,643 bytes 653x985 pixels (1:2) First 80,389 bytes @guypod


Slide 64

FLIF Progressive “Breakpoints” 1969x1307 pixels All 299,643 bytes 653x985 pixels (1:2) First 80,389 bytes 492x326 pixels (1:4)
 First 37,014 bytes @guypod


Slide 65

Tip #3: 
 Size Images To Device @guypod


Slide 66

Tip #4: 
 Prioritize Critical Images @guypod


Slide 67

Below The Fold Etsy 82% @guypod Velocity 91% Guardian 92%


Slide 68

On A Typical Page & Desktop Screen… Page Content Image Requests Visible 20% Visible 38% Not Visible 62% @guypod Not Visible 80%


Slide 69

Download & Hide @guypod


Slide 70

Download & Hide img {display: none} @guypod


Slide 71

Download & Hide Image Requests 79 78 Image Weight 2,258 KB 2,251 KB @guypod


Slide 72

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


Slide 73

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)"> @guypod


Slide 74

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)"> @guypod


Slide 75

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> @guypod


Slide 76

The Infamous PRELOADER @guypod


Slide 77

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> @guypod


Slide 78

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> @guypod main.js styles.css book.jpg bag.jpg 7


Slide 79

HTML Parser & Pre-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> @guypod main.js styles.css book.jpg bag.jpg


Slide 80

HTML Parser & Pre-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> @guypod main.js styles.css book.jpg bag.jpg


Slide 81

HTML Parser & Pre-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> @guypod 11 main.js styles.css book.jpg bag.jpg


Slide 82

Who Initiates Image Downloads? CSS 20% Pre-parser 43% HTML Parser 37% Source: Ilya Grigorik, HTTP Archive @guypod


Slide 83

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 @guypod 11


Slide 84

HTTP/1.1 @guypod HTTP/2


Slide 85

Pre-Parser
 Boost @guypod Excess
 Images


Slide 86

Protip #1: LQIP Low Quality Image Placeholders <img src=“LowQ.jpg” data-src=“HighQ.jpg” 
 onload=“loadImage(this)”> @guypod


Slide 87

Protip #1: LQIP Low Quality Image Placeholders <img src=“LowQ.jpg” data-src=“HighQ.jpg” 
 onload=“loadImage(this)”> LowQ.jpg Quality: 25
 Size: 16 KB @guypod


Slide 88

Protip #1: LQIP Low Quality Image Placeholders <img src=“LowQ.jpg” data-src=“HighQ.jpg” 
 onload=“loadImage(this)”> LowQ.jpg Quality: 25
 Size: 16 KB HighQ.jpg Quality: 90
 Size: 66 KB @guypod


Slide 89

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"> @guypod


Slide 90

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=="> @guypod


Slide 91

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=="> @guypod JS 
 Disabled


Slide 92

Tip #4: 
 Prioritize Critical Images @guypod


Slide 93

Operationalizing 
 Image Optimization @guypod


Slide 94

Tip #5: Encode Well • Quality 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) @guypod


Slide 95

Tip #6: 
 Use Image Management Service 5 breakpoints * 2 Pixel Ratios * 3 Views *
 5 thumbnails * 100,000 Products/Articles… And tomorrow? @guypod


Slide 96

Tip #6: 
 Use Image Management Service 5 breakpoints * 2 Pixel Ratios * 3 Views *
 5 thumbnails * 100,000 Products/Articles… And tomorrow? Origin Transcoder /q75/w120/book.jpg <Right-Sized Img> @guypod GET /book.jpg <Big, High Res Img>


Slide 97

Image Manager @guypod


Slide 98

Cloudinary @guypod


Slide 99

What Can You Do? Image Compression Image 
 Loading Image Operations Choose The 
 Right Format Use Responsive Images Encode Well Transcode in Proxy Control Quality Prioritize Critical Content Enforce a Performance Budget @guypod


Slide 100

FREE Copy at
 http://bit.ly/hpi-preview @guypod


Slide 101

Thank You! Guy Podjarny @guypod Reminder Free HPI Link:
 @guypod http://bit.ly/hpi-preview


Slide 102


×

HTML:





Ссылка: