Il tuo sito Next.js carica in 6 secondi su mobile e le immagini pesano più del testo. I visitatori se ne vanno prima ancora di vedere cosa vendi. Questo è il problema concreto che affrontiamo oggi: l'ottimizzazione di immagini e font in Next.js non è un dettaglio estetico, è una leva diretta sulle conversioni. Ogni secondo di ritardo nel caricamento può costarti fino al 7% di vendite perse. Noi, di Meteora Web, lo vediamo ogni giorno nei progetti che ci arrivano: siti bellissimi ma lenti, con immagini da 2 MB e font che bloccano il rendering. In questa guida ti mostriamo come risolvere, partendo dal perché prima del come.
Perché le immagini e i font sono i primi nemici dei tuoi Core Web Vitals?
I Core Web Vitals di Google misurano tre cose: LCP (Largest Contentful Paint), ovvero quanto tempo impiega l'elemento più grande della pagina a comparire; CLS (Cumulative Layout Shift), quanto la pagina "balla" mentre carica; e INP (Interaction to Next Paint), quanto è reattiva ai click. Le immagini impattano direttamente su LCP e CLS. I font, se caricati male, bloccano il rendering del testo e peggiorano LCP e INP. Un cliente e-commerce aveva immagini da diversi MB: ottimizzandole abbiamo ridotto il peso del 60% senza perdita di qualità. Il risultato? Un LCP passato da 4.5 secondi a 1.8 secondi e un aumento delle conversioni del 12%. Il punto è che la velocità non è un lusso, è un requisito.
Sponsored Protocol
Come usa Next.js il componente Image per ottimizzare le immagini?
Il componente next/image non è un semplice tag <img>. È un sistema completo che include lazy loading automatico, formati moderni come WebP e AVIF, e il dimensionamento responsivo. Ma la vera forza è il layout shift prevention: se dichiari width e height, Next.js riserva lo spazio necessario e il CLS resta a zero. Ecco un esempio pratico:
import Image from 'next/image';
export default function ProductCard({ product }) {
return (
<div className="card">
<Image
src={product.image}
alt={product.name}
width={600}
height={400}
sizes="(max-width: 768px) 100vw, 50vw"
priority={false}
className="rounded-lg"
/>
</div>
);
}
Il prop sizes dice al browser quanto spazio occuperà l'immagine in base al viewport. Senza questo, Next.js scarica immagini troppo grandi per schermi piccoli. Usa priority solo per l'immagine LCP (di solito quella sopra la piega), altrimenti il lazy loading di default è la scelta giusta.
Quali formati scegliere per le immagini in Next.js?
Next.js converte automaticamente le immagini in WebP o AVIF se il browser li supporta. Noi consigliamo di partire sempre da formati leggeri come WebP e di usare AVIF per le immagini fotografiche dove la qualità è prioritaria. Se hai immagini PNG con trasparenza, WebP le gestisce benissimo. Il consiglio operativo: non caricare mai un JPEG da 2 MB. Prima di importarlo, comprimilo con strumenti come Squoosh o ImageOptim. Un'immagine ottimizzata pesa tra 50 e 150 KB, non di più.
Sponsored Protocol
Come configurare next.config.js per un'ottimizzazione spinta?
La configurazione di default di Next.js è buona, ma puoi spingerti oltre. Il file next.config.js ti permette di impostare deviceSizes e imageSizes per generare esattamente le dimensioni che ti servono. Ecco la nostra configurazione base:
// next.config.js
module.exports = {
images: {
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
formats: ['image/avif', 'image/webp'],
minimumCacheTTL: 60 * 60 * 24 * 30, // 30 giorni
},
};
Il minimumCacheTTL è fondamentale: dice a Next.js di tenere in cache le immagini ottimizzate per 30 giorni. Questo riduce il carico sul server e velocizza le visite successive. Se le immagini cambiano spesso, abbassa il TTL; se sono statiche, alzalo. Noi usiamo questa configurazione per quasi tutti i clienti e funziona.
Come ottimizzare i font in Next.js senza bloccare il rendering?
I font sono un problema silenzioso. Se carichi un font con @font-face tradizionale, il browser blocca il rendering del testo finché non lo scarica. Questo peggiora LCP e INP. Next.js risolve con il sistema next/font, che carica i font in modo automatico con font-display: swap e li serve dallo stesso dominio, eliminando richieste extra. Ecco come si usa:
Sponsored Protocol
import { Inter, Roboto_Mono } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
variable: '--font-inter',
});
const robotoMono = Roboto_Mono({
subsets: ['latin'],
variable: '--font-roboto-mono',
});
export default function RootLayout({ children }) {
return (
<html lang="it" className={`${inter.variable} ${robotoMono.variable}`}>
<body>{children}</body>
</html>
);
}
Con next/font non devi preoccuparti di preload o di display: swap: Next.js lo fa per te. Inoltre, i font vengono self-hosted automaticamente, il che migliora la privacy e la velocità perché non ci sono richieste a Google Fonts. Se hai un font custom, puoi usare localFont per caricarlo dal tuo server.
Come evitare il layout shift con i font?
Il CLS causato dai font si verifica quando il testo cambia dimensione dopo il caricamento. Con next/font, Next.js genera un @font-face con size-adjust automatico, che riduce al minimo il salto. Ma c'è un trucco in più: dichiara sempre font-family con un fallback simile, come system-ui o Arial. In questo modo, se il font tarda, il testo appare con il fallback e il layout non salta. Noi testiamo sempre con Lighthouse e PageSpeed Insights: se il CLS è sopra 0.1, c'è un problema.
Sponsored Protocol
Come misurare i Core Web Vitals dopo l'ottimizzazione?
Ottimizzare senza misurare è come guidare al buio. Usa PageSpeed Insights per una visione sintetica e Lighthouse in DevTools per il debug locale. Ma il dato più importante viene da Google Search Console, nella sezione "Esperienza" → "Core Web Vitals". Lì vedi i dati reali degli utenti, non le simulazioni. Per un monitoraggio continuo, noi usiamo @next/bundle-analyzer per capire cosa pesa nel bundle e web-vitals per tracciare le metriche in produzione. Ecco un esempio di report:
// app/layout.jsx
import { reportWebVitals } from 'next/web-vitals';
export function reportWebVitals(metric) {
if (metric.label === 'web-vital') {
console.log(metric.name, metric.value);
}
}
Questo codice ti mostra in console i valori di LCP, CLS e INP. Se LCP è sotto 2.5 secondi, CLS sotto 0.1 e INP sotto 200ms, sei sulla strada giusta. Se non lo sono, torna indietro e controlla le immagini e i font.
Quali errori comuni evitare nell'ottimizzazione di immagini e font?
Il primo errore è non usare next/image e usare tag <img> classici. Perdi tutte le ottimizzazioni automatiche. Il secondo è caricare immagini decorative con priority: questo forza il caricamento immediato e rallenta la pagina. Il terzo è usare troppi font o pesi: ogni font aggiuntivo è una richiesta in più. Noi consigliamo massimo due famiglie di font con due pesi ciascuna. Il quarto errore è ignorare il caching: senza minimumCacheTTL, il server rigenera le immagini a ogni richiesta. Infine, non testare su mobile reale: le simulazioni desktop non mostrano i problemi di rete mobile. Usa sempre il throttling di Lighthouse per simulare una connessione 4G.
Sponsored Protocol
Cosa fare adesso
Non serve rifare tutto il sito. Ecco le tre azioni immediate che puoi fare oggi:
1. Sostituisci tutti i tag <img> con next/image e dichiara width e height. È il cambio più impattante sul CLS.
2. Migra i font a next/font e rimuovi il <link> a Google Fonts. Guadagnerai in velocità e privacy.
3. Esegui PageSpeed Insights prima e dopo e confronta i numeri. Se LCP scende sotto 2.5 secondi, hai fatto centro.
Se vuoi approfondire come costruire un sito Next.js completo che performa davvero, parti dalla nostra guida pillar su Next.js App Router. E se gestisci annunci immobiliari, dai un'occhiata a come ottimizzare le schede per vendere di più. Noi, di Meteora Web, ragioniamo sempre in termini di ritorno: un sito veloce non è un costo, è un investimento che paga.