PROGRESSIVE IMAGE RENDERING
@jmperezperez
About me
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Page Load Time
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Version A
JSDayES
Madrid
2017
Speakers & Schedule
0.0s
0.3s
0.6s
0.9s
1.2s
Version B
JSDayES
Madrid
2017
Speakers & Schedule
0.0s
0.3s
0.6s
0.9s
1.2s
JSDayES
Madrid
2017
Speakers & Schedule
JSDayES
Madrid
2017
JSDayES
Madrid
2017
PROGRESSIVE IMAGE RENDERING
@jmperezperez
User Perceived Performance
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
More kilobytes
improved perceived performance
can sometimes lead to
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
1712kB (66%)
scripts
426kB (16%)
other
464kB (18%)
source: http archive 15 apr 2017
To use or not to use images
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
1 column
2 columns
3 columns
Responsive
TIP 2
<img sizes="(max-width: 30em) 100vw,
(max-width: 50em) 50vw,
calc(33vw - 100px)"
srcset="profile-200.jpg 200w,
profile-400.jpg 400w,
profile-800.jpg 800w,
profile-1600.jpg 1600w"
src="profile-400.jpg" alt="Pinchito">
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
What to show while the image is loading
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Options
PROGRESSIVE IMAGE RENDERING
PLACEHOLDERS
Nothing
Placeholder
Solid colour
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
Progressive JPEGs
Baseline
Progressive
PROGRESSIVE IMAGE RENDERING
@jmperezperez
With the Progressive JPEG method [...] cognitive fluency is inhibited and the brain has to work slightly harder to make sense of what is being displayed.
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Inlining thumbnail image in payload
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Unfortunately, the standard JPEG header is hundreds of bytes in size. In fact, the JPEG header alone is several times bigger than our entire 200-byte budget. However, excluding the JPEG header, the encoded data payload itself was approaching our 200 bytes.
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Header (Quantization Table and Huffman Table) | Compressed Data |
---|
Client (mobile app) GraphQL
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Thumbnails
Getting creative with SVGs
PROGRESSIVE IMAGE RENDERING
@jmperezperez
PROGRESSIVE IMAGE RENDERING
@jmperezperez
SVG
PROGRESSIVE IMAGE RENDERING
@jmperezperez
SVG
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Drawing with SVG
PROGRESSIVE IMAGE RENDERING
@jmperezperez
Drawing bitmap images
Canny Edge Detector
PROGRESSIVE IMAGE RENDERING
@jmperezperez
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
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
- Innovate!
Summary
The Web is fun.
PROGRESSIVE IMAGE RENDERING
@jmperezperez
talk with me for more info
Thanks!
@jmperezperez