Images machen durchschnittlich 50% des Page Weights aus. Die next/image Komponente automatisiert Optimierung, aber nur wenn richtig konfiguriert. In diesem Guide zeigen wir alle Features und Best Practices.
Die next/image Komponente verstehen
Basis-Nutzung
import Image from 'next/image'
export default function Hero() {
return (
<Image
src="/hero.jpg"
alt="Hero Image"
width={1920}
height={1080}
priority // Kritisch für LCP
/>
)
}
Was passiert automatisch:
- ✅ Conversion zu WebP/AVIF
- ✅ Responsive Image Sizes
- ✅ Lazy Loading (außer mit
priority
) - ✅ Blur Placeholder
- ✅ Auto-Optimization der Quality
Moderne Bildformate: AVIF vs WebP vs JPEG
Format-Vergleich
| Format | Kompression | Browser Support | Use Case | |--------|-------------|-----------------|----------| | JPEG | Baseline | 100% | Fallback | | WebP | 25-35% besser | 97% | Standard | | AVIF | 50% besser | 89% | Premium |
Format-Konfiguration
// next.config.js
module.exports = {
images: {
formats: ['image/avif', 'image/webp'],
// Reihenfolge wichtig: AVIF zuerst, WebP fallback
},
}
Next.js sendet automatisch:
- AVIF für Chrome 85+, Firefox 93+
- WebP für ältere Browser
- JPEG als universal fallback
Größenvergleich real
Original JPEG: 2.4 MB (4000×3000 px)
Nach Next.js Optimization:
- AVIF: 145 KB (-94%)
- WebP: 215 KB (-91%)
- JPEG (optimiert): 380 KB (-84%)
Einsparung: Bis zu 94% weniger Daten!
Responsive Images richtig machen
sizes Property verstehen
<Image
src="/product.jpg"
width={1200}
height={800}
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
// Mobile: volle Breite ↑
// Tablet: halbe Breite ↑
// Desktop: 1/3 Breite ↑
/>
Generiertes srcset:
<img
srcset="
/_next/image?url=%2Fproduct.jpg&w=640 640w,
/_next/image?url=%2Fproduct.jpg&w=750 750w,
/_next/image?url=%2Fproduct.jpg&w=828 828w,
/_next/image?url=%2Fproduct.jpg&w=1080 1080w,
/_next/image?url=%2Fproduct.jpg&w=1200 1200w
"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
Device Sizes konfigurieren
// next.config.js
module.exports = {
images: {
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
}
deviceSizes: Für responsive images (mit sizes
)
imageSizes: Für fixed images (ohne sizes
)
Priority und Lazy Loading
Above-the-Fold Images
export default function HomePage() {
return (
<div>
{/* Hero Image - sichtbar ohne Scroll */}
<Image
src="/hero.jpg"
width={1920}
height={1080}
priority // ⚡ Sofort laden!
fetchPriority="high"
/>
{/* Weitere Images - lazy loading */}
<Image
src="/feature1.jpg"
width={800}
height={600}
// loading="lazy" ist default
/>
<Image
src="/feature2.jpg"
width={800}
height={600}
/>
</div>
)
}
Regel: Max 1-2 Images mit priority
pro Page (LCP-relevant).
Intersection Observer Lazy Loading
Next.js nutzt moderne Intersection Observer API:
// Automatisches Lazy Loading
<Image
src="/below-fold.jpg"
width={800}
height={600}
loading="lazy" // Default - kann weggelassen werden
// Lädt wenn Image 200px vor Viewport ist
/>
Placeholder-Strategien
1. Blur Placeholder (empfohlen)
import Image from 'next/image'
import heroImage from '@/public/hero.jpg'
export default function Hero() {
return (
<Image
src={heroImage}
alt="Hero"
placeholder="blur"
// blurDataURL wird automatisch generiert für lokale Images
/>
)
}
2. Custom Blur Data URL
Für remote Images:
<Image
src="https://example.com/image.jpg"
width={800}
height={600}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRg..." // 10×7 Pixel reichen
/>
Blur Data URL generieren:
# Mit Sharp
const sharp = require('sharp')
sharp('hero.jpg')
.resize(10, 10)
.blur()
.toBuffer()
.then(buffer => {
console.log(`data:image/jpeg;base64,${buffer.toString('base64')}`)
})
3. Empty Placeholder
<Image
src="/image.jpg"
width={800}
height={600}
placeholder="empty"
// Kein Placeholder - sofort leer bis geladen
/>
fill-Mode für flexible Layouts
Responsive Container
<div className="relative w-full h-96">
<Image
src="/background.jpg"
alt="Background"
fill
style={{ objectFit: 'cover' }}
sizes="100vw"
/>
</div>
Use Cases für fill:
- Background Images
- Unknown Dimensions
- CSS-gesteuerte Sizes
- Aspect Ratio Containers
Aspect Ratio Container
<div className="relative aspect-video w-full">
<Image
src="/video-thumbnail.jpg"
alt="Video"
fill
style={{ objectFit: 'cover' }}
sizes="(max-width: 768px) 100vw, 50vw"
/>
</div>
Quality-Optimierung
Quality-Werte
// ❌ Zu hoch: Unnötig große Files
<Image src="/photo.jpg" width={800} height={600} quality={100} />
// ✅ Optimal: Kaum sichtbarer Unterschied
<Image src="/photo.jpg" width={800} height={600} quality={85} />
// ✅ Für Thumbnails
<Image src="/thumb.jpg" width={200} height={150} quality={75} />
Empfehlungen:
- Hero Images: quality=90
- Content Images: quality=85 (Default)
- Thumbnails: quality=75
- Background Images: quality=80
Unoptimized für besondere Fälle
// Für SVG, GIF (Animationen), bereits optimierte Images
<Image
src="/logo.svg"
width={200}
height={60}
unoptimized
/>
Custom Loader für externe CDNs
Cloudinary Integration
// imageLoader.js
export default function cloudinaryLoader({ src, width, quality }) {
const params = ['f_auto', 'c_limit', `w_${width}`, `q_${quality || 'auto'}`]
return `https://res.cloudinary.com/demo/image/upload/${params.join(',')}${src}`
}
// next.config.js
module.exports = {
images: {
loader: 'custom',
loaderFile: './imageLoader.js',
},
}
Imgix Integration
export default function imgixLoader({ src, width, quality }) {
const url = new URL(`https://example.imgix.net${src}`)
url.searchParams.set('auto', 'format,compress')
url.searchParams.set('w', width.toString())
if (quality) {
url.searchParams.set('q', quality.toString())
}
return url.href
}
Performance Best Practices
1. Dimensions immer setzen
// ❌ CLS Risk: Keine Dimensions
<Image src="/product.jpg" alt="Product" />
// ✅ CLS verhindert
<Image
src="/product.jpg"
width={800}
height={600}
alt="Product"
/>
2. Srcset für Retina Displays
<Image
src="/logo.png"
width={200}
height={60}
srcSet="/logo.png 1x, /logo@2x.png 2x"
alt="Logo"
/>
3. Remote Images erlauben
// next.config.js
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'images.unsplash.com',
port: '',
pathname: '/photo-*',
},
{
protocol: 'https',
hostname: 'cdn.headon.pro',
},
],
},
}
4. Caching konfigurieren
// next.config.js
module.exports = {
images: {
minimumCacheTTL: 60, // Sekunden
},
}
Browser cached automatisch optimierte Images für 1 Jahr.
Art Direction
Verschiedene Images für verschiedene Viewports
'use client'
import Image from 'next/image'
import { useMediaQuery } from '@/hooks/useMediaQuery'
export default function ResponsiveHero() {
const isMobile = useMediaQuery('(max-width: 768px)')
return (
<Image
src={isMobile ? '/hero-mobile.jpg' : '/hero-desktop.jpg'}
width={isMobile ? 768 : 1920}
height={isMobile ? 1024 : 1080}
alt="Hero"
priority
/>
)
}
Mit CSS (besser für SSR)
export default function ArtDirectionHero() {
return (
<>
{/* Mobile */}
<Image
src="/hero-mobile.jpg"
width={768}
height={1024}
alt="Hero"
className="md:hidden"
priority
/>
{/* Desktop */}
<Image
src="/hero-desktop.jpg"
width={1920}
height={1080}
alt="Hero"
className="hidden md:block"
priority
/>
</>
)
}
Image Optimization Checklist
- [ ] Alle
<img>
durch<Image>
ersetzt - [ ] Width und height gesetzt (oder fill)
- [ ]
priority
für LCP-Image gesetzt - [ ]
sizes
für responsive images definiert - [ ] Quality zwischen 75-90 je nach Use Case
- [ ] Blur placeholder für große images
- [ ] Remote patterns konfiguriert
- [ ] Alt-Texte für Accessibility
- [ ] Modern formats (AVIF/WebP) enabled
- [ ] Lazy loading für below-fold images
Häufige Fehler vermeiden
1. Zu viele Priority Images
// ❌ Schlecht: Alle priority
<Image src="/img1.jpg" width={800} height={600} priority />
<Image src="/img2.jpg" width={800} height={600} priority />
<Image src="/img3.jpg" width={800} height={600} priority />
// ✅ Gut: Nur LCP-Element
<Image src="/hero.jpg" width={1920} height={1080} priority />
<Image src="/img2.jpg" width={800} height={600} />
<Image src="/img3.jpg" width={800} height={600} />
2. Sizes nicht gesetzt
// ❌ Lädt zu große Version
<Image src="/img.jpg" width={4000} height={3000} />
// ✅ Optimale Size für Viewport
<Image
src="/img.jpg"
width={4000}
height={3000}
sizes="(max-width: 768px) 100vw, 50vw"
/>
3. Unoptimized für alle Images
// ❌ Deaktiviert alle Optimierung
<Image src="/photo.jpg" width={800} height={600} unoptimized />
// ✅ Nur für spezielle Fälle (SVG, GIF)
<Image src="/logo.svg" width={200} height={60} unoptimized />
Real-World Performance
Bei unserem E-Commerce-Projekt:
Vor Image Optimization:
- Total Image Size: 8.4 MB
- LCP: 3.2s
- Requests: 47 images
Nach next/image:
- Total Image Size: 1.2 MB (-86%)
- LCP: 0.9s (-72%)
- Requests: 12 images (-74% durch lazy loading)
Business Impact: +23% Conversion Rate
Tools & Testing
Performance Testing:
- PageSpeed Insights
- WebPageTest
- Chrome DevTools Network Tab
Image Optimization:
- Squoosh - Browser-based
- TinyPNG - Bulk optimization
- ImageOptim - Mac app
Format Conversion:
- Convertio - JPEG → WebP/AVIF
- Sharp (Node.js) - Automated conversion
Zusammenfassung
Next.js Image Optimization ist leistungsstark aber konfigurierbar:
✅ Moderne Formate (AVIF/WebP) automatisch ✅ Responsive Images mit sizes ✅ Lazy Loading out of the box ✅ Priority für kritische images ✅ Blur Placeholder für bessere UX ✅ Custom Loader für CDNs
Resultat: 80-95% kleinere Images, bessere Core Web Vitals.
Weitere Optimierungen nötig?
Als Performance-Experten optimieren wir:
- 🖼️ Image-Pipeline-Setup
- ⚡ CDN-Integration (Cloudinary, Imgix)
- 📊 Performance-Monitoring
- 🎯 Core Web Vitals Tuning
Weiterführende Guides
Aktualisiert: Juni 2024