Ottimizzare Immagini per il Web: Guida Pratica
Ottimizzare immagini per il web: WebP, AVIF, lazy loading, srcset. Guida pratica per ridurre il peso delle immagini e migliorare le performance del sito.
Perché Ottimizzare le Immagini
Le immagini sono spesso il 50-80% del peso totale di una pagina web. Ottimizzarle correttamente può dimezzare i tempi di caricamento, migliorare i Core Web Vitals (specialmente LCP), aumentare il ranking SEO e ridurre significativamente i costi di bandwidth. Questa guida copre tecniche, formati e strumenti per l'ottimizzazione professionale delle immagini.
Formati Immagine Moderni
Confronto Formati
| Formato | Uso Ideale | Compressione | Trasparenza | Supporto Browser |
|---|---|---|---|---|
| JPEG | Foto | Lossy | No | 100% |
| PNG | Grafica, screenshot | Lossless | Sì | 100% |
| WebP | Tutto | Entrambi | Sì | 97%+ |
| AVIF | Foto, grafica | Lossy | Sì | 92%+ |
| SVG | Icone, loghi, grafici | N/A | Sì | 100% |
Quando Usare Cosa
- Foto e immagini complesse: AVIF con fallback WebP e JPEG
- Screenshot e grafica: WebP o PNG-8 se pochi colori
- Icone e loghi: SVG sempre (scalabile, modificabile via CSS)
- Animazioni semplici: WebP animato o Lottie
- Animazioni complesse: Video MP4/WebM (più efficiente di GIF)
Risparmio Dimensioni
# Comparazione stesso file 1920x1080
JPEG (quality 80): 120 KB
WebP (quality 80): 85 KB (-30%)
AVIF (quality 50): 50 KB (-58%)
# Per icone e loghi
PNG: 15 KB
SVG: 2 KB (scalabile infinitamente)
Riduzione Dimensioni
Regola Base
Non servire mai immagini più grandi del loro display size. Un'immagine 4000px per un container 800px spreca bandwidth e rallenta il rendering.
# Dimensioni tipiche per breakpoint
Mobile: 640px (max-width)
Tablet: 1024px
Desktop: 1920px
Retina: 2x il display size
# Esempio: immagine full-width
Mobile 1x: 640px
Mobile 2x: 1280px (retina)
Desktop 1x: 1920px
Desktop 2x: 3840px (4K)
Responsive Images
<!-- srcset per densità pixel -->
<img
src="hero.jpg"
srcset="hero.jpg 1x, hero@2x.jpg 2x"
alt="Hero image"
>
<!-- srcset per viewport width -->
<img
srcset="
hero-640.webp 640w,
hero-1024.webp 1024w,
hero-1920.webp 1920w
"
sizes="(max-width: 640px) 100vw, 50vw"
src="hero-1024.webp"
alt="Hero image"
>
<!-- Picture element per formati multipli -->
<picture>
<source type="image/avif" srcset="hero.avif">
<source type="image/webp" srcset="hero.webp">
<img src="hero.jpg" alt="Hero image">
</picture>
Compressione
Livelli di Qualità
# Qualità raccomandata per formato
JPEG: 70-85% (80% sweet spot)
WebP: 75-85%
AVIF: 50-70% (comprime molto meglio)
# Strumenti CLI
# ImageMagick
convert input.jpg -quality 80 output.jpg
# cwebp (Google WebP)
cwebp -q 80 input.png -o output.webp
# avifenc (AVIF)
avifenc --min 30 --max 50 input.png output.avif
# Sharp (Node.js)
sharp('input.jpg')
.resize(800)
.webp({ quality: 80 })
.toFile('output.webp');
# Squoosh CLI (Google)
npx @squoosh/cli --webp '{quality: 80}' input.jpg
Compressione Lossless
# Per PNG (mantiene qualità esatta)
optipng -o7 image.png
pngquant --quality=65-80 image.png
# Per SVG
svgo input.svg -o output.svg
# SVGO rimuove metadati, commenti, spazi inutili
# Può ridurre SVG del 50-80%
Lazy Loading
Nativo (Raccomandato)
<!-- loading="lazy" per immagini sotto la fold -->
<img src="below-fold.webp" loading="lazy" alt="...">
<!-- NON usare lazy su immagini above the fold -->
<img src="hero.webp" alt="Hero" fetchpriority="high">
<!-- Con dimensioni esplicite (importante per CLS!) -->
<img
src="photo.webp"
loading="lazy"
width="800"
height="600"
alt="Description"
>
Con Blur Placeholder
<!-- CSS per transizione smooth -->
<style>
.lazy-image {
background-size: cover;
background-image: url('placeholder-blur-tiny.webp');
transition: opacity 0.3s;
}
.lazy-image.loaded {
background: none;
}
</style>
<img
src="placeholder-blur.webp"
data-src="full-image.webp"
class="lazy-image"
loading="lazy"
>
<script>
// Intersection Observer per caricamento
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.add('loaded');
observer.unobserve(img);
}
});
}, { rootMargin: '50px' });
document.querySelectorAll('.lazy-image').forEach(img => {
observer.observe(img);
});
</script>
Next.js Image Component
import Image from 'next/image';
// Ottimizzazione automatica
<Image
src="/hero.jpg"
width={1200}
height={600}
alt="Hero"
priority // Per immagini above the fold
quality={80} // Qualità compressione
placeholder="blur" // Blur placeholder
blurDataURL={blurUrl}
/>
// Immagine responsive che riempie il container
<div style={{ position: 'relative', width: '100%', height: '400px' }}>
<Image
src="/photo.jpg"
fill
sizes="(max-width: 768px) 100vw, 50vw"
style={{ objectFit: 'cover' }}
alt="Photo"
/>
</div>
// next.config.js
module.exports = {
images: {
formats: ['image/avif', 'image/webp'],
deviceSizes: [640, 750, 1080, 1200, 1920, 2048],
imageSizes: [16, 32, 48, 64, 96, 128, 256],
minimumCacheTTL: 60,
}
};
CDN e Image Services
Cloudinary
// Trasformazioni on-the-fly via URL
https://res.cloudinary.com/demo/image/upload/
w_800, // Larghezza
h_600, // Altezza
c_fill, // Crop mode (fill, fit, crop)
g_face, // Gravity (center su facce)
q_auto, // Qualità automatica
f_auto // Formato automatico (WebP/AVIF se supportato)
/sample.jpg
// Esempio completo
https://res.cloudinary.com/mycloud/image/upload/w_800,h_600,c_fill,q_auto,f_auto/v1234567890/hero.jpg
Imgix
https://example.imgix.net/image.jpg?
w=800& // Larghezza
h=600& // Altezza
fit=crop& // Modalità
auto=format,compress // Formato e compressione auto
Strumenti di Ottimizzazione
Online
- Squoosh: Compressione visuale di Google, confronto side-by-side
- TinyPNG: Compressione lossy per PNG/JPEG
- SVGOMG: Ottimizzazione SVG con preview
Build Pipeline
// package.json
{
"scripts": {
"optimize-images": "npx @squoosh/cli --webp '{quality:80}' --avif '{quality:50}' images/*",
"build": "npm run optimize-images && next build"
}
}
// vite.config.js con plugin
import imagePresets from 'vite-plugin-image-presets';
export default {
plugins: [
imagePresets({
thumbnail: {
width: 200,
formats: ['webp', 'avif']
},
full: {
width: 1920,
formats: ['webp', 'avif', 'original']
}
})
]
};
Checklist Ottimizzazione
- Usa WebP/AVIF con fallback JPEG/PNG
- Implementa srcset per viewport diversi
- Aggiungi loading="lazy" sotto la fold
- Specifica sempre width e height (evita CLS)
- Usa fetchpriority="high" per LCP image
- Comprimi a qualità 70-85%
- Non servire immagini più grandi del necessario
- Considera CDN con ottimizzazione automatica
Testing e Validazione
Usa Lighthouse in Chrome DevTools per analizzare le performance delle immagini. Verifica che tutte le immagini above-the-fold abbiano dimensioni appropriate e siano caricate con priorità. Controlla che loading lazy sia applicato solo alle immagini below-the-fold. PageSpeed Insights mostra quali immagini potrebbero beneficiare di formati più efficienti. WebPageTest permette di testare su connessioni lente per simulare l'esperienza di utenti mobili con 3G. Monitora il LCP nelle metriche di produzione per identificare immagini problematiche che rallentano il rendering della pagina.
Strumenti Correlati
Per lavorare con immagini web:
- Base64 Encoder - Inline piccole immagini
- Color Converter - Colori per placeholder
- JSON Formatter - Config CDN
Conclusione
L'ottimizzazione immagini è fondamentale per:
- Performance: LCP nei Core Web Vitals
- SEO: Velocità è fattore di ranking
- UX: Utenti mobili con connessioni lente
- Costi: Meno bandwidth = meno costi hosting
Automatizza l'ottimizzazione nel build process per risultati consistenti. Integra strumenti come sharp in Node.js o Pillow in Python per processare immagini durante il deployment. Per siti statici, genera tutte le varianti al build time invece che on-demand. Monitora regolarmente le dimensioni delle immagini e imposta budget di performance nel CI/CD.
Per altri strumenti utili, esplora i nostri tool online gratuiti. Per approfondimenti, consulta web.dev Image Optimization.