Limitiertes Angebot: Jetzt digitalen Vorteil sichern– Nur noch 3 Plätze frei

Zurück zum Blog
Web Development

Website Performance 2025: Core Web Vitals Optimierung für Top Rankings

Langsame Websites verlieren Kunden. Diese Performance-Strategien verbessern Core Web Vitals, steigern Rankings und reduzieren Bounce Rate um bis zu 45%.

Raphael Lugmayr
13. Oktober 2025
12 min Lesezeit

Website Performance 2025: Core Web Vitals Optimierung für Top Rankings

Your website takes 4 seconds to load? 53% of mobile users are already gone.

And that's not even the worst part. Google sees your slow site and thinks: "This sucks. Let's rank it lower." So you're losing traffic AND conversions at the same time.

But here's the good news: Most performance issues are easy to fix. You just need to know what actually matters. Let me show you.

Warum Website Performance 2025 kritisch ist#

Die brutalen Fakten

Loading Time Impact:

  • 1 second delay = 7% fewer conversions
  • 3 seconds load time = 53% bounce rate
  • 5 seconds load time = 90% bounce rate

Google Rankings:

  • Core Web Vitals sind ein direkter Ranking-Faktor
  • Slow sites get punished hard
  • Mobile performance zählt am meisten

Business Impact:

Beispiel: E-Commerce Shop mit 10.000 Besuchern/Tag
- Aktuell: 3s Load Time, 2% Conversion = 200 Sales
- Optimiert: 1.5s Load Time, 3% Conversion = 300 Sales

Ergebnis: 50% mehr Umsatz. Same traffic.

Yeah. Performance is money.

Die 3 Core Web Vitals (CWV)#

Google misst Performance mit 3 Metriken. Diese entscheiden über dein Ranking.

1. LCP - Largest Contentful Paint

Was es ist: Wie lange bis der Hauptinhalt geladen ist.

Target: < 2.5 Sekunden

Was zählt als LCP:

  • Hero Image
  • Headline Text
  • Video Element
  • Großer Text-Block

Typische Probleme:

  • ❌ Riesige Hero-Images (5MB)
  • ❌ Unoptimierte Fonts
  • ❌ Server Response Time > 600ms
  • ❌ Render-blocking JavaScript

Wie du es fixst:

1. Image Optimization:

// Next.js Image Component (automatic optimization) import Image from 'next/image' export default function Hero() { return ( <Image src="/hero.jpg" width={1920} height={1080} priority // Loads immediately! quality={85} // Good balance alt="Hero Image" placeholder="blur" // Shows blur while loading blurDataURL="data:image/jpeg;base64,..." // Tiny preview /> ) }

2. Font Optimization:

// app/layout.tsx import { Inter } from 'next/font/google' const inter = Inter({ subsets: ['latin'], display: 'swap', // Show fallback immediately preload: true }) export default function RootLayout({ children }) { return ( <html className={inter.className}> <body>{children}</body> </html> ) }

3. Server Response Time:

// Use Static Generation where possible export async function generateStaticParams() { return [ { slug: 'post-1' }, { slug: 'post-2' }, ] } // Or Incremental Static Regeneration export const revalidate = 3600 // Revalidate every hour

2. FID/INP - First Input Delay / Interaction to Next Paint

Was es ist: Wie schnell reagiert die Seite auf User-Interaktion.

Target: < 100ms (FID) oder < 200ms (INP)

Typische Probleme:

  • ❌ Massive JavaScript bundles
  • ❌ Main thread blockiert
  • ❌ Unoptimierte Event Handlers
  • ❌ Zu viele Third-Party Scripts

Wie du es fixst:

1. Code Splitting:

// Lazy load heavy components import dynamic from 'next/dynamic' const HeavyChart = dynamic(() => import('./HeavyChart'), { loading: () => <Skeleton />, ssr: false // Only load on client }) const VideoPlayer = dynamic(() => import('./VideoPlayer'), { ssr: false }) export default function Dashboard() { return ( <div> {/* Loads immediately */} <Header /> {/* Loads when needed */} <HeavyChart /> </div> ) }

2. Optimize JavaScript:

// next.config.js module.exports = { compiler: { removeConsole: true, // Remove console.logs in production }, swcMinify: true, // Fast minification }

