
Привет!
What will we see today?
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Improve perceived performance of images on the web
PROGRESSIVE IMAGE RENDERING
@jmperezperez
by
- not making requests
- optimizing images
- rendering previews
PROGRESSIVE IMAGE RENDERING
@jmperezperez
PROGRESSIVE IMAGE RENDERING
@jmperezperez

About me


Page Load Time
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Version A
FrontFest
2017
Speakers & Schedule
0.0s
0.3s
0.6s
0.9s
1.2s
Version B
FrontFest
2017
Speakers & Schedule
0.0s
0.3s
0.6s
0.9s
1.2s
FrontFest
2017
Speakers & Schedule
FrontFest
2017
FrontFest
2017
PROGRESSIVE IMAGE RENDERING
@jmperezperez

Source https://www.smashingmagazine.com/2015/11/why-performance-matters-part-2-perception-management/
PROGRESSIVE IMAGE RENDERING
@jmperezperez
PROGRESSIVE IMAGE RENDERING
@jmperezperez
end = end time in milliseconds
VC = % visually complete
PROGRESSIVE IMAGE RENDERING
@jmperezperez
WebPageTest

PROGRESSIVE IMAGE RENDERING
@jmperezperez

Avoiding this:
PROGRESSIVE IMAGE RENDERING
@jmperezperez

Techniques to improve perceived performance
- Server-side rendering
- Critical CSS
- Async JS
- Async fonts
PROGRESSIVE IMAGE RENDERING
@jmperezperez
What about images?
PROGRESSIVE IMAGE RENDERING
@jmperezperez
PROGRESSIVE IMAGE RENDERING
@jmperezperez
images
1,815kB (54%)
scripts
457kB (14%)
other
1,106kB (33%)
source: http archive 1 nov 2017

PROGRESSIVE IMAGE RENDERING
@jmperezperez

Minimalist | Flat Design
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Not that long ago


Optimise your images
PROGRESSIVE IMAGE RENDERING
@jmperezperez
TIP 1
PROGRESSIVE IMAGE RENDERING
@jmperezperez

right format
gif | png | jpg | webp | <the_next_thing>
PROGRESSIVE IMAGE RENDERING
@jmperezperez
<picture>
<source type="image/webp" srcset="2700x1209/my-image.webp 2700w,
1024x1024/my-image.webp 1024w,
600x600/my-image.webp 600w"
sizes="100vw" />
<source srcset="2700x1209/my-image.jpg 2700w,
1024x1024/my-image.jpg 1024w,
600x600/my-image.jpg 600w"
sizes="100vw" />
<img class="rsImg" src="600x600/my-image.jpg" alt="My beautiful image" />
</picture>
compression
PROGRESSIVE IMAGE RENDERING
@jmperezperez
· lossless
· perceptual
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Responsive
TIP 2



1 column
2 columns
3 columns
<img sizes="(max-width: 30em) 100vw,
(max-width: 50em) 50vw,
calc(33vw - 100px)"
srcset="red-square-200.jpg 200w,
red-square-400.jpg 400w,
red-square-800.jpg 800w,
red-square-1600.jpg 1600w"
src="red-square-400.jpg"
alt="Red Square">
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Challenge: Keeping in sync markup and CSS
Example
RESPONSIVE IMAGES
Lazy-load images
PROGRESSIVE IMAGE RENDERING
@jmperezperez
TIP 3

<img> above the fold
&
Lazy below the fold
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Intersection
Observer

PROGRESSIVE IMAGE RENDERING
@jmperezperez
// load image when it's within 100px of the viewport
const options = {
rootMargin: '100px'
}
const callback = entries => {
entries.forEach(entry => {
if (entry.intersectionRatio > 0) {
// load image
}
});
};
const observer = new IntersectionObserver(callback, options);
observer.observe(document.querySelector('.lazy-img'));
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Example
INTERSECTION OBSERVER
class LazyImage extends React.Component {
constructor() {
this.observer = new IntersectionObserver(entries => {
if (entries[0].intersectionRatio > 0) {
// load!
}
});
this.element = null; /* render() will set it through a ref */
}
componentDidMount() {
this.observer.observe(this.element);
}
componentWillUnmount() {
this.observer.unobserve(this.element);
}
...
}
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Encapsulating in React
INTERSECTION OBSERVER
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Using image.decode()
IMAGE DECODING
// Image loading with predecoding
const img = new Image();
img.src = "image.jpg";
img.decode().then(() => {
document.body.appendChild(img);
}).catch(() => {
throw new Error('Could not load/decode big image.');
});
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Using image.decode()
IMAGE DECODING
Add an image to the DOM without causing a decoding delay.
Track the proposal on https://github.com/whatwg/html/issues/1920
TIP 4
What to show while the image is loading
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Options
PROGRESSIVE IMAGE RENDERING
PLACEHOLDERS
Nothing
Placeholder
Solid colour or gradient
Progressive image loading or "Blur-up"
@jmperezperez



