Caricamento lento ibrido: una migrazione progressiva al caricamento lento nativo

Pubblicato: 2022-03-10
Riepilogo rapido ↬ Il caricamento lento nativo sta arrivando sul Web. Dal momento che non dipende da JavaScript, rivoluzionerà il modo in cui carichiamo i contenuti oggi, rendendo più facile per gli sviluppatori caricare immagini e iframe in modo lento. Ma non è una funzionalità che possiamo riempire con il polyfill e ci vorrà del tempo prima che diventi utilizzabile su tutti i browser. In questo articolo imparerai come funziona e come puoi sostituire progressivamente il caricamento lento basato su JavaScript con la sua alternativa nativa, grazie al caricamento lento ibrido.

Nelle ultime settimane, potresti aver sentito o letto del caricamento lento nativo, che arriverà su Chromium 75 nei prossimi mesi.

"Sì, un'ottima notizia, ma dovremo aspettare che tutti i browser lo supportino."

Se questa è stata la prima cosa che ti è passata per la mente, continua a leggere. Proverò a convincerti del contrario.

Iniziamo con un confronto tra il caricamento lento nativo e il buon vecchio basato su JavaScript.

Caricamento lento basato su JavaScript e nativo

Il caricamento lento è un modo per migliorare le prestazioni di un sito Web o di un'applicazione Web massimizzando la velocità di rendering delle immagini above-the-fold e degli iframe (e talvolta dei video) posticipando il caricamento del contenuto below-the-fold.

Caricamento lento basato su JavaScript

Per caricare in modo pigro immagini o iframe, è una pratica molto comune contrassegnarli sostituendo l'attributo src corretto con un attributo di dati simile, data-src , quindi fare affidamento su una soluzione JavaScript per rilevare quando le immagini/iframe vengono vicino alla parte visibile del sito (tipicamente perché l'utente effettua lo scroll) e di copiare gli attributi dei dati in quelli propri, innescando poi il caricamento differito dei loro contenuti.

 <img data-src="turtle.jpg" alt="Lazy turtle" class="lazy">
Altro dopo il salto! Continua a leggere sotto ↓

Caricamento pigro nativo

Secondo la specifica nativa di caricamento lento (ancora in fase di sviluppo), se si desidera caricare in modo lento immagini o iframe utilizzando la funzione di caricamento lento nativa, è sufficiente aggiungere l'attributo loading=lazy sul tag correlato.

 <img src="turtle.jpg" alt="Lazy turtle" loading="lazy">

Addy Osmani ha scritto ampiamente su questo argomento nel suo articolo "Native Image Lazy-Loading For The Web!" in cui ha affermato che il team di Google Chrome sta già sviluppando la funzionalità e intende distribuirla in Chrome 75.

Anche altri browser basati su Chromium come Opera e Microsoft Edge trarranno vantaggio da questo sviluppo ottenendo la stessa funzionalità nel loro primo aggiornamento basato su Chromium 75.

Inizia con il caricamento lento nativo

Nel caso in cui le immagini del tuo sito web vengano scaricate tutte in una volta all'atterraggio della pagina senza caricamento lento, puoi abilitare (ove supportato) il caricamento lento nativo nel tuo sito web con la stessa facilità con cui aggiungi un attributo HTML. L'attributo loading indica ai browser quali immagini è importante caricare immediatamente e quali possono essere scaricate pigramente mentre gli utenti scorrono verso il basso. Lo stesso attributo può essere applicato agli iframe.

Per dire ai browser che una particolare immagine è importante in modo che possano caricarla il prima possibile, devi aggiungere l'attributo loading="eager" sul tag img . La procedura migliore consiste nell'eseguire questa operazione per le immagini primarie, in genere per quelle che verranno visualizzate above the fold.

 <img src="rabbit.jpg" alt="Fast rabbit" loading="eager">

Per dire ai browser che un'immagine deve essere scaricata pigramente, aggiungi semplicemente l'attributo loading="lazy" . Questa è una procedura consigliata solo se lo fai solo su immagini secondarie, in genere quelle verranno visualizzate sotto la piega.

 <img src="turtle.jpg" alt="Lazy turtle" loading="lazy">

Semplicemente aggiungendo l'attributo di loading alle tue immagini e iframe, consentirai al tuo sito Web di utilizzare il caricamento lento nativo come miglioramento progressivo. Il tuo sito web ne trarrà gradualmente vantaggio man mano che il supporto arriva ai tuoi utenti nella maggior parte dei browser moderni.

Questo è l'approccio migliore da utilizzare se il tuo sito Web non utilizza alcun tipo di caricamento lento oggi, ma se hai già implementato una soluzione di caricamento lento basata su JavaScript, potresti voler mantenerla mentre passi progressivamente al caricamento lento nativo.

