CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
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
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
fin = tiempo final en milisegundos
R = % de pantalla renderizado
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
puede, a veces,
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
imágenes
1795kB (54%)
scripts
453kB (14%)
vídeos
756kB (23%)
fuente: http archive 15 agosto 2017
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CONSEJO 1
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
en especial las de mapa de bits (JPG, PNG, WebP...)
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
<img src="example.png"> <!-- el navegador hará la petición -->
@media (max-width: 480px) {
img {
display: none;
}
}
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; }
HTML
CSS
CONSEJO 2
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
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
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
1 columna
2 columnas
3 columnas
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
IMÁGENES RESPONSIVE
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CONSEJO 4
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
&
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
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'));
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);
}
...
}
INTERSECTION OBSERVER
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
INTERSECTION OBSERVER
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
PLACEHOLDERS
Nada
Placeholder
Color sólido
Carga progresiva o "Blur-up"
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
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
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
<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
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
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
42 x 42px con máxima compresión
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
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>
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
Que se pueda hacer no significa que se deba hacer
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
CARGANDO IMÁGENES EN LA WEB
@jmperezperez
buscamos desarrolladores web,
preguntadme para saber más
@jmperezperez