Examples of solid color
PROGRESSIVE IMAGE RENDERING
@jmperezperez
PROGRESSIVE IMAGE RENDERING
@jmperezperez

PROGRESSIVE IMAGE RENDERING
@jmperezperez
PROGRESSIVE IMAGE RENDERING
@jmperezperez
PROGRESSIVE IMAGE RENDERING
@jmperezperez
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Examples of
Progressive Image Loading
PROGRESSIVE IMAGE RENDERING
@jmperezperez
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Medium

PROGRESSIVE IMAGE RENDERING
@jmperezperez
Medium
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Quartz (qz.com)

PROGRESSIVE IMAGE RENDERING
@jmperezperez
Quartz (qz.com)
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Quora

PROGRESSIVE IMAGE RENDERING
@jmperezperez
How it is done



PROGRESSIVE IMAGE RENDERING
@jmperezperez
Markup - Eg Medium
<figure>
<div>
<div/> <!-- this div keeps the aspect ratio so
the placeholder doesn't collapse -->
<img/> <!-- this is a tiny image with a small
resolution (e.g. ~27x17) and low quality -->
<canvas/> <!-- takes the above image and applies a blur filter -->
<img/> <!-- the large image to be displayed -->
<noscript/> <!-- fallback for no JS -->
</div>
</figure>
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Thumbnails


PROGRESSIVE IMAGE RENDERING
@jmperezperez
Thumbnails



Getting creative with SVGs
PROGRESSIVE IMAGE RENDERING
@jmperezperez
PROGRESSIVE IMAGE RENDERING
@jmperezperez
SVG - Edges
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Drawing edges with SVG
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Drawing bitmap images

Canny Edge Detector
PROGRESSIVE IMAGE RENDERING
@jmperezperez
<svg>
<polyline points="51,1 61,1 61,2 56,4 56,3"/>
<polyline points="52,1 50,2 51,3 50,4 50,9 46,10 46,8 48,8 48,9"/>
<polyline points="61,4 61,5 58,6"/>
...
<polyline points="62,58 61,59 61,60 50,62 50,61 51,61"/>
</svg>
- Find edges with canny edge detector
- Create lines
- Use JS and SVG to animate
How to draw bitmaps
PROGRESSIVE IMAGE RENDERING
@jmperezperez
SVG - Shapes
PROGRESSIVE IMAGE RENDERING
@jmperezperez
PROGRESSIVE IMAGE RENDERING
@jmperezperez
SVG - Shapes

SVG - 10 shapes
SVG - 100 shapes
Original
0.74kB
3.5kB
101kB
PROGRESSIVE IMAGE RENDERING
@jmperezperez
SVG - Shapes + Blur
SVG - 10 shapes + Blur
SVG 100 shapes + Blur
(JPEG or WebP) + Blur
0.8kB
3.6kB
0.5kB (JPEG)
0.09 kB (WebP)

PROGRESSIVE IMAGE RENDERING
@jmperezperez
SVG - Silhouettes / Traces

PROGRESSIVE IMAGE RENDERING
@jmperezperez
SVG - Silhouettes / Traces

PROGRESSIVE IMAGE RENDERING
@jmperezperez
SVG - Silhouettes / Traces
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Should we do this?
Just because you can it doesn't mean you should
PROGRESSIVE IMAGE RENDERING
@jmperezperez
- Reduce requests
- Choose the right format and optimise
- Embrace responsive images
- Try to lazy load
- Think about placeholders
- Innovate!
Summary
The Web is fun.
PROGRESSIVE IMAGE RENDERING
@jmperezperez
talk with me for more info
Thanks!
@jmperezperez
Slides on https://slides.com/jmperez