Cargando imágenes en la web de una forma óptima

A presentation at Alicante Frontend in September 2017 in Alicante, Spain by José M. Pérez

Slide 1

Slide 1

Cargando imágenes de una forma óptima José M. Pérez · Desarrollador Web en Spotify @jmperezperez http://spoti.fi/alicante-frontend

Slide 2

Slide 2

CARGANDO IMÁGENES EN LA WEB @jmperezperez Qué hago

Slide 3

Slide 3

CARGANDO IMÁGENES EN LA WEB @jmperezperez

Slide 4

Slide 4

CARGANDO IMÁGENES EN LA WEB @jmperezperez Page Load Time

Slide 5

Slide 5

CARGANDO IMÁGENES EN LA WEB @jmperezperez 0.0s 0.3s 0.6s 0.9s 1.2s React Alicante Versión A 2017 Speakers & Schedule 0.0s Versión B 0.3s 0.6s 0.9s 1.2s React Alicante React Alicante React Alicante React Alicante 2017 2017 2017 2017 Speakers & Schedule Speakers & Schedule

Slide 6

Slide 6

CARGANDO IMÁGENES EN LA WEB @jmperezperez Rendimiento percibido por el usuario (User Perceived Performance)

Slide 7

Slide 7

CARGANDO IMÁGENES EN LA WEB @jmperezperez SpeedIndex = f in ∫0 1− fin = tiempo final en milisegundos R = % de pantalla renderizado R 100

Slide 8

Slide 8

CARGANDO IMÁGENES EN LA WEB @jmperezperez WebPageTest

Slide 9

Slide 9

CARGANDO IMÁGENES EN LA WEB @jmperezperez

Slide 10

Slide 10

CARGANDO IMÁGENES EN LA WEB @jmperezperez Más kilobytes puede, a veces, mejorar el rendimiento percibido

Slide 11

Slide 11

CARGANDO IMÁGENES EN LA WEB @jmperezperez Evitando esto:

Slide 12

Slide 12

CARGANDO IMÁGENES EN LA WEB @jmperezperez Técnicas para mejorar el rendimiento percibido Server-side rendering Critical CSS JS Async Fuentes Async

Slide 13

Slide 13

CARGANDO IMÁGENES EN LA WEB @jmperezperez ¿Qué pasa con las imágenes?

Slide 14

Slide 14

CARGANDO IMÁGENES EN LA WEB @jmperezperez imágenes vídeos scripts 1795kB (54%) 756kB (23%) 453kB (14%) fuente: http archive 15 agosto 2017

Slide 15

Slide 15

Slide 16

Slide 16

Usar o no usar imágenes

Slide 17

Slide 17

CARGANDO IMÁGENES EN LA WEB @jmperezperez CO N SE JO 1 Reduce las peticiones de imágenes en especial las de mapa de bits (JPG, PNG, WebP...)

Slide 18

Slide 18

CARGANDO IMÁGENES EN LA WEB @jmperezperez Minimalismo | Diseño Flat

Slide 19

Slide 19

CARGANDO IMÁGENES EN LA WEB @jmperezperez Hace no mucho tiempo...

Slide 20

Slide 20

CARGANDO IMÁGENES EN LA WEB @jmperezperez

Slide 21

Slide 21

CARGANDO IMÁGENES EN LA WEB @jmperezperez

Slide 22

Slide 22

CARGANDO IMÁGENES EN LA WEB @jmperezperez Cómo NO ocultar imágenes (1/2) CSS @media (max-width: 480px) { img { display: none; } } HTML <img src="example.png"> <!-- el navegador hará la petición -->

Slide 23

Slide 23

CARGANDO IMÁGENES EN LA WEB @jmperezperez Cómo NO ocultar imágenes (2/2) CSS .hidden { display: none; } HTML <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>

Slide 24

Slide 24

CARGANDO IMÁGENES EN LA WEB @jmperezperez CO N SE JO 2 Optimiza tus imágenes

Slide 25

Slide 25

CARGANDO IMÁGENES EN LA WEB @jmperezperez

Slide 26

Slide 26

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>

Slide 27

Slide 27

CARGANDO IMÁGENES EN LA WEB @jmperezperez compresión · sin pérdida (lossless) · perceptual

Slide 28

Slide 28

CARGANDO IMÁGENES EN LA WEB @jmperezperez Responsive 1 columna 2 columnas CO N SE 3 columnas JO 3

Slide 29

Slide 29

CARGANDO IMÁGENES EN LA WEB @jmperezperez IMÁGENES RESPONSIVE Ejemplo <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

Slide 30

Slide 30

CARGANDO IMÁGENES EN LA WEB @jmperezperez CO N SE JO Usar lazy-loading en imágenes 4

Slide 31

Slide 31

CARGANDO IMÁGENES EN LA WEB @jmperezperez <img> encima del fold & Lazy debajo del fold

Slide 32

Slide 32

CARGANDO IMÁGENES EN LA WEB @jmperezperez Intersection Observer

Slide 33

Slide 33

CARGANDO IMÁGENES EN LA WEB @jmperezperez INTERSECTION OBSERVER Ejemplo // 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'));

Slide 34

Slide 34

