Cargando imágenes de una forma óptima
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Qué hago
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Page Load Time
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Versión A
React
Alicante
2017
Speakers & Schedule
0.0s
0.3s
0.6s
0.9s
1.2s
Versión B
React
Alicante
2017
Speakers & Schedule
0.0s
0.3s
0.6s
0.9s
1.2s
React
Alicante
2017
Speakers & Schedule
React
Alicante
2017
React
Alicante
2017
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Rendimiento percibido por el usuario
(User Perceived Performance)
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
fin = tiempo final en milisegundos
R = % de pantalla renderizado
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
WebPageTest
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Más kilobytes
mejorar el rendimiento percibido
puede, a veces,
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Evitando esto:
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Técnicas para mejorar el rendimiento percibido
- Server-side rendering
- Critical CSS
- JS Async
- Fuentes Async
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
¿Qué pasa con las imágenes?
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
imágenes
1795kB (54%)
scripts
453kB (14%)
vídeos
756kB (23%)
fuente: http archive 15 agosto 2017
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Usar o no usar imágenes
Reduce las peticiones de imágenes
CONSEJO 1
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
en especial las de mapa de bits (JPG, PNG, WebP...)
Minimalismo | Diseño Flat
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Hace no mucho tiempo...
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
<img src="example.png"> <!-- el navegador hará la petición -->
@media (max-width: 480px) {
img {
display: none;
}
}
Cómo NO ocultar imágenes (1/2)
HTML
CSS
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
<body>
<section class="section-1">
<p>Esta es la sección actual</p>
<img src="example-1.png">
</section>
<section class="section-2 hidden">
<p>Esta sección quizás se muestre luego</p>
<img src="example-2.png"> <!-- el navegador pedirá esta imagen -->
</section>
</body>
.hidden { display: none; }
Cómo NO ocultar imágenes (2/2)
HTML
CSS
Optimiza tus imágenes
CONSEJO 2
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
formato adecuado
gif | png | jpg | webp | <lo_que_venga_después>
<picture>
<source type="image/webp" srcset="2700x1209/mi-imagen.webp 2700w,
1024x1024/mi-imagen.webp 1024w,
600x600/mi-imagen.webp 600w"
sizes="100vw" />
<source srcset="2700x1209/mi-imagen.jpg 2700w,
1024x1024/mi-imagen.jpg 1024w,
600x600/mi-imagen.jpg 600w"
sizes="100vw" />
<img src="600x600/mi-imagen.jpg" alt="Mi preciosa imagen" />
</picture>
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
compresión
· sin pérdida (lossless)
· perceptual
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
1 columna
2 columnas
3 columnas
Responsive
CONSEJO 3
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
<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="Alicante">
Reto: Mantener sincronizado el markup y el CSS
Ejemplo
IMÁGENES RESPONSIVE
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Usar lazy-loading en imágenes
CONSEJO 4
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
<img> encima del fold
&
Lazy debajo del fold
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Intersection
Observer
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
// cargar imagen cuando esté a <= 100 px del viewport
const options = {
rootMargin: '100px'
}
const callback = entries => {
entries.forEach(entry => {
if (entry.intersectionRatio > 0) {
// cargar imagen
}
});
};
const observer = new IntersectionObserver(callback, options);
observer.observe(document.querySelector('.lazy-img'));
Ejemplo
INTERSECTION OBSERVER
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
class LazyImage extends React.Component {
constructor() {
this.observer = new IntersectionObserver(entries => {
if (entries[0].intersectionRatio > 0) {
// ¡hacer la petición!
}
});
this.element = null; /* render() le dará valor a través de un ref */
}
componentDidMount() {
this.observer.observe(this.element);
}
componentWillUnmount() {
this.observer.unobserve(this.element);
}
...
}
Encapsulación en React
INTERSECTION OBSERVER
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Soporte
INTERSECTION OBSERVER
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Qué mostrar mientras la imagen se está cargando
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Opciones
PLACEHOLDERS
Nada
Placeholder
Color sólido
Carga progresiva o "Blur-up"
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Ejemplos de colores sólidos
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Ejemplos de
carga progresiva de imágenes
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Medium
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Medium
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Quartz (qz.com)
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Quartz (qz.com)
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Quora
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Cómo se hace
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
HTML - Medium
<figure>
<div>
<div/> <!-- este div mantiene el espacio con la correcta
proporción de la imagen, para que no se "colapse" -->
<img/> <!-- pequeña imagen con baja resolución (por
ejemplo 27x17) y baja calidad -->
<canvas/> <!-- toma la imagen anterior y aplica filtro "blur" -->
<img/> <!-- la imagen final (grande) que se va a mostrar -->
<noscript/> <!-- fallback para cuando no hay JS -->
</div>
</figure>
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
JPEGs progresivos
Baseline
Progressive
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Con el método de JPEGs progresivos [...] la fluidez cognitiva se inhibe y el cerebro tiene que hacer un mayor esfuerzo para darle sentido a lo que se está mostrando.
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Thumbnails
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
42 x 42px con máxima compresión
Siendo creativos con SVGs
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
SVG
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
SVG
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Dibujando con SVG
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Dibujando imágenes
de mapa de bits
Canny Edge Detector
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@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>
- Buscar el contorno con un detector de bordes Canny
- Crear líneas
- Usar JS y SVG para animar
Cómo dibujar imágenes
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
¿Deberíamos hacer esto?
Que se pueda hacer no significa que se deba hacer
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
- Reducir peticiones
- Elegir el formato adecuado y optimizar
- Utilizar imágenes responsive
- Aplicar lazy loading
- ¡Innovar!
Resumen
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Desarrollar Web es divertido.
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
buscamos desarrolladores web,
preguntadme para saber más
¡Gracias!
@jmperezperez