JavaScript Resource Loading: onload e onerror
Scopri come gli eventi onload e onerror tracciano il caricamento di immagini, script e fogli di stile, con esempi eseguibili e pattern di fallback.
Le risorse esterne — immagini, script, fogli di stile, iframe — vengono caricate in modo asincrono e in modo indipendente rispetto al JavaScript che le richiede. Il browser avvia il download e il codice continua l'esecuzione; la risorsa potrebbe non essere pronta per millisecondi o secondi. Per sapere quando una risorsa è pronta (o se ha fallito), ogni elemento caricabile genera due eventi: load in caso di successo e error in caso di fallimento. Questa pagina mostra come utilizzarli tramite le proprietà handler onload / onerror.
Questo argomento è strettamente correlato al ciclo di vita a livello di pagina trattato in DOMContentLoaded, load, beforeunload, unload, e alle strategie di caricamento in Scripts: async, defer.
Gestione del caricamento delle risorse con l'evento onload
Che cos'è l'evento onload?
L'evento load si attiva su un elemento quando la sua risorsa ha terminato completamente il download ed è pronta all'uso. È possibile ascoltarlo in due modi equivalenti:
// 1. Handler property (only one handler allowed)
img.onload = () => { /* ... */ };
// 2. addEventListener (multiple handlers allowed)
img.addEventListener('load', () => { /* ... */ });La forma con proprietà (onload) è comoda ma memorizza un solo handler — assegnarne uno nuovo sovrascrive quello precedente. Preferire addEventListener('load', ...) quando più parti di codice si preoccupano della stessa risorsa.
Un punto importante da tenere a mente: per un <img>, l'evento load riguarda solo i byte di quella singola immagine. Non è il window.onload a livello di pagina, che attende tutte le risorse. Non bisogna confondere i due.
Esempio: Visualizzare un'immagine dopo il caricamento completo
Per illustrare il concetto, considera uno scenario in cui si vuole visualizzare un'immagine solo dopo che è stata completamente caricata, per evitare di mostrare un'immagine parziale o danneggiata.
<div>Here you see the w3docs logo when the page is loaded.</div>
<br />
<div id="imageContainer" style="background-color: grey;"></div>
<script>
document.addEventListener('DOMContentLoaded', function() {
var img = new Image();
img.onload = function() {
document.getElementById('imageContainer').appendChild(img);
};
img.src = 'https://www.w3docs.com/build/images/logo-color-w3.png';
});
</script>Questo script garantisce che l'immagine venga aggiunta al div #imageContainer solo dopo il caricamento completo, migliorando l'esperienza utente evitando la visualizzazione di un'immagine incompleta.
Imposta img.onload prima di img.src. Il browser può servire un'immagine dalla cache così velocemente che il caricamento termina nello stesso tick in cui viene assegnato src — se l'handler non è ancora stato collegato, l'evento verrà perso del tutto.
Utilizzo dell'evento onerror per la gestione degli errori
Che cos'è l'evento onerror?
L'evento onerror è essenziale per uno sviluppo web solido. Si attiva quando si verifica un errore durante il caricamento di una risorsa esterna, come uno script o un'immagine. Questo evento è fondamentale per gestire gli errori in modo elegante e garantire che l'esperienza utente rimanga ininterrotta.
Esempio: Gestione degli errori per il caricamento fallito di un'immagine
Considera uno scenario in cui un'immagine non riesce a caricarsi a causa di un link interrotto o di un problema del server. Utilizzando l'evento onerror, puoi fornire una soluzione di fallback o notificare l'utente. Nell'esempio seguente, il src non valido attiva l'handler degli errori non appena la pagina viene eseguita, perché il link dell'immagine non punta a un file reale.
Una risorsa genera o load o error, mai entrambi. Puoi quindi collegare handler per ciascuno e fare affidamento sul fatto che venga eseguito esattamente uno dei due.
<div>If there was no error, you could see an image below. But it's a broken link!</div>
<br />
<div id="imageContainer" style="background-color: grey;"></div>
<script>
const img = new Image();
const imageContainer = document.getElementById('imageContainer');
img.onerror = function() {
imageContainer.innerHTML = 'An error happened.';
};
img.onload = function() {
imageContainer.appendChild(img);
};
img.src = 'https://www.w3docs.com/build/images/broken-link.png';
</script>In questo esempio, se l'immagine non riesce a caricarsi, il contenitore mostra un messaggio di fallback al posto dell'icona di immagine non trovata, gestendo l'errore in modo trasparente.
onerror si attiva solo per i fallimenti delle risorse — un 404, una richiesta bloccata, un errore DNS o un file corrotto. Non si attiva se uno script caricato correttamente genera un'eccezione a runtime; quella viene segnalata dall'handler globale window.onerror / window.addEventListener('error', ...).
Esempio: Caricamento di uno script o di un foglio di stile
Lo stesso pattern si applica agli elementi <script> e <link>. Puoi crearli dinamicamente e collegare handler onload/onerror:
<script>
function loadScript(url) {
const script = document.createElement('script');
script.src = url;
script.onload = () => console.log('Script loaded successfully');
script.onerror = () => console.error('Failed to load script');
document.head.appendChild(script);
}
loadScript('https://example.com/app.js');
function loadStylesheet(url) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
link.onload = () => console.log('Stylesheet loaded successfully');
link.onerror = () => console.error('Failed to load stylesheet');
document.head.appendChild(link);
}
loadStylesheet('https://example.com/styles.css');
</script>Gli script creati dinamicamente si comportano come script async: vengono scaricati in parallelo ed eseguiti non appena arrivano, quindi l'ordine di caricamento non è garantito. Se uno script dipende da un altro, concatenarli all'interno dell'onload del primo script.
Esempio: Racchiudere load/error in una Promise
Per il codice moderno, racchiudere i due eventi in una Promise fornisce l'ergonomia di async/await e un unico punto in cui gestire i fallimenti:
function loadScript(src) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.onload = () => resolve(script);
script.onerror = () => reject(new Error(`Failed to load: ${src}`));
document.head.append(script);
});
}
// Usage
loadScript('https://example.com/app.js')
.then(() => console.log('Ready to use the script'))
.catch((err) => console.error(err.message));Poiché load ed error si escludono a vicenda, la Promise si risolve esattamente una volta — o risolta o rifiutata.
Ottimizzazione delle prestazioni web tramite la gestione degli eventi
L'ottimizzazione delle prestazioni web implica la gestione delle sequenze di caricamento delle risorse e la gestione dei fallimenti in modo elegante. Gli eventi onload e onerror sono particolarmente utili per l'iniezione dinamica di risorse. Invece di codificare tutti gli asset nell'HTML, puoi caricare le risorse non critiche su richiesta. Quando una risorsa non riesce a caricarsi, l'evento onerror si attiva, consentendoti di implementare una logica di fallback — come sostituire un'immagine non trovata con un segnaposto o riprovare una richiesta di script fallita. Combinando questi eventi con il rendering progressivo, garantisci che il contenuto critico appaia immediatamente mentre gli asset secondari si caricano in background, mantenendo un'esperienza utente fluida anche in condizioni di rete scadenti.
Conclusione
Comprendere e implementare gli eventi onload e onerror in JavaScript è fondamentale per qualsiasi sviluppatore web che desideri migliorare l'affidabilità e le prestazioni delle proprie applicazioni web. Utilizzando questi eventi in modo efficace, gli sviluppatori possono garantire che le risorse vengano gestite in modo efficiente, migliorando sia le prestazioni che l'esperienza utente dei loro siti web. Gli esempi forniti costituiscono un punto di partenza per implementare queste tecniche in vari scenari, favorendo una comprensione più approfondita e la padronanza del caricamento delle risorse in JavaScript.