Differire le Immagini Fuori Schermo su Mobile: Guida al Lazy Loading Nativo

Lazy loading nativo, content-visibility e perché il differimento delle immagini in JavaScript è un peso morto

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-03-10

Differimento delle Immagini su Mobile: lo standard

Le pagine mobile lottano per connessioni limitate e CPU limitata. Ogni immagine fuori schermo caricata in anticipo ruba larghezza di banda alle immagini e agli script che contano davvero per il paint iniziale.

Ultima revisione a cura di Arjen Karel a Marzo 2026

1. Differire le immagini fuori schermo su mobile: lazy loading nativo

Quando un browser carica una pagina, apre un numero limitato di connessioni parallele (dipende da molti fattori ma 6 per dominio è una media comune). Se queste connessioni vengono utilizzate per scaricare immagini fuori schermo (es. un logo nel footer o una slide di un carosello), il download di risorse critiche (tipicamente l'immagine LCP, script importanti e font) competerà per gli slot e la larghezza di banda. Questa è la contesa di rete, e degrada direttamente i tuoi Core Web Vitals.

Differendo le immagini fuori schermo utilizzando l'attributo nativo loading, dai priorità a ciò che conta. Il browser recupera solo ciò che è immediatamente visibile, riservando larghezza di banda per gli asset che impattano il Largest Contentful Paint (LCP) e il First Contentful Paint (FCP). Il lazy loading nativo scarica questa prioritizzazione sul meccanismo del browser, che è più veloce e rimuove la necessità di librerie JavaScript per il lazy loading.

Implementazione

Per tutte le immagini al di sotto del viewport iniziale ("the fold") aggiungi l'attributo loading="lazy".

<!-- Immagine Differita Standard -->
<img src="product-detail.jpg"
     loading="lazy"
     alt="Vista laterale del telaio"
     width="800"
     height="600"
     decoding="async">

Gli attributi width e height sono essenziali. Senza di essi, il browser non può riservare spazio prima che l'immagine venga caricata, il che causa un layout shift (CLS). Il 62% delle pagine mobile omette ancora di impostare dimensioni esplicite su almeno un'immagine.

Come funziona il lazy loading su mobile: L'Euristica del Browser

Il lazy loading nativo è superiore alle soluzioni JavaScript perché il browser regola la soglia di caricamento (quando un'immagine viene attivata per il download) in base all'Effective Connection Type (ECT).

  • Su 4G/WiFi: Il motore Blink (Chrome/Edge) utilizza una soglia conservativa di circa 1.250px. Presume una bassa latenza e recupera l'immagine solo quando l'utente si avvicina relativamente scorrendo.
  • Su 3G/Slow-2G: La soglia si espande a circa 2.500px. Il browser inizia la richiesta molto prima per compensare i tempi di round-trip elevati, in modo che l'immagine sia pronta prima che l'utente la scorra nella vista.

Secondo il 2025 Web Almanac, la pagina mobile mediana carica 15 immagini per un totale di 911 KB. Solo circa il 26% di quelle immagini usa loading="lazy". Il resto viene caricato in modo eager, competendo per le stesse connessioni limitate. Su una tipica connessione mobile 4G, questo significa che l'immagine LCP è bloccata in attesa dietro a una dozzina di immagini che l'utente non vedrà per svariati secondi.

Eccezione Critica: Il Candidato LCP

Una regressione delle performance comune: applicare loading="lazy" all'elemento Largest Contentful Paint (tipicamente l'hero image). Questo ritarda il fetch fino a quando il layout non è completo.

La ricerca di Google mostra che il lazy-loading dell'immagine LCP aggiunge 624ms all'LCP mediano. Questo non è un rischio teorico. Il 17% delle pagine mobile commette ancora questo errore secondo il 2025 Web Almanac. Se Lighthouse lo segnala, vedi come risolvere l'avviso di LCP caricato con lazy-loading.

L'immagine LCP deve essere caricata in modo eager e prioritizzata:

<!-- Hero Image: Eager e Prioritizzata -->
<img src="hero.jpg"
     alt="Collezione Estiva"
     width="1200"
     height="800"
     loading="eager"
     fetchpriority="high">

Non combinare loading="lazy" con fetchpriority="high". Si contraddicono a vicenda: lazy dice al browser di aspettare, high gli dice di sbrigarsi. Il browser ignora il suggerimento di priorità quando lazy è impostato. Per maggiori informazioni su come i browser danno priorità alle risorse, vedi la guida alla prioritizzazione delle risorse.

2. Complessità su Mobile: Viewport e Touch

I viewport mobile non sono statici. L'area visibile cambia man mano che l'utente scorre, ruota il dispositivo o fa ritrarre la barra degli URL. È qui che il lazy loading nativo ha un vero vantaggio rispetto alle soluzioni JavaScript.

  • Il Viewport: L'area rettangolare visibile della finestra del browser. Su mobile, questa è dinamica; cambia dimensioni in base all'orientamento del dispositivo (verticale vs orizzontale) e allo stato del browser chrome (ritrazione della barra degli URL).
  • The Fold: L'esatto bordo inferiore del viewport. È la soglia che separa il contenuto visibile dal contenuto fuori schermo.
  • Above the Fold: Qualsiasi contenuto visibile immediatamente al caricamento della pagina senza scorrere. Le immagini qui sono critiche e non dovrebbero mai utilizzare il lazy-loading.
  • Below the Fold: Qualsiasi contenuto posizionato verticalmente oltre il fold. Questo contenuto non è critico e dovrebbe essere differito finché l'utente non ci scorre vicino.

Il Viewport Dinamico

Sui browser mobile, l'altezza del viewport (vh) è fluida. Quando l'utente avvia uno scroll tattile, la barra degli URL e i controlli di navigazione spesso si ritraggono, cambiando le dimensioni dell'area visibile.

Le librerie JavaScript di lazy loading in genere calcolano l'altezza del viewport (window.innerHeight) una sola volta al caricamento della pagina. Quando i browser mobile ridimensionano dinamicamente l'area visibile nascondendo la barra degli URL durante uno scroll, i metodi JavaScript continuano a utilizzare il vecchio valore di altezza più piccolo. Le immagini rimangono scaricate anche quando entrano nel viewport espanso, causando dei placeholder vuoti per i visitatori.

Il motore di layout interno del browser traccia automaticamente il visual viewport, quindi i trigger del lazy loading nativo si attivano indipendentemente dalle modifiche alle dimensioni del viewport. Questa è una delle ragioni per preferire il lazy loading nativo rispetto a qualsiasi alternativa JavaScript.

3. Decodifica delle Immagini su Mobile e Throttling della CPU

I dispositivi mobile hanno CPU limitata e la decodifica delle immagini su mobile può essere relativamente lenta e costosa. Convertire una JPEG in una bitmap richiede molti cicli della CPU. Su un processore mobile, la decodifica di una sequenza di immagini più grandi può bloccare il main thread dai 50ms ai 100ms ciascuna, causando latenza di input.

La Soluzione: content-visibility

La proprietà CSS content-visibility: auto agisce come un lazy rendering. Istruisce il browser a bypassare interamente le fasi di layout e painting per gli elementi fuori schermo. L'elemento esiste nel DOM, ma non esiste nel Render Tree finché non si avvicina al viewport.

Poiché questa ottimizzazione funziona saltando il rendering del sotto-albero di un elemento, non puoi applicarla direttamente a un tag <img> (che non ha sotto-alberi). Applica content-visibility al contenitore del prodotto o alla scheda dell'immagine che ospita le immagini e il suo contenuto:

@media (max-width: 768px) {
    .image-card, .product-card {
        /* Salta il rendering del contenitore e dei suoi figli */
        content-visibility: auto;

        /* Essenziale: Impedisce al contenitore di collassare a 0px di altezza */
        contain-intrinsic-size: auto 300px;
    }
}

Questo assicura che anche se un'immagine viene scaricata, il browser non paga il costo di layout/paint finché l'utente non vi scorre effettivamente sopra.

content-visibility ha raggiunto lo stato Baseline a settembre 2024 quando Safari 18 ne ha introdotto il supporto. Ora funziona nel 93% dei browser a livello globale. I benchmark di Google mostrano un miglioramento delle performance di rendering di 7x al caricamento iniziale per pagine con molte sezioni fuori schermo.

Se vuoi verificare il miglioramento del rendering su dispositivi reali, il Real User Monitoring ti mostrerà l'impatto reale sull'INP e sull'LCP in tutto il tuo traffico mobile. Nei siti monitorati da CoreDash, le pagine che utilizzano content-visibility: auto sulle griglie dei prodotti mostrano un INP migliore di circa il 15% su mobile rispetto alle pagine senza.

4. Metodologie Legacy: Perché evitarle

Prima che loading="lazy" avesse il supporto dei browser, JavaScript era l'unica opzione. Con il lazy loading nativo al 95% di supporto globale, questi metodi JavaScript sono debito tecnico. Rimuovili.

L'Era dello Scroll Handler (dal 2010 al 2016)

Le prime implementazioni collegavano event listener all'evento scroll.

// Obsoleto: non usare
window.addEventListener('scroll', () => {
    images.forEach(img => {
        if (img.getBoundingClientRect().top < window.innerHeight) {
            img.src = img.dataset.src;
        }
    });
});

Blocco del Main Thread: L'evento scroll si attiva dozzine di volte al secondo. L'esecuzione della logica e il calcolo del layout (getBoundingClientRect) durante lo scroll attivo causano cadute di frame (jank).

Layout Thrashing: L'interrogazione delle proprietà geometriche costringe il browser a ricalcolare sincronicamente il layout, un'operazione computazionalmente costosa sulle CPU mobile.

L'Era di IntersectionObserver (dal 2016 al 2019)

L'API IntersectionObserver ha migliorato le performance osservando in modo asincrono i cambiamenti nella visibilità degli elementi.

// Legacy: preferisci loading="lazy" nativo dove possibile
const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const img = entry.target;
            img.src = img.dataset.src;
            observer.unobserve(img);
        }
    });
});

Dipendenza dagli Script: Richiede l'esecuzione di JavaScript. Se il main thread è occupato a idratare un framework (React/Vue), le immagini rimangono scaricate anche se si trovano nel viewport.

Mancanza di Consapevolezza della Rete: A differenza del caricamento nativo, IntersectionObserver utilizza margini fissi (es., rootMargin: '200px'). Non espande automaticamente il suo buffer su reti lente, portando a flash vuoti per gli utenti con connessioni scadenti.

Per una panoramica completa delle tecniche di ottimizzazione delle immagini oltre il lazy loading, o per imparare di più sul differimento delle immagini di sfondo CSS (che loading="lazy" non copre), vedi quelle guide dedicate.

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

The RUM tool I built for my own clients.

CoreDash is what I use to audit enterprise platforms. Under 1KB tracking script, EU hosted, no consent banner. AI with MCP support built in. The same tool, available to everyone.

Create Free Account
Differire le Immagini Fuori Schermo su Mobile: Guida al Lazy Loading NativoCore Web Vitals Differire le Immagini Fuori Schermo su Mobile: Guida al Lazy Loading Nativo