Best practice per il caricamento lento

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:

Sono un&#39;immagine!

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.