Mentre il caricamento lento di immagini e video ha un rendimento positivo e misurabile vantaggi, non è un compito da prendere con leggerezza. Se ti sbagli, potresti conseguenze indesiderate. Di conseguenza, è importante mantenere quanto segue: in mente.
Mind the fold
Potresti avere la tentazione di eseguire il caricamento lento di ogni singola risorsa multimediale sulla pagina con JavaScript, ma devi resistere a questa tentazione. Qualsiasi elemento che si trovi al di sopra il fold non deve essere caricato tramite caricamento lento. Queste risorse devono essere considerate critiche asset, quindi devono essere caricati normalmente.
Il caricamento lento ritarda il caricamento delle risorse fino a quando il DOM non è interattivo
al termine del caricamento degli script
e ne inizia l'esecuzione. Per le immagini al di sotto di
fold, va bene, ma le risorse critiche above the fold dovrebbero essere caricate con
l'elemento <img>
standard in modo che vengano visualizzati il prima possibile.
Ovviamente, il punto in cui si trova il fold non è così chiaro al giorno d'oggi quando i siti web visualizzati su tantissimi schermi di varie dimensioni. Che cosa c'è above the fold su un laptop potrebbe trovarsi sotto sui dispositivi mobili. Non esistono consigli a prova di proiettile per per affrontare questo problema in modo ottimale in ogni situazione. Dovrai condurre una inventario degli asset critici della tua pagina e carica le immagini in formato moda.
Inoltre, è bene che tu non voglia essere troppo severo riguardo alla linea di piegatura
soglia per attivare il caricamento lento. Per i tuoi scopi potrebbe essere una soluzione
stabilire una zona buffer a una certa distanza below the fold affinché le immagini inizino
prima che l'utente li scorra nell'area visibile. Ad esempio,
L'API Intersection Observer consente di specificare una proprietà rootMargin
in un
quando crei una nuova istanza IntersectionObserver
. Questo
fornisce efficacemente agli elementi un buffer, che attiva il caricamento lento prima
l'elemento si trova nell'area visibile:
let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
// lazy-loading image code goes here
}, {
rootMargin: "0px 0px 256px 0px"
});
Se il valore del campo rootMargin
è simile a quello indicato per un CSS
margin
proprietà, perché lo è! In questo caso,
margine inferiore dell'elemento osservato (l'area visibile del browser per impostazione predefinita,
può essere modificato in un elemento specifico utilizzando la proprietà root
) viene ampliato di 256
pixel. Ciò significa che la funzione di callback viene eseguita quando un elemento immagine viene
entro 256 pixel dall'area visibile e il caricamento dell'immagine inizierà
prima che l'utente lo veda.
Per ottenere lo stesso effetto nei browser che non supportano la funzione Osserva intersezione, utilizza il codice per la gestione degli eventi di scorrimento e modifica il valore
getBoundingClientRect
controllo per includere un buffer.
Spostamento del layout e segnaposto
Il caricamento lento dei contenuti multimediali può causare variazioni nel layout se non vengono utilizzati i segnaposto. Queste modifiche possono disorientare gli utenti e attivare un layout DOM costoso e operazioni che consumano risorse di sistema e contribuiscono al jank. Come minimo, valuta la possibilità di utilizzare un segnaposto per colore a tinta unita che abbia le stesse dimensioni immagine target, oppure tecniche come LQIP o SQIP che suggeriscono i contenuti di un contenuto multimediale prima che venga caricato.
Per i tag <img>
, src
deve inizialmente puntare a un segnaposto fino a quando
viene aggiornato con l'URL finale dell'immagine. Utilizza l'attributo poster
in un
Elemento <video>
per puntare a un'immagine segnaposto. Inoltre, usa width
e
height
nei tag <img>
e <video>
. Ciò garantisce che
la transizione dai segnaposto alle immagini finali non modificherà le dimensioni visualizzate
dell'elemento quando vengono caricati gli elementi multimediali.
Ritardi della decodifica delle immagini
Il caricamento di immagini di grandi dimensioni in JavaScript e il loro rilascio nel DOM può
il thread principale, causando la mancata risposta da parte dell'interfaccia utente per un breve periodo di tempo
durante la decodifica. Decodifica delle immagini in modo asincrono utilizzando l'interfaccia decode
metodo
prima di inserirli nel DOM può ridurre questo tipo di jank,
Fai attenzione: non è ancora disponibile ovunque e aggiunge complessità alla logica di caricamento lento.
Se vuoi utilizzarlo, dovrai verificarlo. Sotto i programmi
come potresti utilizzare Image.decode()
con un fallback:
var newImage = new Image();
newImage.src = "my-awesome-image.jpg";
if ("decode" in newImage) {
// Fancy decoding logic
newImage.decode().then(function() {
imageContainer.appendChild(newImage);
});
} else {
// Regular image load
imageContainer.appendChild(newImage);
}
Dai un'occhiata a questo link CodePen per scoprire un codice simile a questo esempio. Se la maggior parte delle immagini è di piccole dimensioni, questo potrebbe non fare molto per te, ma sicuramente può aiutarti a ridurre le jank quando il caricamento lento di immagini di grandi dimensioni e la loro inserimento nel DOM.
Quando non vengono caricati contenuti
A volte le risorse multimediali non vengono caricate per un motivo o per l'altro causando errori che si verificano. Quando potrebbe verificarsi il problema? Dipende, ma ecco uno scenario ipotetico Hai una norma di memorizzazione nella cache HTML per un breve periodo di tempo (ad es. minuti) e l'utente visita il sito o se ha una scheda non attiva aperta per un lungo periodo di tempo (ad es. diverse ore) e torna per leggere i contenuti. A un certo punto del processo, viene eseguito un nuovo deployment. Durante il deployment, il nome della risorsa immagine cambia a causa del controllo delle versioni basato su hash o viene rimosso del tutto. Nel momento in cui l'utente esegue il caricamento lento dell'immagine, la risorsa non è disponibile e quindi non funziona.
Anche se si tratta di occorrenze relativamente rare, potrebbe essere necessario avere un backup se il caricamento lento non va a buon fine. Per le immagini, la soluzione potrebbe avere un aspetto simile a questo:
var newImage = new Image();
newImage.src = "my-awesome-image.jpg";
newImage.onerror = function(){
// Decide what to do on error
};
newImage.onload = function(){
// Load the image
};
Le azioni che decidi di intraprendere in caso di errore dipendono dall'applicazione. Per Ad esempio, puoi sostituire l'area segnaposto dell'immagine con un pulsante che ti consente all'utente di tentare di caricare nuovamente l'immagine o semplicemente visualizzare un messaggio di errore nell'area segnaposto dell'immagine.
Potrebbero sorgere anche altri scenari. Qualsiasi cosa tu faccia, non è mai una cattiva idea segnalare all'utente quando si è verificato un errore ed eventualmente eseguire un'azione da prendere in caso di problemi.
Disponibilità di JavaScript
Non si deve presumere che JavaScript sia sempre disponibile. Se vuoi
le immagini con caricamento lento, valuta la possibilità di offrire un markup <noscript>
che mostri le immagini in
case JavaScript non è disponibile. L'esempio di fallback più semplice possibile prevede
utilizzare elementi <noscript>
per pubblicare immagini se JavaScript è disattivato:
Se JavaScript è disattivato, gli utenti vedranno sia l'immagine segnaposto che
immagine contenuta con gli elementi <noscript>
. Per evitare questo problema,
una classe no-js
nel tag <html>
in questo modo:
<html class="no-js">
Successivamente, inserisci una riga di script incorporato nella sezione <head>
prima di qualsiasi foglio di stile
vengono richieste tramite tag <link>
che rimuove la classe no-js
da <html>
se JavaScript è attivato:
<script>document.documentElement.classList.remove("no-js");</script>
Infine, usa alcuni CSS per nascondere elementi con una classe di elementi lazy quando JavaScript non è disponibile:
.no-js .lazy {
display: none;
}
Ciò non impedisce il caricamento delle immagini segnaposto, ma il risultato è maggiore desiderabile. Gli utenti con JavaScript disattivato ottengono qualcosa di più del segnaposto un'immagine, che è migliore dei segnaposto e non hanno contenuti significativi tutti.