Rimanda le immagini offscreen su mobile

Rimanda le immagini offscreen su mobile

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-01-23

Deferimento delle immagini su mobile: lo standard

Le prestazioni su mobile sono spesso limitate dalla latenza di rete (RTT) e dalla disponibilità della CPU sul thread principale. Il deferimento delle immagini offscreen su mobile risolve entrambi i problemi prevenendo la competizione per la larghezza di banda nel critical rendering path e distribuendo i costi di decodifica delle immagini per l'intera durata della sessione.

Questo documento spiega come deferire efficacemente le immagini su mobile, quando usarlo e affronta i vincoli meccanici specifici dei viewport su mobile.

priority waterfall web dev example

1. Rimandare le immagini offscreen 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 offscreen (ad esempio, un logo nel footer o una slide di un carosello), il download di risorse critiche (tipicamente l'immagine LCP, script e font importanti competeranno per slot e larghezza di banda). Questo fenomeno, noto come Network Contention, degrada direttamente i Core Web Vitals.

Differendo le immagini offscreen utilizzando l'attributo nativo loading, possiamo dare priorità alle risorse importanti e ottimizzare il Critical Rendering Path. Il browser recupera solo ciò che è immediatamente visibile, riservando larghezza di banda per le risorse che influiscono strettamente sul First Contentful Paint (FCP) e sul Largest Contentful Paint (LCP). Il metodo di lazy loading nativo scarica questa logica di priorità sul meccanismo interno molto più veloce del browser, eliminando la necessità di vecchie e lente librerie JavaScript.

Implementazione

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

<!-- Standard Deferred Image -->
<img src="product-detail.jpg"
     
     alt="Side view of the chassis"
     width="800"
     height="600"
     decoding="async">

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 viene avviato il download di un'immagine) in base all'Effective Connection Type (ECT).

  • Su 4G/WiFi: Il motore Blink (Chrome/Edge) impiega una soglia prudente (ad es. 1250px). Presume una bassa latenza e recupera l'immagine solo quando l'utente è relativamente vicino al viewport.
  • Su 3G/Slow-2G: La soglia si espande (ad es. 2500px). Il browser avvia la richiesta molto prima rispetto alla posizione di scorrimento per compensare gli elevati tempi di andata e ritorno, assicurando che l'immagine sia pronta prima che l'utente scorra per visualizzarla.

Eccezione Critica: Il Candidato LCP

Una comune regressione delle prestazioni si verifica quando gli sviluppatori applicano loading="lazy" all'elemento Largest Contentful Paint (LCP) (tipicamente l'immagine hero). Questo ritarda il recupero fino al completamento del layout.

Strategia LCP Corretta: L'immagine LCP deve essere caricata in modo eager (immediato) e avere la priorità.

<!-- Hero Image: Eager and Prioritized -->
<img src="hero.jpg"
     alt="Summer Collection"
     width="1200"
     height="800"
     
     > 

2. Complessità su mobile: Viewport e Touch

I viewport mobile introducono sfide specifiche di rendering che l'implementazione nativa gestisce in modo più robusto rispetto alle soluzioni basate su script.

  • Il Viewport: L'area rettangolare visibile della finestra del browser. Su mobile, questo è dinamico; cambia le dimensioni in base all'orientamento del dispositivo (verticale vs orizzontale) e allo stato dell'interfaccia del browser (la barra dell'URL che si ritrae).
  • La Piega (The Fold): Il bordo inferiore esatto del viewport. È la soglia che separa il contenuto visibile dal contenuto off-screen.
  • Above the Fold (Sopra la Piega): Qualsiasi contenuto visibile immediatamente al caricamento della pagina senza scorrere. Le immagini qui sono spesso critiche e non dovrebbero quasi mai essere caricate in lazy-loading.
  • Below the Fold (Sotto la Piega): Qualsiasi contenuto situato verticalmente oltre la piega. Questo contenuto non è Critico e deve essere deferito finché l'utente non vi scorre vicino.

above and below the mobile fold 22 01 26