3. Web Workers for Heavy Tasks:

// worker.ts self.addEventListener('message', (e) => { const result = heavyCalculation(e.data) self.postMessage(result) }) // component.tsx const worker = new Worker('worker.ts') worker.postMessage(data) worker.onmessage = (e) => setResult(e.data)

3. CLS - Cumulative Layout Shift

Was es ist: Wie viel springt die Seite beim Laden.

Target: < 0.1

Typische Probleme:

  • ❌ Images ohne width/height
  • ❌ Ads that push content
  • ❌ Fonts die spät laden (FOIT/FOUT)
  • ❌ Injected Content ohne Space

Wie du es fixst:

1. Image Dimensions festlegen:

// ❌ BAD: No dimensions <img src="/image.jpg" /> // ✅ GOOD: Fixed dimensions <Image src="/image.jpg" width={800} height={600} alt="Product" /> // ✅ BETTER: Aspect ratio <div className="aspect-[16/9]"> <Image src="/image.jpg" fill className="object-cover" alt="Product" /> </div>

2. Font Loading Strategy:

/* app/globals.css */ @font-face { font-family: 'Inter'; src: url('/fonts/inter.woff2') format('woff2'); font-display: swap; /* Shows fallback immediately */ font-weight: 400; }

3. Reserve Space for Dynamic Content:

// Reserve space for ads/content <div className="min-h-[250px]"> {loading ? <Skeleton /> : <Ad />} </div> // Reserve space for fonts <h1 className="font-inter text-4xl leading-tight"> {/* Height is consistent even before font loads */} </h1>

Performance Optimization: Schritt für Schritt#

Step 1: Messen

You can't improve what you don't measure.

Tools:

1. PageSpeed Insights

https://pagespeed.web.dev/
  • Google's official tool
  • Shows Core Web Vitals
  • Gives specific recommendations

2. Lighthouse (Chrome DevTools)

F12 → Lighthouse → Analyze
  • Detailed breakdown
  • Performance score
  • Best practices

3. WebPageTest

https://webpagetest.org/
  • Test from different locations
  • Different devices
  • Connection speeds

4. Real User Monitoring

// app/layout.tsx export function reportWebVitals(metric) { console.log(metric) // Send to analytics analytics.track('Web Vitals', { name: metric.name, value: metric.value }) }

Step 2: Images optimieren

Images are usually 50-70% of page weight. Fix this first.

Next.js Image Component:

import Image from 'next/image' // Local images <Image src="/product.jpg" width={800} height={600} alt="Product" quality={85} // 85 is sweet spot priority // For above-fold images /> // Remote images (need config) <Image src="https://example.com/image.jpg" width={800} height={600} alt="Remote" />

next.config.js für Remote Images:

module.exports = { images: { domains: ['example.com', 'cdn.example.com'], formats: ['image/avif', 'image/webp'], // Modern formats deviceSizes: [640, 750, 828, 1080, 1200, 1920], // Breakpoints }, }

Image Optimization Checklist:

  • ✅ Use Next.js Image component
  • ✅ Specify width/height
  • ✅ Use priority for above-fold images
  • ✅ Lazy load everything else (automatic)
  • ✅ Use WebP/AVIF format
  • ✅ Compress with quality 80-85%
  • ✅ Serve responsive sizes

Manual Image Optimization:

# Use Sharp for manual optimization npm install sharp # optimize-images.js const sharp = require('sharp') sharp('input.jpg') .resize(1920, 1080, { fit: 'cover' }) .webp({ quality: 85 }) .toFile('output.webp')

Step 3: JavaScript reduzieren

Less JavaScript = faster site. Simple.

Code Splitting Strategies:

1. Route-based splitting (automatic in Next.js):

// Each page is a separate bundle app/ page.tsx // Bundle 1 about/page.tsx // Bundle 2 blog/page.tsx // Bundle 3

2. Component-based splitting:

// Heavy components loaded on demand const Modal = dynamic(() => import('./Modal')) const Chat = dynamic(() => import('./ChatWidget')) const VideoPlayer = dynamic(() => import('./VideoPlayer')) export default function Page() { const [showModal, setShowModal] = useState(false) return ( <> <Button onClick={() => setShowModal(true)}>Open</Button> {showModal && <Modal />} {/* Only loads when needed */} </> ) }

3. Library imports:

// ❌ BAD: Import entire library import _ from 'lodash' // 70KB // ✅ GOOD: Import only what you need import debounce from 'lodash/debounce' // 2KB

Bundle Analysis:

# Install bundle analyzer npm install @next/bundle-analyzer # next.config.js const withBundleAnalyzer = require('@next/bundle-analyzer')({ enabled: process.env.ANALYZE === 'true', }) module.exports = withBundleAnalyzer({ // your config }) # Run analysis ANALYZE=true npm run build

Step 4: Server Performance

Your server speed affects everything.

Server Response Time Target: < 600ms

Optimization Strategies:

1. Static Site Generation (SSG):

// Fastest possible - pre-rendered at build time export default function Page({ posts }) { return <PostList posts={posts} /> } export async function generateStaticParams() { const posts = await getPosts() return posts.map(post => ({ slug: post.slug })) }

2. Incremental Static Regeneration (ISR):

// Revalidate every hour export const revalidate = 3600 export default async function Page() { const data = await fetchData() return <Content data={data} /> }

3. Edge Functions:

// Run at edge locations (faster) export const runtime = 'edge' export async function GET() { return Response.json({ hello: 'world' }) }

4. Database Optimization:

// Connection pooling import { Pool } from 'pg' const pool = new Pool({ max: 20, // Max connections idleTimeoutMillis: 30000, connectionTimeoutMillis: 2000, }) // Indexing CREATE INDEX idx_user_email ON users(email); CREATE INDEX idx_post_slug ON posts(slug);

Step 5: Caching Strategies

Don't recalculate what hasn't changed.

Browser Caching:

// next.config.js module.exports = { async headers() { return [ { source: '/images/:path*', headers: [ { key: 'Cache-Control', value: 'public, max-age=31536000, immutable', }, ], }, ] }, }

React Cache:

import { cache } from 'react' // Cache function results const getUser = cache(async (id: string) => { return await db.user.findUnique({ where: { id } }) }) // Called multiple times, but only fetches once const user1 = await getUser('123') const user2 = await getUser('123') // Uses cached result

Redis Caching:

import { Redis } from '@upstash/redis' const redis = new Redis({ /* config */ }) async function getCachedData(key: string) { // Check cache first const cached = await redis.get(key) if (cached) return cached // Fetch fresh data const data = await fetchData() // Cache for 1 hour await redis.setex(key, 3600, data) return data }

Step 6: Third-Party Scripts optimieren

Third-party scripts are performance killers.

Common Culprits:

  • Google Analytics: ~45KB
  • Google Tag Manager: ~35KB
  • Facebook Pixel: ~50KB
  • Intercom Chat: ~200KB
  • HubSpot: ~150KB

Optimization:

1. Use Next.js Script component:

import Script from 'next/script' export default function Page() { return ( <> {/* Load after page is interactive */} <Script src="https://analytics.com/script.js" strategy="lazyOnload" // or "afterInteractive" /> {/* Inline critical scripts */} <Script id="critical-script"> {`console.log('Critical code')`} </Script> </> ) }

2. Self-host when possible:

# Download Google Fonts locally npm install @fontsource/inter # Import in app import '@fontsource/inter/400.css' import '@fontsource/inter/700.css'

3. Replace heavy tools:

❌ Google Analytics (45KB)
✅ Plausible Analytics (< 1KB)

❌ Intercom (200KB)  
✅ Crisp Chat (15KB)

❌ jQuery (30KB)
✅ Native JavaScript (0KB)

4. Lazy load non-critical scripts:

'use client' import { useEffect } from 'react' export default function Analytics() { useEffect(() => { // Load analytics after 3 seconds setTimeout(() => { const script = document.createElement('script') script.src = 'https://analytics.com/script.js' document.body.appendChild(script) }, 3000) }, []) return null }

Advanced Performance Tactics#

1. Preloading & Prefetching

Tell the browser what to load next.

Preload Critical Resources:

// app/layout.tsx export default function Layout({ children }) { return ( <html> <head> {/* Preload critical font */} <link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossOrigin="anonymous" /> {/* Preload hero image */} <link rel="preload" href="/hero.jpg" as="image" /> </head> <body>{children}</body> </html> ) }

Prefetch Next Page:

import Link from 'next/link' // Automatically prefetches on hover <Link href="/about" prefetch> About Us </Link>

2. Service Workers & PWA

Cache assets for instant loads.

// app/manifest.ts export default function manifest() { return { name: 'My App', short_name: 'App', start_url: '/', display: 'standalone', background_color: '#ffffff', theme_color: '#000000', } }

3. Compression

Make everything smaller.

Brotli Compression (automatic on Vercel):

// next.config.js module.exports = { compress: true, // Enable gzip/brotli }

Typical compression gains:

  • HTML: 60-80% smaller
  • CSS: 60-70% smaller
  • JavaScript: 50-60% smaller

4. Critical CSS

Inline critical CSS, defer the rest.

// app/layout.tsx export default function Layout({ children }) { return ( <html> <head> {/* Critical CSS inline */} <style dangerouslySetInnerHTML={{ __html: ` body { margin: 0; font-family: Inter, sans-serif; } .hero { height: 100vh; display: flex; } ` }} /> </head> <body>{children}</body> </html> ) }

Performance Monitoring#

Set up continuous monitoring.

Real User Monitoring (RUM):

// app/layout.tsx import { Analytics } from '@vercel/analytics/react' import { SpeedInsights } from '@vercel/speed-insights/next' export default function Layout({ children }) { return ( <html> <body> {children} <Analytics /> <SpeedInsights /> </body> </html> ) }

Custom Performance Tracking:

'use client' import { useReportWebVitals } from 'next/web-vitals' export function WebVitals() { useReportWebVitals((metric) => { // Send to your analytics fetch('/api/analytics', { method: 'POST', body: JSON.stringify({ name: metric.name, value: metric.value, id: metric.id, }), }) }) return null }

Performance Budget#

Set limits and stick to them.

Example Budget:

{ "budgets": [ { "path": "/*", "timings": [ { "metric": "interactive", "budget": 3000 }, { "metric": "first-contentful-paint", "budget": 1000 } ], "resourceSizes": [ { "resourceType": "script", "budget": 300 }, { "resourceType": "image", "budget": 500 } ] } ] }

Performance Checkliste#

Before launch:

Images:

  • ✅ Next.js Image component used
  • ✅ WebP/AVIF format
  • ✅ Proper dimensions set
  • ✅ Lazy loading (except hero)
  • ✅ Compressed (quality 85%)

JavaScript:

  • ✅ Code splitting implemented
  • ✅ Heavy components lazy loaded
  • ✅ Bundle analyzed
  • ✅ Unused code removed
  • ✅ Third-party scripts deferred

Fonts:

  • ✅ Self-hosted
  • ✅ Preloaded
  • ✅ font-display: swap
  • ✅ Only needed weights loaded

Server:

  • ✅ Static generation where possible
  • ✅ ISR configured
  • ✅ Response time < 600ms
  • ✅ Database indexed
  • ✅ Caching implemented

Monitoring:

  • ✅ Analytics installed
  • ✅ Core Web Vitals tracked
  • ✅ Performance budget set
  • ✅ Alerts configured

Fazit: Performance ist nicht optional#

Here's the deal:

Slow website = Lost money

Every 100ms improvement = 1% more conversions. Do the math for your business.

Priority:

  1. Fix Core Web Vitals first (biggest ranking impact)
  2. Optimize images (biggest quick win)
  3. Reduce JavaScript (biggest performance gain)
  4. Monitor continuously (catch regressions)

Stop making excuses. Your competitors are fast. Be faster.


Brauchen Sie Performance-Hilfe?

Wir optimieren Websites auf Core Web Vitals Score 95+. Guaranteed.

Kostenlose Performance-Analyse erhalten →

R

Raphael Lugmayr

Founder & CEO bei Stoicera. Spezialisiert auf moderne Webentwicklung mit Next.js, React und TypeScript. Passion für Clean Code und UX-optimierte Lösungen.

Brauchst du Hilfe mit deinem Projekt?

Wir helfen dir bei Webentwicklung, Design, Marketing und mehr. Kostenlose Erstberatung!