CARGANDO IMÁGENES EN LA WEB @jmperezperez INTERSECTION OBSERVER Encapsulación en React 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); } ... }

Slide 35

Slide 35

CARGANDO IMÁGENES EN LA WEB @jmperezperez INTERSECTION OBSERVER Soporte

Slide 36

Slide 36

CARGANDO IMÁGENES EN LA WEB @jmperezperez Qué mostrar mientras la imagen se está cargando

Slide 37

Slide 37

CARGANDO IMÁGENES EN LA WEB @jmperezperez PLACEHOLDERS Opciones Nada Placeholder Color sólido Carga progresiva o "Blur-up"

Slide 38

Slide 38

CARGANDO IMÁGENES EN LA WEB @jmperezperez Ejemplos de colores sólidos

Slide 39

Slide 39

CARGANDO IMÁGENES EN LA WEB @jmperezperez

Slide 40

Slide 40

CARGANDO IMÁGENES EN LA WEB @jmperezperez

Slide 41

Slide 41

CARGANDO IMÁGENES EN LA WEB @jmperezperez

Slide 42

Slide 42

CARGANDO IMÁGENES EN LA WEB @jmperezperez

Slide 43

Slide 43

CARGANDO IMÁGENES EN LA WEB @jmperezperez

Slide 44

Slide 44

CARGANDO IMÁGENES EN LA WEB @jmperezperez Ejemplos de carga progresiva de imágenes

Slide 45

Slide 45

CARGANDO IMÁGENES EN LA WEB @jmperezperez Medium

Slide 46

Slide 46

CARGANDO IMÁGENES EN LA WEB @jmperezperez Medium

Slide 47

Slide 47

CARGANDO IMÁGENES EN LA WEB @jmperezperez Quartz (qz.com)

Slide 48

Slide 48

CARGANDO IMÁGENES EN LA WEB @jmperezperez Quartz (qz.com)

Slide 49

Slide 49

CARGANDO IMÁGENES EN LA WEB Quora @jmperezperez

Slide 50

Slide 50

CARGANDO IMÁGENES EN LA WEB @jmperezperez Cómo se hace

Slide 51

Slide 51

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>

Slide 52

Slide 52

CARGANDO IMÁGENES EN LA WEB @jmperezperez JPEGs progresivos Baseline Progressive Fuente: https://blog.codinghorror.com/progressive-image-rendering/

Slide 53

Slide 53

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. — De Progressive image rendering: Good or evil?

Slide 54

Slide 54

CARGANDO IMÁGENES EN LA WEB @jmperezperez Thumbnails 42 x 42px con máxima compresión Fuente: https://jmperezperez.com/webp-placeholder-images/

Slide 55

Slide 55

CARGANDO IMÁGENES EN LA WEB @jmperezperez Siendo creativos con SVGs

Slide 56

Slide 56

CARGANDO IMÁGENES EN LA WEB @jmperezperez SVG Fuente: https://www.polygon.com/a/ps4-review

Slide 57

Slide 57

CARGANDO IMÁGENES EN LA WEB @jmperezperez SVG Fuente: https://www.polygon.com/a/xbox-one-review

Slide 58

Slide 58

CARGANDO IMÁGENES EN LA WEB @jmperezperez Dibujando con SVG ">//codepen.io/jmperez/embed/rxxRRg/?height=525&themeid=0&default-tab=js,result&embed-version=2"> Fuente: https://codepen.io/jmperez/pen/rxxRRg

Slide 59

Slide 59

CARGANDO IMÁGENES EN LA WEB @jmperezperez Dibujando imágenes de mapa de bits Canny Edge Detector

Slide 60

Slide 60

https://jmperezperez.com/renderconf17/extslides/contour2/index.html Fuente: https://jmperezperez.com/contour/

Slide 61

Slide 61

CARGANDO IMÁGENES EN LA WEB @jmperezperez https://jmperezperez.com/contour/ Fuente: https://jmperezperez.com/contour/

Slide 62

Slide 62

CARGANDO IMÁGENES EN LA WEB @jmperezperez Cómo dibujar imágenes 1. Buscar el contorno con un detector de bordes Canny 2. Crear líneas 3. Usar JS y SVG para animar <svg> <polyline <polyline <polyline ... <polyline </svg> points="51,1 61,1 61,2 56,4 56,3"/> points="52,1 50,2 51,3 50,4 50,9 46,10 46,8 48,8 48,9"/> points="61,4 61,5 58,6"/> points="62,58 61,59 61,60 50,62 50,61 51,61"/>

Slide 63

Slide 63

CARGANDO IMÁGENES EN LA WEB @jmperezperez ¿Deberíamos hacer esto? Que se pueda hacer no significa que se deba hacer

Slide 64

Slide 64

CARGANDO IMÁGENES EN LA WEB @jmperezperez Resumen Reducir peticiones Elegir el formato adecuado y optimizar Utilizar imágenes responsive Aplicar lazy loading ¡Innovar!

Slide 65

Slide 65

CARGANDO IMÁGENES EN LA WEB @jmperezperez Desarrollar Web es divertido.. divertido

Slide 66

Slide 66

spotify.com/jobs buscamos desarrolladores web, preguntadme para saber más

Slide 67

Slide 67

¡Gracias! @jmperezperez