performance

Next.js Image Optimization: WebP, AVIF und moderne Formate meistern

Kompletter Guide zur Next.js Image-Komponente: Automatische Optimierung, moderne Formate (WebP/AVIF), Lazy Loading und Best Practices für perfekte Performance.

Onur Cirakoglu
9 min read
#Next.js#Image Optimization#WebP#AVIF#Performance
Bildoptimierung und moderne Bildformate Illustration

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:

  1. AVIF für Chrome 85+, Firefox 93+
  2. WebP für ältere Browser
  3. 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:

Image Optimization:

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

Performance-Audit anfragen

Weiterführende Guides

Aktualisiert: Juni 2024

#Next.js#Image Optimization#WebP#AVIF#Performance