Il tuo sito ha immagini pesanti e il PageSpeed Insight ti penalizza? Ogni kilobyte caricato in ritardo è un cliente che potrebbe andarsene. Noi, di Meteora Web, lo vediamo tutti i giorni: siti con decine di immagini caricate tutte insieme, anche quelle che l'utente non vede mai. Il risultato? Tempi di caricamento lunghi, Core Web Vitals sotto la soglia, e Google che ti penalizza. La soluzione si chiama lazy loading: caricare le immagini solo quando servono. In questa guida ti mostriamo come implementarlo con due tecniche: native loading='lazy' e Intersection Observer. Partiamo dal problema concreto: la tua home ha 12 immagini fuori schermo? Stai pagando per farle caricare tutte.
Perché il Lazy Loading delle Immagini è Fondamentale per le Performance?
Immagina di entrare in un negozio e il commesso ti mostra tutto il catalogo in una volta, anche gli articoli del reparto che non ti interessa. Sarebbe uno spreco di tempo. Su un sito web funziona allo stesso modo: il browser deve scaricare, decodificare e renderizzare ogni immagine presente nel DOM, anche quelle che l'utente non ha ancora scrollato. Con il lazy loading rimandiamo il caricamento delle immagini fuori schermo finché l'utente non si avvicina a vederle. Questo riduce il tempo di caricamento iniziale (FCP, LCP) e la quantità di dati trasferiti.
Sponsored Protocol
L'effetto sui Core Web Vitals è diretto: un LCP più basso significa miglior posizionamento. Secondo dati interni, ottimizzando il lazy loading su un e-commerce con 40 immagini per pagina, abbiamo ridotto il tempo di caricamento del 35% e migliorato il LCP di oltre 1 secondo. Non è teoria: è contabilità.
Differenza tra Lazy Loading Nativo e Intersection Observer
Il browser offre oggi due modi per implementare il caricamento differito delle immagini:
- Native lazy loading (loading='lazy') — attributo HTML supportato da tutti i browser moderni. Basta aggiungere
loading="lazy"ai tag<img>o<iframe>. Il browser decide quando caricare l'immagine, basandosi sulla distanza dall'area visibile (viewport). - Intersection Observer API — API JavaScript più flessibile: osservi un elemento e quando entra nel viewport (o a una soglia che imposti) esegui una callback. Puoi personalizzare il comportamento, ad esempio caricare prima le immagini (pre-lazy) o applicare effetti di fade-in.
Quale scegliere? Se vuoi la strada più semplice e affidabile, usa native. Se hai esigenze avanzate (placeholder animati, caricamento progressivo, supporto per immagini in CSS background), Intersection Observer ti dà il controllo totale.
Sponsored Protocol
Come Funziona il Native Lazy Loading e Quando Usarlo?
Il native lazy loading è il metodo più facile: basta aggiungere loading="lazy" all'immagine. Nessun JavaScript, nessuna libreria. Il browser si occupa di tutto, rispettando le soglie predefinite (di solito inizia a caricare quando l'immagine è a circa 1250 pixel dal viewport).
Sponsored Protocol
Implementazione Pratica di loading='lazy'
<img src="immagine-pesante.jpg" alt="Descrizione" loading="lazy" width="800" height="600">
Importante: specifica sempre width e height per evitare il Cumulative Layout Shift (CLS). Il browser riserva lo spazio anche se l'immagine non è ancora caricata.
Esempio con immagini in una griglia di prodotti:
<div class="grid">
<img src="prodotto1.jpg" alt="Prodotto 1" loading="lazy" width="300" height="300">
<img src="prodotto2.jpg" alt="Prodotto 2" loading="lazy" width="300" height="300">
<!-- … -->
</div>
Supporto Browser e Fallback
Native lazy loading è supportato da Chrome 76+, Firefox 75+, Safari 15.4+, Edge 79+. Per browser vecchi (es. Safari <15.4) puoi usare un fallback con Intersection Observer. Noi spesso combiniamo entrambi: proviamo prima native, se non supportato attiviamo Observer.
Quando Scegliere Native vs JavaScript
- Native è sufficiente per la maggior parte dei siti: blog, landing page, portfolio.
- Intersection Observer è necessario se vuoi:
– Applicare effetti di caricamento (placeholder, blur-up)
– Caricare immagini solo dopo un certo tempo (es. per pagine infinite scroll)
– gestire il lazy loading su immagini di background CSS
Come Implementare il Lazy Loading con Intersection Observer?
Intersection Observer è un'API JavaScript nativa (disponibile dal 2017) che ti permette di osservare quando un elemento entra in una certa area (intersezione) con il viewport. Perfetto per lazy loading avanzato.
Codice Base: Caricare Immagini al Comparire nel Viewport
Ecco uno snippet funzionante che puoi copiare e incollare nel tuo tema:
document.addEventListener("DOMContentLoaded", function() {
const lazyImages = document.querySelectorAll("img[data-src]");
if ("IntersectionObserver" in window) {
const imageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src; // carica l'immagine vera
img.removeAttribute("data-src");
img.classList.add("loaded");
observer.unobserve(img);
}
});
}, { rootMargin: "200px 0px" }); // carica 200px prima che entri
lazyImages.forEach(function(img) {
imageObserver.observe(img);
});
} else {
// Fallback: carica tutte subito
lazyImages.forEach(function(img) {
img.src = img.dataset.src;
});
}
});
Come funziona: metti l'URL reale in data-src e un placeholder in src (es. img trasparente). L'observer attiva il caricamento quando l'immagine entra nel viewport, con un margine di 200px per anticipare lo scroll.
Gestire Placeholder e Effetti Visivi
Puoi aggiungere un piccolo placeholder SVG (o sottile immagine compressa) come src iniziale, poi applicare una transizione CSS quando arriva l'immagine reale:
img[data-src] {
opacity: 0.3;
transition: opacity 0.3s ease-in-out;
}
img.loaded {
opacity: 1;
}
Oppure usa una tecnica di blur-up: carica una miniatura pixellata come src, poi sostituisci con l'immagine full-size. Noi abbiamo usato questa tecnica per un cliente e-commerce: le immagini passavano da 1 MB a 400 KB con fade-in, e LCP è calato del 40%.
Lazy Loading per Immagini di Background CSS
Intersection Observer può gestire anche immagini caricate tramite CSS background. Esempio:
<div class="hero lazy-bg" data-bg="url('sfondo.jpg')">…</div>
const lazyBgs = document.querySelectorAll(".lazy-bg");
const bgObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const el = entry.target;
el.style.backgroundImage = el.dataset.bg;
el.classList.add("bg-loaded");
observer.unobserve(el);
}
});
}, { rootMargin: "100px" });
lazyBgs.forEach(el => bgObserver.observe(el));
Come Testare e Validare il Tuo Lazy Loading?
Non basta implementare: devi verificare che funzioni e che non causi regressioni.
- Google PageSpeed Insights — se le immagini fuori schermo non vengono caricate, non compaiono nei consigli di “leverage lazy loading”.
- Lighthouse (sezione Performance) — controlla la voce “Defer offscreen images”.
- Chrome DevTools > Network — filtra per “img” e scrolla: vedrai le immagini caricarsi man mano che scendi.
- Visual check — assicurati che le immagini non appaiano vuote o con placeholder rotti su browser vecchi (test su Safari 14, Chrome 70).
Errori Comuni da Evitare
- Mancanza di dimensioni esplicite: se non specifichi width/height, il browser riserva spazio zero e poi ridimensiona l'immagine, causando CLS. Sempre width/height.
- Immagine above-the-fold con lazy loading: non applicare lazy loading alle immagini visibili all'inizio. Peggiora l'LCP. Usa
loading="eager"o semplicemente non aggiungere l'attributo. - RootMargin troppo piccolo: se carichi l'immagine esattamente quando entra, potresti vedere un flash di placeholder. Aggiungi margine (es. 200-300px) per caricare prima.
- Dimenticare i fallback: per browser che non supportano Intersection Observer (IE11) o native lazy, fallback a caricamento immediato.
Quale Tecnica Scegliere per il Tuo Progetto?
Non c'è una risposta unica. Ecco come decidiamo noi di Meteora Web:
- Sito WordPress con Elementor: native lazy loading (spesso già abilitato di default, ma controlla che non sia in conflitto con plugin di caching).
- E-commerce WooCommerce con tante immagini: Intersection Observer con placeholder e fade-in. Il controllo sull'esperienza utente vale la complessità.
- Single-page application (Vue, React): nativamente hanno lazy loading via framework, ma aggiungere Intersection Observer per immagini in componenti non ancora montati è utile.
- Progetti con CMS custom: usiamo uno script unico che prova native, fallback a Observer, e in fondo carica tutto se nulla funziona.
Ricorda: il costo di una immagine caricata in ritardo è basso, il costo di una immagine caricata subito è alto. Ogni millisecondo risparmiato sul carico iniziale è un vantaggio competitivo.
Cosa Fare Adesso
- Analizza il tuo sito con PageSpeed Insights. Identifica le immagini offscreen che non sono lazy.
- Aggiungi loading='lazy' a tutte le immagini sotto la prima piega. Se usi WordPress, molti temi già lo fanno; altrimenti modifica il file functions.php o usa un plugin.
- Implementa Intersection Observer se hai bisogno di controllo avanzato. Inizia con lo snippet sopra, poi personalizza placeholder e margini.
- Testa su browser reali: Safari mobile, Chrome, Firefox. Controlla che non ci siano immagini bianche o rotture.
- Misura l'impatto sui Core Web Vitals (LCP, CLS). Una buona implementazione può ridurre LCP di 0.5-2 secondi.
Se vuoi approfondire tutto l'ecosistema delle performance, leggi il nostro pillar dedicato: Core Web Vitals e PageSpeed — la guida pillar.