La soluzione ideale sarebbe iniziare subito a utilizzare il caricamento lento nativo e utilizzare un polyfill per farlo funzionare su tutti i browser. Sfortunatamente, il caricamento lento nativo non è una funzionalità che possiamo riempire con JavaScript.

Nessun uso per un Polyfill

Quando una nuova tecnologia browser viene rilasciata a un singolo browser, la comunità open source di solito rilascia un polyfill JavaScript per fornire la stessa tecnologia al resto dei browser. Ad esempio, il polyfill IntersectionObserver utilizza elementi JavaScript e DOM per coordinare Element.getBoundingClientRect() per riprodurre il comportamento dell'API nativa.

Ma il caso del caricamento lento nativo è diverso perché un polyfill JavaScript per loading="lazy" dovrebbe impedire ai browser di caricare il contenuto non appena trovano un URL nel markup di un'immagine o di un iframe. JavaScript non ha alcun controllo su questa fase iniziale del rendering della pagina, quindi non è possibile eseguire il polyfill del caricamento lento nativo.

Caricamento lento ibrido

Se non sei soddisfatto di avere il caricamento lento nativo solo come miglioramento progressivo, o hai già implementato il caricamento lento basato su JavaScript e non vuoi perdere questa funzionalità nei browser meno moderni (ma vuoi comunque abilitare il caricamento lento nativo sui browser che lo supportano), allora hai bisogno di una soluzione diversa. Presentazione: caricamento lento ibrido.

Il caricamento lento ibrido è una tecnica per utilizzare il caricamento lento nativo sui browser che lo supportano, altrimenti, fare affidamento su JavaScript per gestire il caricamento lento.

Per eseguire il caricamento lento ibrido, è necessario eseguire il markup del contenuto pigro utilizzando gli attributi dei data anziché quelli reali (come nel caricamento lento basato su JavaScript) e aggiungere l'attributo loading="lazy" .

 <img data-src="turtle.jpg" loading="lazy" alt="Lazy turtle">

Quindi hai bisogno di JavaScript. In primo luogo, è necessario rilevare se il caricamento lento nativo è supportato o meno dal browser . Quindi, esegui una delle seguenti operazioni per ogni elemento con l'attributo loading="lazy" :

  • Se il caricamento lento nativo è supportato, copiare il valore dell'attributo data-src nell'attributo src ;
  • Se non è supportato, inizializza uno script di caricamento lento JavaScript o un plug-in per farlo quando gli elementi entrano nel viewport.

Non è molto difficile scrivere il codice JavaScript richiesto per eseguire queste operazioni da solo. È possibile rilevare se il caricamento lento nativo è supportato con la condizione:

 if ('loading' in HTMLImageElement.prototype)

Se lo è, copia semplicemente il valore dell'attributo src da data-src . In caso contrario, inizializza uno script di caricamento lento a tua scelta.

Ecco un frammento di codice che lo fa.

 <!-- In-viewport images should be loaded normally, or eagerly --> <img src="important.jpg" loading="eager" alt="Important image"> <!-- Let's lazy-load the rest of these images --> <img data-src="lazy1.jpg" loading="lazy" alt="Lazy image 1"> <img data-src="lazy2.jpg" loading="lazy" alt="Lazy image 2"> <img data-src="lazy3.jpg" loading="lazy" alt="Lazy image 3"> <script> (function() { if ("loading" in HTMLImageElement.prototype) { var lazyEls = document.querySelectorAll("[loading=lazy]"); lazyEls.forEach(function(lazyEl) { lazyEl.setAttribute( "src", lazyEl.getAttribute("data-src") ); }); } else { // Dynamically include a lazy loading library of your choice // Here including vanilla-lazyload var script = document.createElement("script"); script.async = true; script.src = "https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"; window.lazyLoadOptions = { elements_selector: "[loading=lazy]" //eventually more options here }; document.body.appendChild(script); } })(); </script>

Puoi trovare e testare il codice sopra in questa demo dal vivo.

Tuttavia, questo è uno script molto semplice e le cose possono complicarsi quando si utilizzano attributi o tag aggiuntivi per ottenere immagini reattive (come gli attributi srcset e sizes o anche i tag picture e source ).

Un piccolo aiuto di terze parti

Negli ultimi quattro anni, ho mantenuto uno script di caricamento lento open source chiamato " vanilla-lazyload " e, in un paio di giorni dopo che Addy Osmani ha scritto sul caricamento lento nativo, la comunità ha reagito chiedendomi se il mio script poteva agire come un polyfill.