Il Viewport Dinamico

Sui browser mobile, l'altezza del viewport (vh) è fluida. Non appena l'utente avvia uno scorrimento touch, la barra dell'URL e i controlli di navigazione spesso si ritraggono, modificando le dimensioni dell'area visibile.

Le librerie basate su JavaScript per il deferimento delle immagini solitamente calcolano l'altezza del viewport (window.innerHeight) solo una volta all'inizio del caricamento della pagina.  Quando i browser mobile ridimensionano dinamicamente l'area visibile nascondendo la barra dell'URL durante uno scorrimento, i metodi JavaScript continuano ad utilizzare il vecchio valore di altezza, che è inferiore. Ciò causava il mancato caricamento delle immagini anche quando entravano fisicamente nell'area estesa del viewport, causando una scarsa UX per i visitatori.

La Gestione Nativa risolve questo problema poiché il motore di layout interno del browser traccia automaticamente il visual viewport, assicurando che gli inneschi si attivino indipendentemente da eventuali modifiche alle dimensioni del viewport.

3. Decodifica delle Immagini su Mobile e CPU Throttling

I dispositivi mobili hanno una CPU limitata e la decodifica delle immagini su mobile può essere relativamente lenta e costosa. La conversione di un JPEG in una bitmap richiede molti cicli di CPU. Su un processore mobile, la decodifica di una sequenza di immagini più grandi può bloccare il thread principale per 50ms–100ms ciascuna, causando input latency.

La Soluzione: content-visibility

Per risolvere questo problema, possiamo usare la proprietà e il valore CSS content-visibility: auto. Questa proprietà funge da standard per il "Lazy Rendering". Istruisce il browser a ignorare completamente le fasi di layout e di painting per gli elementi off-screen. 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 sottoalbero di un elemento, non puoi applicarla direttamente a un tag <img> (che non ha un sottoalbero). Dovresti applicare content-visibility al contenitore del prodotto o alla scheda dell'immagine che ospita queste immagini e al suo contenuto

 @static/cache/static/img/clients/dpgmedia.webp (max-width: 768px) {
    .image-card, .product-card {
        /* Skip rendering of the container and its children */
        content-visibility: auto;
        
        /* Essential: Prevents container from collapsing to 0px height */
        contain-intrinsic-size: auto 300px;
    }
}

Ciò garantisce che, anche se un'immagine viene scaricata, il browser non paghi il costo del layout/paint finché l'utente non scorre effettivamente verso di essa.

4. Metodologie Legacy: Perché evitarle

Prima del supporto nativo, gli sviluppatori si affidavano a JavaScript per deferire le immagini su mobile. Questi metodi sono ancora ampiamente utilizzati ma dovrebbero essere considerati come debito tecnico!

L'Era dello "Scroll Handler" (2010–2016)

Le prime implementazioni associavano event listener all'evento di scroll.

// OBSOLETE: Do not use
window.addEventListener('scroll', () => {
    images.forEach(img => {
        if (img.getBoundingClientRect().top < window.innerHeight) {
            img.src = img.dataset.src;
        }
    });
});

Blocco del Thread Principale: L'evento di scroll viene attivato dozzine di volte al secondo. L'esecuzione della logica e il calcolo del layout (getBoundingClientRect) durante lo scorrimento attivo causavano cali di frame (jank).

Layout Thrashing: L'interrogazione delle proprietà geometriche forza il browser a ricalcolare in modo sincrono lo stile di layout, un'operazione computazionalmente costosa sulle CPU mobile. 

L'Era dell'IntersectionObserver (2016–2019)

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

// DEPRECATED: Use native loading where possible
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 thread principale è occupato con l'idratazione di un framework (React/Vue), le immagini rimangono non caricate anche se sono nel viewport.

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


Your Lighthouse score is not the full picture.

Lab tests run on fast hardware with a stable connection. I analyze what your actual visitors experience on real devices and real networks.

Analyze Field Data
Rimanda le immagini offscreen su mobileCore Web Vitals Rimanda le immagini offscreen su mobile