Come ho spiegato prima, non è possibile creare un polyfill per la funzione di caricamento lento nativo, tuttavia, ho pensato a una soluzione che rendesse più semplice per gli sviluppatori iniziare la transizione al caricamento lento nativo, senza dover scrivere il codice JavaScript che Ho accennato prima.

A partire dalla versione 12 di vanilla-lazyload , puoi semplicemente impostare l'opzione use_native su true per abilitare il caricamento lazy ibrido. Lo script ha solo 2,0 kB gzippato ed è già disponibile su GitHub, npm e jsDelivr.

  • Scopri vanilla-lazyload su GitHub

Demo

Puoi iniziare a giocare con il caricamento lento nativo oggi scaricando Chrome Canary o Microsoft Edge Insider ( canale di sviluppo ), quindi abilitando i flag "Abilita caricamento lento delle immagini" e "Abilita caricamento lento dei frame". Per abilitare questi flag, inserisci about:flags nel campo URL del tuo browser e cerca "lazy" nella casella di ricerca.

Demo di caricamento lento nativo

Per analizzare come funziona il caricamento lento nativo negli strumenti per sviluppatori, puoi iniziare a giocare con la demo seguente. In questo, non viene utilizzata una singola riga di JavaScript . Sì, è solo un caricamento lento nativo completo.

  • Prova la demo di caricamento lento nativo

Cosa aspettarsi : tutte le immagini vengono recuperate contemporaneamente, ma con risposte HTTP diverse. Quelle con il codice di risposta 200 sono le immagini caricate avidamente, mentre quelle con il codice di risposta 206 vengono recuperate solo parzialmente per ottenere le informazioni iniziali sulle immagini. Quelle immagini verranno quindi recuperate completamente con un codice di risposta 200 quando scorri verso il basso.

Demo di caricamento lento ibrido

Per analizzare come funziona il caricamento lento ibrido, puoi iniziare a giocare con la prossima demo. Qui viene utilizzato [email protected] e l'opzione use_native è impostata su true :

  • Prova la demo di caricamento lento ibrido

Cosa aspettarsi : prova la demo su diversi browser per vedere come si comporta. Sui browser che supportano il caricamento lento nativo, il comportamento sarebbe lo stesso della demo di caricamento lento nativo. Sui browser che non supportano il caricamento lento nativo, le immagini verranno scaricate mentre scorri verso il basso.

Tieni presente che vanilla-lazyload utilizza l'API IntersectionObserver sotto il cofano, quindi dovresti eseguirne il polyfill su Internet Explorer e versioni meno recenti di Safari. Tuttavia, non è un grosso problema se non viene fornito un polyfill, perché in tal caso vanilla-lazyload scaricherebbe tutte le immagini contemporaneamente.

Nota : Leggi di più nel capitolo "To Polyfill or Not To Polyfill" del file readme di vanilla-lazyload .

Prova il caricamento lento ibrido nel tuo sito web

Poiché il caricamento lento nativo arriverà presto su alcuni browser, perché non gli dai una possibilità oggi usando il caricamento lento ibrido? Ecco cosa devi fare:

Marcatura HTML

Il markup dell'immagine più semplice è costituito da due attributi: src e alt .

Per le immagini above-the-fold, dovresti lasciare l'attributo src e aggiungere l'attributo loading="eager" .

 <img src="important.jpg" loading="eager" alt="Important image">

Per le immagini below-the-fold, dovresti sostituire l'attributo src con l'attributo data-src e aggiungere l'attributo loading="lazy" .

 <img data-src="lazy.jpg" loading="lazy" alt="A lazy image">

Se desideri utilizzare immagini reattive, fai lo stesso con gli attributi srcset e sizes .

 <img alt="A lazy image" loading="lazy" data-src="lazy.jpg">

Se preferisci usare il tag picture , cambia srcset , sizes e src anche nei tag source .

 <picture> <source media="(min-width: 1200px)"> <source media="(min-width: 800px)"> <img alt="A lazy image" loading="lazy" data-src="lazy.jpg"> </picture>

Il tag picture può essere utilizzato anche per caricare selettivamente il formato WebP per le tue immagini.

Nota : se vuoi conoscere più usi di vanilla-lazyload , leggi la sezione HTML "Guida introduttiva" del suo file readme.

Codice JavaScript

Prima di tutto, devi includere vanilla-lazyload sul tuo sito web.

Puoi caricarlo da un CDN come jsDelivr:

 <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"></script>

Oppure puoi installarlo usando npm:

 npm install vanilla-lazyload@12

È anche possibile utilizzare uno script async con inizializzazione automatica; caricalo come modulo ES usando type="module" o caricalo come AMD usando RequireJS. Trova altri modi per includere e utilizzare vanilla-lazyload nella sezione dello script "Guida introduttiva" del file readme.

Quindi, nel codice JavaScript del tuo sito web/applicazione web, includi quanto segue:

 var pageLazyLoad = new LazyLoad({ elements_selector: "[loading=lazy]", use_native: true // ← enables hybrid lazy loading });

Nota : lo script ha molte altre impostazioni che puoi usare per personalizzare il comportamento di vanilla-lazyload , ad esempio per aumentare la distanza dell'area di scorrimento da cui iniziare a caricare gli elementi o per caricare gli elementi solo se sono rimasti nella finestra per un tempo a disposizione. Trova altre impostazioni nella sezione API del file Leggimi.

Tutti insieme, utilizzando uno script async

Per mettere tutto insieme e utilizzare uno script async per massimizzare le prestazioni, fare riferimento al seguente codice HTML e JavaScript:

 <!-- In-viewport images should be loaded normally, or eagerly --> <img src="important.jpg" loading="eager" alt="Important image"> <!-- Let's lazy-load the rest of these images --> <img data-src="lazy1.jpg" loading="lazy" alt="Lazy image 1"> <img data-src="lazy2.jpg" loading="lazy" alt="Lazy image 2"> <img data-src="lazy3.jpg" loading="lazy" alt="Lazy image 3"> <!-- Set the options for the global instance of vanilla-lazyload --> <script> window.lazyLoadOptions = { elements_selector: "[loading=lazy]", use_native: true // ← enables hybrid lazy loading }; </script> <!-- Include vanilla lazyload 12 through an async script --> <script async src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"></script>

Questo è tutto! Con questi passaggi molto semplici e facili, avrai abilitato il caricamento lento ibrido nel tuo sito web!

Migliori pratiche importanti

  • Applica il caricamento lento solo alle immagini che sai che probabilmente verranno visualizzate sotto la piega. Carica con ansia quelli above the fold per massimizzare le prestazioni. Se applichi solo il lazy load a tutte le immagini nella tua pagina, rallenterai le prestazioni di rendering.
  • Usa i CSS per riservare spazio alle immagini prima che vengano caricate. In questo modo, spingeranno il resto del contenuto di seguito. Se non lo fai, un numero maggiore di immagini verrà posizionato above the fold prima che dovrebbero, attivando download immediati per loro. Se hai bisogno di un trucco CSS per farlo, puoi trovarne uno nella sezione suggerimenti e trucchi del readme di vanilla-lazyload .

Pro e contro

CARICAMENTO LAZY NATIVE
PROFESSIONISTI
  • Nessun JavaScript richiesto;
  • Nessun mal di testa di installazione, funziona e basta;
  • Non c'è bisogno di riservare spazio alle immagini usando trucchi CSS;
CONTRO
  • Oggi non funziona su tutti i browser;
  • Il carico utile iniziale è maggiore, a causa del prefetch dei 2 kb iniziali per ogni immagine.
CARICAMENTO LAZY GUIDATO DA JAVASCRIPT
PROFESSIONISTI
  • Funziona in modo coerente su tutti i browser, in questo momento;
  • Puoi eseguire trucchi dell'interfaccia utente altamente personalizzati, come l'effetto sfocatura o il caricamento ritardato.
CONTRO
  • Si basa su JavaScript per caricare i tuoi contenuti.
CARICAMENTO IBRIDO LAZY
PROFESSIONISTI
  • Ti dà la possibilità di abilitare e testare il caricamento lento nativo dove supportato;
  • Consente il caricamento lento su tutti i browser;
  • È possibile rimuovere in modo trasparente la dipendenza dello script non appena il supporto del caricamento lento nativo sarà diffuso.
CONTRO
  • Si basa ancora su JavaScript per caricare i tuoi contenuti.

Avvolgendo

Sono molto entusiasta dell'arrivo del caricamento lento nativo sui browser e non vedo l'ora che tutti i fornitori di browser lo implementino!

Nel frattempo, puoi scegliere di arricchire il tuo markup HTML per un miglioramento progressivo e ottenere il caricamento lento nativo solo dove supportato, oppure puoi optare per il caricamento lento ibrido e ottenere il caricamento lento nativo e basato su JavaScript fino al giorno in cui il caricamento lento nativo lo farà essere supportato dalla stragrande maggioranza dei browser.

Provaci! Non dimenticare di recitare / guardare vanilla-lazyload su GitHub e fammi sapere i tuoi pensieri nella sezione commenti.

Ulteriori letture su SmashingMag:

  • Ora mi vedi: come differire, caricare pigro e agire con IntersectionObserver
  • Moduli JavaScript a caricamento lento con ConditionerJS
  • Elenco di controllo delle prestazioni front-end 2019 (PDF, pagine Apple, MS Word)
  • In che modo il miglioramento delle prestazioni del sito Web può aiutare a salvare il pianeta