Skip to content

Messung und Optimierung der Web-Performance

🎯 Kernfrage

Warum lädt deine Webseite langsam und Nutzer beschweren sich ständig über Ruckeln? Das ist wie die Frage: Warum dauert das Essen im Restaurant so lange und die Gäste werden ungeduldig? Dieses Kapitel führt dich in die Kernkonzepte der Frontend-Performance-Optimierung ein und lässt deine Webseite „fliegen".


1. Warum „Performance-Optimierung"?

1.1 Von funktionsfähig zu benutzerfreundlich: Die Entwicklung der Performance-Optimierung

Vor zehn Jahren waren Webseiten sehr einfach – eine Seite war vielleicht nur wenige KB groß und die Ladezeit war kaum spürbar. Damals mussten wir uns überhaupt keine Gedanken über Performance-Optimierung machen – weil das Problem noch nicht existierte.

Doch heute ist das völlig anders. Die Komplexität moderner Webseiten wächst exponentiell: Eine E-Commerce-Startseite kann Dutzende hochauflösende Bilder enthalten, eine Social-Media-Plattform lädt möglicherweise tausende Beiträge gleichzeitig, ein Admin-Dashboard kann Dutzende interaktive Komponenten enthalten. Hinter diesen „reichen" Funktionen stecken riesige Code- und Ressourcenmengen – ohne gute Optimierung wird die Benutzererfahrung katastrophal.

👴 Webseiten vor zehn Jahren

  • Eine einzelne Seite war nur wenige KB bis einige Dutzend KB groß
  • Nur Text und wenige Bilder
  • Nutzer spürten kaum Ladeverzögerungen
  • Keine Performance-Optimierung nötig

🚀 Moderne Webseiten

  • Eine einzelne Seite kann mehrere MB oder noch größer sein
  • Hochauflösende Bilder, Videos, interaktive Komponenten
  • Langsames Laden, ruckelndes Scrollen, träge Klick-Reaktionen
  • Performance-Optimierung ist zwingend erforderlich

Das ist das Problem, das „Performance-Optimierung" löst: Die Wartezeit der Nutzer verkürzen und die Bedienung flüssiger machen.

1.2 Eine wahre Geschichte aus der Praxis: Warum du Performance-Optimierung verstehen musst

Du könntest sagen: „Das Internet ist heute so schnell und die Geräte sind so gut – muss man sich da wirklich noch um Performance-Optimierung kümmern?" Lass mich eine wahre Geschichte erzählen, damit du verstehst, warum dieses Wissen so wichtig ist.

Xiaos Performance-Falle

Xiao ist ein frisch eingestellter Frontend-Entwickler, der für die E-Commerce-Startseite des Unternehmens verantwortlich ist. Er verwendete das neueste Vue 3 und die beliebteste UI-Bibliothek, die Funktionalität war perfekt umgesetzt, und auf seinem leistungsstarken Firmenrechner lief alles einwandfrei.

Doch am Tag nach dem Launch explodierte die Support-Abteilung – massenhaft Nutzer beschwerten sich: „Die Seite ist viel zu träge", „Die Bilder laden nicht", „Klicks auf Buttons reagieren ewig nicht". Xiao öffnete seine Entwicklerkonsole zum Testen – alles lief flüssig. Er verstand überhaupt nicht, wo das Problem lag.

Später bat er einen erfahrenen Kollegen um Hilfe. Der ließ ihn ein normales Notebook mit einer normalen 4G-Verbindung nutzen und seine eigene Webseite testen. Xiao war fassungslos: Die Startseite brauchte über zehn Sekunden zum Laden, beim Scrollen durch Listen ruckelte es wie eine Diashow, und Klicks auf Buttons brauchten mehrere Sekunden für eine Reaktion.

Es stellte sich heraus, dass Xiao ein Top-MacBook Pro mit Gigabit-Glasfaser nutzte, während die meisten Nutzer normale Geräte mit mobilen Daten verwendeten. Sein Code enthielt dutzende unkomprimierte hochauflösende Bilder, importierte die gesamte UI-Bibliothek, obwohl nur wenige Komponenten genutzt wurden, und führte beim Rendering viele synchrone Berechnungen durch.

Die Lösung war eigentlich nicht kompliziert: Bilder komprimieren, Komponenten bei Bedarf importieren, Berechnungen in Hintergrund-Threads auslagern, virtuelle Listen verwenden. Nach diesen Änderungen sank die Ladezeit der Startseite von über zehn Sekunden auf 2 Sekunden, das Scrollen wurde flüssig und die Nutzerbeschwerden verschwanden sofort.

Xiao verstand von da an ein Prinzip: Ohne Verständnis für Performance-Optimierung läuft dein Code auf deinem eigenen Rechner blitzschnell, aber auf den Geräten der Nutzer ist er möglicherweise völlig unbrauchbar.

💡 Kernbotschaft

Performance-Optimierung ist keine Option, sondern eine unverzichtbare Fähigkeit. Du musst aus der Perspektive der Nutzer denken – sie verwenden normale Geräte und normale Netzwerke. Wenn dein Code auf ihren Geräten nicht läuft, dann musst du optimieren.


2. Kernkonzepte: Laden, Rendern, Interaktion

🤔 Was haben diese Konzepte mit Performance zu tun?

Laden, Rendern und Interaktion sind die drei Kernbereiche beim Besuch einer Webseite – jeder Bereich kann zum Performance-Engpass werden.

Wenn ein Nutzer deine Webseite besucht, durchläuft er nacheinander:

  1. Laden → HTML/CSS/JS/Bilder vom Server in den Browser herunterladen
  2. Rendern → Die heruntergeladenen Inhalte in eine sichtbare Seite „malen"
  3. Interaktion → Auf Klicks, Scrollen und andere Aktionen des Nutzers reagieren

Performance-Optimierung bedeutet also, alle drei Bereiche zu beschleunigen. Wenn du sie verstehst, weißt du, wo der Performance-Engpass liegt und welche Methode du zur Optimierung einsetzen kannst.

Bevor wir uns mit konkreten Optimierungstechniken befassen, müssen wir diese Kernkonzepte verstehen. Um dir das zu erleichtern, verwenden wir eine Restaurant-Analogie.

2.1 Die drei Bereiche mit einer Restaurant-Analogie verstehen

Stell dir vor, du gehst in ein Restaurant essen – dieser Prozess ist dem Besuch einer Webseite erstaunlich ähnlich:

Bereich🍽️ Restaurant-AnalogieTatsächliche FunktionKonkretes Beispiel
LadenZutaten vom Lager in die Küche transportierenHTML/CSS/JS/Bilder vom Server in den Browser herunterladenNutzer öffnet die Webseite, der Browser beginnt, Ressourcen herunterzuladen
RendernDer Koch verarbeitet die Zutaten zu GerichtenDer Browser wandelt Code in eine sichtbare Seite umDer Browser parst HTML, berechnet das Layout, zeichnet die Seite
InteraktionDer Kellner reagiert auf die Wünsche der GästeDer Browser reagiert auf Klicks, Scrollen und andere AktionenNutzer klickt auf einen Button, die Seite gibt Feedback

2.2 Laden (Loading): Zutaten transportieren

Laden bezeichnet den Prozess, bei dem alle benötigten Ressourcen (HTML, CSS, JavaScript, Bilder, Schriften usw.) vom Server in den Browser heruntergeladen werden. Dieser Prozess ist wie der Transport von Zutaten vom Lager in die Küche – wenn der Transport langsam ist oder es zu viele Zutaten sind, muss die Küche warten.

Warum ist das Laden langsam? Es gibt drei Hauptgründe: Erstens, zu große Ressourcen – ein einziges unkomprimiertes hochauflösendes Bild kann 5 MB groß sein, so viel wie ein Roman. Zweitens, Netzwerklatenz – wenn der Server im Ausland steht oder der Nutzer mobile Daten verwendet, dauert jede Anfrage lange. Drittens, zu viele Anfragen – der Browser kann nur eine begrenzte Anzahl von Ressourcen gleichzeitig herunterladen, bei zu vielen Ressourcen entsteht eine Warteschlange.

🔍 Was passiert in der Ladephase?

Wenn ein Nutzer eine URL in die Adressleiste eingibt und Enter drückt, passiert folgendes nacheinander:

  1. DNS-Auflösung: Die Domain (z.B. www.example.com) in eine IP-Adresse (z.B. 192.168.1.1) umwandeln – wie die Suche nach der Restaurantadresse im Telefonbuch
  2. TCP-Verbindung: Browser und Server bauen eine Verbindung auf – wie das Wählen einer Nummer vor dem Telefonat
  3. TLS-Handshake: Eine sichere Verbindung aufbauen (HTTPS) – wie die Bestätigung der Identität des Gegenübers
  4. Ressourcen anfordern: Der Browser fordert die HTML-Datei vom Server an
  5. HTML parsen: Der Browser parst das HTML und stellt fest, dass CSS, JS, Bilder usw. benötigt werden, und fordert diese weiter an
  6. Ressourcen herunterladen: Alle benötigten Ressourcen lokal herunterladen
  7. Rendern beginnen: Nach Abschluss des Downloads mit dem Rendern der Seite beginnen

Die Schritte 1-4 werden „Time to First Byte" (TTFB) genannt, die Schritte 5-7 sind die eigentliche Ressourcen-Downloadzeit.

Gängige Ladeoptimierungen:

  • Ressourcen komprimieren: Dateien verkleinern (Gzip-, Brotli-Kompression)
  • CDN verwenden: Dateien auf Servern näher am Nutzer speichern
  • Lazy Loading: Nur den sichtbaren Inhalt laden, den Rest erst beim Scrollen nachladen
  • Code Splitting: Große Dateien in kleine aufteilen und bei Bedarf laden

2.3 Rendern (Rendering): Der Koch bereitet die Gerichte zu

Rendern bezeichnet den Prozess, bei dem der Browser das heruntergeladene HTML, CSS und JavaScript in eine für den Nutzer sichtbare Seite umwandelt. Dieser Prozess ist wie ein Koch, der Zutaten zu Gerichten verarbeitet – wenn der Prozess kompliziert ist und viele Schritte hat, dauert das Servieren länger.

📖 Was ist „Rendern"?

Du hast vielleicht schon vom Begriff „Rendern" gehört – was ist das eigentlich?

Einfach gesagt: Rendern ist der Prozess, Code in ein Bild zu verwandeln.

Der Browser muss folgende Dinge tun:

  1. HTML parsen → DOM-Baum erzeugen (die Struktur der Seite)
  2. CSS parsen → CSSOM-Baum erzeugen (die Styles der Seite)
  3. Zusammenführen → Renderbaum erzeugen (Kombination aus Struktur und Styles)
  4. Layout → Position und Größe jedes Elements berechnen
  5. Zeichnen (Paint) → Die Elemente zeichnen
  6. Zusammensetzen (Composite) → Mehrere Ebenen zum endgültigen Bild zusammenfügen

Dieser Prozess ist sehr komplex – ein Problem in einem beliebigen Schritt führt zu Ruckeln der Seite.

Warum ist das Rendern langsam? Es gibt zwei Hauptgründe: Erstens, die Seite ist zu komplex – wenn eine Seite zehntausende DOM-Knoten hat, braucht der Browser sehr lange für Layout und Zeichnen. Zweitens, häufige Änderungen an der Seite – wenn JavaScript-Code häufig das DOM verändert, muss der Browser immer wieder Layout und Zeichnen neu berechnen, was viel Performance kostet.

📁 Was passiert in der Renderphase?

Der vollständige Render-Prozess:

HTML (String)

[HTML parsen] → DOM-Baum erzeugen

DOM-Baum (Seitenstruktur)

CSS (Stylesheet)

[CSS parsen] → CSSOM-Baum erzeugen

CSSOM-Baum (Seitenstyles)

DOM-Baum + CSSOM-Baum

[Zusammenführen] → Renderbaum erzeugen

Renderbaum (zu rendernde Elemente)

[Layout] → Position und Größe jedes Elements berechnen

[Zeichnen (Paint)] → Farben füllen, Text zeichnen

[Zusammensetzen (Composite)] → Mehrere Ebenen zusammenfügen

Endgültiges Bild

Kritischer Renderpfad (Critical Rendering Path): Der Browser muss den Inhalt des ersten Bildschirms so schnell wie möglich rendern, damit der Nutzer das Gefühl hat, „die Seite ist schnell". Das nennt man „Optimierung des kritischen Renderpfads".

👇 Selbst ausprobieren: Die folgende Demo zeigt, wie der Browser eine Seite rendert. Klicke auf „Weiter", um die verschiedenen Renderphasen zu beobachten:

Frontend Performance Optimization Map
Select a dimension to explore bottlenecks and matching optimization techniques.

⚠️ Common Bottlenecks

  • Large assets
    Images and JS bundles are not compressed, so downloads take longer.
  • Too many requests
    HTTP/1.1 head-of-line blocking makes resources wait in line.
  • Network latency
    The server is physically far away, increasing RTT.
How to fix it?

🚀 Solutions

  • Asset compression
    Use Gzip/Brotli and image formats such as WebP.
    Smaller size
  • Lazy loading
    Load only resources visible in the current viewport.
    Smaller sizeFewer requests
  • CDN acceleration
    Distribute assets to nodes close to users.
    Shorter distance
  • HTTP caching
    Use browser cache to avoid repeated requests.
    Fewer requests

Core goal: Deliver resources to the browser faster by reducing size, request count, and distance.

Gängige Render-Optimierungen:

  • Reflows und Repaints reduzieren: Häufige DOM-Änderungen vermeiden, transform und opacity statt top und width verwenden
  • Virtuelle Listen: Nur den sichtbaren Bereich rendern – bei großen Datenmengen deutliche Performance-Verbesserung
  • CSS-Animationen: CSS-Animationen statt JavaScript-Animationen verwenden – bessere Performance

2.4 Interaktion (Interaction): Der Kellner reagiert

Interaktion bezeichnet den Prozess, bei dem der Browser auf Nutzeraktionen (Klicks, Scrollen, Eingaben usw.) reagiert. Dieser Prozess ist wie ein Kellner, der auf die Wünsche der Gäste reagiert – wenn der Kellner überlastet ist, müssen die Gäste warten.

Warum ruckelt die Interaktion? Der Hauptgrund ist, dass der Haupt-Thread blockiert ist. Das JavaScript des Browsers läuft in einem einzigen Thread – wenn der Code komplexe Berechnungen ausführt, kann er nicht auf Nutzeraktionen reagieren, was zu Ruckeln führt.

🤔 Was ist der „Haupt-Thread"?

Der Browser hat mehrere Threads, aber nur einer ist für die Ausführung von JavaScript, das Rendern der Seite und die Reaktion auf Nutzeraktionen zuständig – der Haupt-Thread.

Du kannst dir den Haupt-Thread wie einen vielbeschäftigten Kellner vorstellen, der viele Dinge gleichzeitig tun muss:

  • JavaScript-Code ausführen (Daten berechnen, APIs aufrufen)
  • Die Seite rendern (Layout, Zeichnen)
  • Auf Nutzeraktionen reagieren (Button-Klicks, Scrollen)

Das Problem: Er ist nur eine Person. Wenn er eine komplexe JavaScript-Berechnung ausführt (z.B. zehntausend Datensätze verarbeiten) und der Nutzer in diesem Moment auf einen Button klickt, kann er nicht sofort reagieren – er muss erst die Berechnung abschließen. Das ist die Ursache von Ruckeln.

Lösungen:

  • Komplexe Berechnungen in einen Web Worker auslagern (Hintergrund-Thread)
  • Time Slicing verwenden, große Aufgaben in kleine aufteilen
  • Synchrone komplexe Operationen vermeiden, stattdessen asynchron arbeiten

👇 Probiere es selbst aus: Die folgende Demo vergleicht synchrone Berechnung mit Web Worker. Klicke auf „Berechnung starten" und beobachte, ob die Seite ruckelt:

📊Core Web VitalsAdjust load time and observe how performance metrics change.
FCP
First Contentful Paint
0.8 s
First contentful paint
Good
LCP
Largest Contentful Paint
1.8 s
Largest contentful paint
Good
FID
First Input Delay
200 ms
First input delay
Needs improvement
CLS
Cumulative Layout Shift
0.15
Cumulative layout shift
Needs improvement
Good
Needs improvement
Poor
💡Core metrics:FCP ≤ 1.8s, LCP ≤ 2.5s, FID ≤ 100ms, and CLS ≤ 0.1. The goal is to keep every metric in the "Good" range.

Gängige Interaktionsoptimierungen:

  • Debouncing und Throttling: Die Auslösefrequenz von Events begrenzen (z.B. Scroll-Events, Eingabe-Events)
  • Web Worker: Komplexe Berechnungen in Hintergrund-Threads auslagern, den Haupt-Thread nicht blockieren
  • Time Slicing: Große Aufgaben in kleine aufteilen, dem Browser die Möglichkeit geben, auf Nutzeraktionen zu reagieren

3. Praxis: Die Performance-Optimierungsreise eines Teams

Nach all der Theorie schauen wir uns einen echten Fall an: Wie sich ein Startup von „überhaupt keine Performance-Berücksichtigung" Schritt für Schritt zu „systematischer Performance-Optimierung" entwickelt hat. Anhand dieses Beispiels verstehst du besser, welche Probleme Performance-Optimierung tatsächlich löst.

3.1 Die Übersicht der Entwicklung

Die folgende Tabelle zeigt die vier Phasen der Performance-Optimierung – du kannst sehen, wie sich Optimierungsmethoden, Werkzeuge und Metriken Schritt für Schritt weiterentwickelt haben:

PhaseOptimierungsmethodenÜberwachungswerkzeugeKernmetrikenKernveränderung
Phase 1: UrzeitKeine (nicht berücksichtigt)Keine (nach Gefühl)KeineÜberhaupt kein Performance-Bewusstsein, Hauptsache es läuft
Phase 2: Manuelle OptimierungBilder komprimieren, Anfragen reduzierenBrowser Network-PanelSeitenladezeitErste Ansätze von Bewusstsein, aber primitive Methoden
Phase 3: Systematische OptimierungCode Splitting, Lazy Loading, virtuelle ListenLighthouse, Performance-PanelFCP, LCP, TBTProfessionelle Werkzeuge, klare Optimierungsziele
Phase 4: Kontinuierliche OptimierungPerformance-Budget, CI/CD-PrüfungRUM, Lighthouse CIINP, CLS, End-to-End-MonitoringPerformance als Teil des Entwicklungsprozesses

📊 Was kannst du aus der Tabelle ablesen?

Lass uns die Tabelle Zeile für Zeile interpretieren:

Phase 1 → Phase 2: Von „kein Bewusstsein" zu „Bewusstsein". Das ist der entscheidende Schritt – Entwickler beginnen zu erkennen, dass Performance ein Problem ist, und versuchen zu optimieren. Aber die Methoden sind noch primitiv, hauptsächlich auf Gefühl und Erfahrung basierend.

Phase 2 → Phase 3: Von „manuell" zu „systematisch". Das ist ein qualitativer Sprung – professionelle Werkzeuge (Lighthouse, Performance-Panel) werden zur Diagnose von Performance-Problemen eingesetzt, wissenschaftliche Methoden (Code Splitting, Lazy Loading) zur Optimierung statt bloßem Gefühl.

Phase 3 → Phase 4: Von „einmaliger Optimierung" zu „kontinuierlicher Optimierung". Wenn Performance-Optimierung Teil des Entwicklungsprozesses wird, braucht man ein Überwachungssystem (RUM, Real User Monitoring), um Performance-Budgets bereits in der Entwicklungsphase festzulegen und Verschlechterungen zu verhindern.

Zusammenfassung: Die Entwicklung der Performance-Optimierung bedeutet nicht nur „mehr Technologie einsetzen", sondern eine komplette Veränderung der Denkweise – von reaktiv zu proaktiv, von gefühlsbasiert zu datengetrieben, von einmaliger Optimierung zu kontinuierlicher Verbesserung.

3.2 Phase 1: Urzeit – überhaupt nicht berücksichtigt

Warum „Urzeit"? Weil in dieser Phase Performance überhaupt keine Rolle spielte – Hauptsache es läuft. Das Team hatte nur 3 Leute und baute eine einfache Unternehmens-Website, das Projekt war klein und schien keine Probleme zu haben.

Aber als das Projekt wuchs und die Nutzerzahlen stiegen, kamen die Probleme ans Licht.

Entwicklungsweise:

  • Optimierungsmethoden: Keine, direkt entwickelt, ohne an Performance zu denken
  • Überwachungswerkzeuge: Keine, nach Gefühl beurteilt, ob es schnell oder langsam ist
  • Kernmetriken: Keine

Merkmale dieser Phase:

  • Vorteile: Schnelle Entwicklung, kein zusätzlicher Lernaufwand
  • Nachteile: Schlechte Benutzererfahrung, bei langsamen Netzwerken unbrauchbar
Die damaligen Probleme

Konkrete Probleme:

  1. Bilder zu groß: Der Produktmanager lud ein 5 MB großes Bannerbild für die Startseite hoch – Nutzer mit mobilen Daten mussten 1 Minute auf den Seitenaufbau warten
  2. Keine Kompression: CSS- und JS-Dateien waren völlig unkomprimiert, das Volumen war das Dreifache der komprimierten Version
  3. Kein Caching: Bei jedem Besuch wurden alle Ressourcen neu heruntergeladen, auch Stammnutzer mussten warten
  4. Synchrones Laden: Alle JS-Dateien wurden synchron im <head> geladen und blockierten das Rendern der Seite

Nutzerfeedback:

  • „Eure Webseite lässt sich nicht öffnen?"
  • „Die Bilder laden ewig nicht, nur ein weißer Bildschirm"
  • „Klicks auf Buttons reagieren nicht – ist die Seite kaputt?"

Die damalige Notlösung:

html
<!-- Nutzer mit einem Lade-Overlay „täuschen" -->
<div id="loading">Lädt...</div>
<script>
  // Overlay erst entfernen, wenn die Seite vollständig geladen ist
  window.onload = function() {
    document.getElementById('loading').style.display = 'none'
  }
</script>

Das war reine „Selbsttäuschung" – die Seite war immer noch langsam, der Nutzer sah es nur nicht.

3.3 Phase 2: Manuelle Optimierung – erste Ansätze von Bewusstsein

Als sich die Probleme der Urzeit anhäuften, beschloss das Team endlich, mit Performance-Optimierung zu beginnen. Das war ein wichtiger Wendepunkt – von „überhaupt nicht berücksichtigt" zu „bewusster Optimierung".

Aber die Optimierung in dieser Phase war noch recht primitiv, hauptsächlich durch einfache Mittel wie Bildkompression und Dateizusammenführung.

Entwicklungsweise:

  • Optimierungsmethoden: Manuelle Bildkompression, CSS/JS-Dateien zusammenführen, HTTP-Anfragen reduzieren
  • Überwachungswerkzeuge: Browser Network-Panel, einfache Zeitmessungs-Logs
  • Kernmetriken: Seitenladezeit (manuell mit Stoppuhr gemessen)

Merkmale dieser Phase:

  • Vorteile: Deutliche Verbesserung, Nutzer beschweren sich nicht mehr ständig
  • Nachteile: Optimierung nicht systematisch, anfällig für Rückschritte, keine quantitativen Metriken
Die konkreten Methoden der manuellen Optimierung

Manuelle Optimierungsmethoden:

  1. Bilder manuell komprimieren:

    • Jedes Bild in Photoshop manuell als „Für Web speichern" exportieren
    • PNG in JPEG konvertieren (verlustbehaftete Kompression, aber deutlich geringeres Volumen)
    • Bildabmessungen verkleinern (z.B. 2000px breite Bilder auf 800px verkleinern)
  2. Dateien manuell zusammenführen:

    html
    <!-- Vor der Optimierung: 10 JS-Dateien = 10 Anfragen -->
    <script src="utils.js"></script>
    <script src="api.js"></script>
    <script src="component-a.js"></script>
    <script src="component-b.js"></script>
    ...(noch 6 weitere)
    
    <!-- Nach der Optimierung: 1 zusammengeführte JS-Datei = 1 Anfrage -->
    <script src="all.js"></script>
  3. CSS/JS ans Ende der Seite verschieben:

    html
    <body>
      <!-- Seiteninhalt -->
      <h1>Willkommen</h1>
    
      <!-- Optimierung: CSS/JS ans Ende setzen -->
      <link rel="stylesheet" href="style.css">
      <script src="app.js"></script>
    </body>

Erzielte Verbesserungen:

  • Bildvolumen von 5 MB auf 500 KB reduziert (90 % weniger)
  • HTTP-Anfragen von 30 auf 5 reduziert
  • Seitenladezeit von 30 Sekunden auf 8 Sekunden reduziert

Neue Schmerzpunkte:

  1. Hoher manueller Aufwand: Bei jedem Update mussten Bilder manuell komprimiert und Dateien zusammengeführt werden
  2. Leicht vergessbar: Neue Mitarbeiter wussten nichts von der Optimierung und luden Originalbilder hoch
  3. Keine Quantifizierung: Man wusste nur, dass es „etwas schneller" war, aber nicht genau, wie viel schneller

3.4 Phase 3: Systematische Optimierung – mit Werkzeugen und Daten arbeiten

Die Probleme der Phase 2 (hoher manueller Aufwand, fehlende Quantifizierung) plagten das Team lange. Bis das Team schließlich professionelle Werkzeuge wie Lighthouse und das Performance-Panel entdeckte und in die Ära der systematischen Optimierung eintrat.

Der Kern dieser Phase ist datengetriebene Optimierung – zuerst Probleme mit Werkzeugen diagnostizieren, Performance-Engpässe finden und dann gezielt optimieren.

Entwicklungsweise:

  • Optimierungsmethoden: Code Splitting, Lazy Loading, virtuelle Listen, automatische Bildkompression
  • Überwachungswerkzeuge: Lighthouse, Chrome Performance-Panel, WebPageTest
  • Kernmetriken: FCP (First Contentful Paint), LCP (Largest Contentful Paint), TBT (Total Blocking Time)
Die konkreten Methoden der systematischen Optimierung

Probleme mit Lighthouse diagnostizieren:

Lighthouse ist ein von Google entwickeltes automatisiertes Performance-Testwerkzeug, das umfassende Performance-Berichte und Optimierungsempfehlungen liefert.

bash
# Webseite mit Lighthouse testen
lighthouse https://www.example.com --view

Lighthouse liefert:

  • Performance-Score (0–100 Punkte)
  • Kernmetriken (FCP, LCP, CLS, TBT, INP)
  • Optimierungsempfehlungen (z.B. „Textkompression aktivieren", „Ungenutztes JavaScript entfernen")

Interpretation der Kernmetriken:

MetrikVollständiger NameBedeutungZielwert
FCPFirst Contentful PaintZeit bis zur ersten Inhaltsdarstellung (wann der Nutzer den ersten Inhalt sieht)<1,8 s
LCPLargest Contentful PaintZeit bis zur Darstellung des größten Inhalts (wann der Hauptinhalt geladen ist)<2,5 s
TBTTotal Blocking TimeGesamte Blockierungszeit (wie lange der Haupt-Thread blockiert war)<200 ms
CLSCumulative Layout ShiftKumulative Layout-Verschiebung (wie stark Seitenelemente springen)<0,1

Merkmale dieser Phase:

  • Vorteile: Gezielte Optimierung, gute Ergebnisse, quantitative Metriken
  • Nachteile: Werkzeuge und Metriken müssen gelernt werden, gewisse Einstiegshürde
Die konkreten Techniken der systematischen Optimierung

1. Code Splitting:

Große Dateien in kleine aufteilen und bei Bedarf laden. Wenn der Nutzer z.B. die Startseite besucht, wird nur der Code für die Startseite geladen – erst beim Klick auf „Über uns" wird der Code für die Über-Uns-Seite geladen.

js
// Vor der Optimierung: Der gesamte Code in einer Datei, alles auf einmal laden
import About from './views/About.vue'
import Contact from './views/Contact.vue'
// ... noch 10 weitere Seiten

// Nach der Optimierung: Lazy Loading, erst beim Zugriff laden
const About = () => import('./views/About.vue')
const Contact = () => import('./views/Contact.vue')

Effekt: Die auf der Startseite geladene Codemenge sank um 70 %, die First-Screen-Zeit von 5 auf 1,5 Sekunden.

2. Lazy Loading für Bilder:

Nur die sichtbaren Bilder laden, weitere Bilder erst beim Scrollen in den sichtbaren Bereich laden.

html
<!-- Moderne Browser unterstützen natives Lazy Loading -->
<img src="placeholder.jpg" data-src="real-image.jpg" loading="lazy" />

Effekt: Die Anzahl der auf der Startseite geladenen Bilder sank von 20 auf 3, was 80 % Bandbreite sparte.

3. Virtuelles Scrollen (Virtual Scrolling):

Wenn 10.000 Datensätze gerendert werden müssen, nicht wirklich 10.000 DOM-Knoten erstellen, sondern nur die 20 sichtbaren rendern und beim Scrollen dynamisch ersetzen.

vue
<!-- vue-virtual-scroller-Komponente verwenden -->
<RecycleScroller
  :items="items"
  :item-size="50"
  key-field="id"
>
  <template #default="{ item }">
    <div>{{ item.name }}</div>
  </template>
</RecycleScroller>

Effekt: 10.000 Datensätze von „eingefroren" zu „flüssigem Scrollen", Speicherverbrauch um 95 % reduziert.

3.5 Phase 4: Kontinuierliche Optimierung – Performance als Teil des Entwicklungsprozesses

Als Werkzeuge und Methoden ausgereift waren, begann das Team, sich tiefergehenden Fragen zu widmen: Wie verhindert man Performance-Verschlechterungen? Wie macht man Performance zu einem Teil des Entwicklungsprozesses?

Der Kern dieser Phase ist der Aufbau eines Performance-Überwachungs- und Budget-Systems – nicht erst nach dem Launch optimieren, sondern Performance-Probleme bereits in der Entwicklungsphase verhindern.

Entwicklungsweise:

  • Optimierungsmethoden: Performance-Budget, Lighthouse CI, Real User Monitoring (RUM)
  • Überwachungswerkzeuge: Lighthouse CI, WebPageTest API, Google Analytics
  • Kernmetriken: INP (Interaction to Next Paint), CLS (Cumulative Layout Shift), End-to-End-Monitoring
Die konkreten Methoden der kontinuierlichen Optimierung

1. Performance-Budget festlegen:

In der Build-Konfiguration Limits setzen, bei Überschreitung Fehler ausgeben – verhindert das „versehentliche Einführen großer Dateien".

js
// vite.config.js
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        // Einzelne Datei auf maximal 200 KB begrenzen
        chunkFileNames: 'js/[name]-[hash].js',
      }
    },
    // Warnung bei Überschreitung von 200 KB
    chunkSizeWarningLimit: 200
  }
})

2. Lighthouse CI:

Bei jedem Commit automatisch Lighthouse-Tests ausführen – wenn der Performance-Score sinkt, den Merge blockieren.

yaml
# .github/workflows/lighthouse.yml
name: Lighthouse CI
on: [pull_request]
jobs:
  lighthouse:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run Lighthouse CI
        uses: treosh/lighthouse-ci-action@v9
        with:
          urls: |
            https://staging.example.com
          budgetPath: ./budget.json

3. Real User Monitoring (RUM):

Performance-Daten in echten Nutzerbrowsern sammeln, statt nur in der Entwicklungsumgebung zu testen.

js
// Performance-Daten an den Server senden
const perfData = performance.getEntriesByType('navigation')[0]
const lcp = performance.getEntriesByType('largest-contentful-paint')[0]

fetch('/api/perf', {
  method: 'POST',
  body: JSON.stringify({
    fcp: perfData.loadEventEnd - perfData.fetchStart,
    lcp: lcp.renderTime || lcp.loadTime,
    url: window.location.href
  })
})

Effekt:

  • Performance-Verschlechterungen werden rechtzeitig erkannt (z.B. ein Commit lässt LCP von 2 auf 5 Sekunden steigen)
  • Die Erfahrung echter Nutzer wird verstanden (statt des „Idealzustands" der Entwicklungsumgebung)
  • Die langsamsten 10 % der Nutzer können gezielt optimiert werden

Was passiert in dieser Phase?

  1. Performance-Budget: Dateigrößen und Anfragezahlen begrenzen, bei Überschreitung Alarm auslösen
  2. CI/CD-Prüfung: Bei jedem Commit automatisch Performance testen, bei Verschlechterung Merge blockieren
  3. Real User Monitoring: Performance-Daten echter Nutzer sammeln und kontinuierlich verbessern
  4. Regelmäßige Performance-Berichte: Wöchentliche/monatliche Performance-Berichte erstellen, Trends verfolgen

4. Häufige Performance-Engpässe und Lösungen

Nach all der Theorie schauen wir uns die häufigsten Performance-Probleme in der Praxis an und wie man sie löst.

4.1 Langsame Bildladung

Symptom: Bilder laden ewig nicht oder die Seite springt während des Ladens.

Ursachen:

  • Bilder sind zu groß (hochauflösende Originale)
  • Bildabmessungen zu groß (2000px breites Bild wird als 200px angezeigt)
  • Kein Lazy Loading (alle Bilder werden auf einmal geladen)

Lösungen:

  1. Moderne Bildformate verwenden (WebP, AVIF):
html
<!-- Modern: WebP-Format, 30–70 % kleineres Volumen -->
<picture>
  <source srcset="image.webp" type="image/webp">
  <img src="image.jpg" alt="Bild">
</picture>
  1. Responsive Bilder (je nach Gerät unterschiedliche Größen laden):
html
<!-- Kleine Geräte laden kleine Bilder, große Geräte laden große Bilder -->
<img
  src="image-800.jpg"
  srcset="image-400.jpg 400w,
          image-800.jpg 800w,
          image-1200.jpg 1200w"
  sizes="(max-width: 600px) 400px,
         (max-width: 1200px) 800px,
         1200px"
  alt="Responsive Bild">
  1. Lazy Loading (erst laden, wenn der Nutzer dorthin scrollt):
html
<!-- Modern: natives Lazy Loading -->
<img src="placeholder.jpg" data-src="real-image.jpg" loading="lazy" />

👇 Probiere es selbst aus: Die folgende Demo vergleicht Lazy Loading mit und ohne Lazy Loading. Beobachte die Netzwerkanfragen:

Image Format Comparison: Size and Quality Tradeoffs
Compare size and quality across image formats.
JPEG
Classic
🖼️
500 KB
File size500 KB
Compression70%
Quality
Browser support100%
Use case
Photos and complex images
PNG
Lossless
🖼️
1.2 MB
File size1.2 MB
Compression40%
Quality
Browser support100%
Use case
Transparent images and icons
WebP
🖼️
250 KB
File size250 KB
Compression85%
Quality
Browser support95%
Use case
Most scenarios
AVIF
Newest
🖼️
180 KB
File size180 KB
Compression90%
Quality
Browser support75%
Use case
Maximum performance

Detailed Comparison

FormatSizeQualityTransparencyAnimationRecommendation
JPEGMediumGood
★★★★☆
PNGLargePerfect
★★★★★
WebPSmallExcellent
★★★★★
AVIFSmallestOutstanding
★★★★★
💡

Optimization Tips

  • Prefer WebP to reduce size by 30-50%.
  • Provide JPEG/PNG fallbacks for older browsers.
  • Use the <picture> element for automatic fallback.
  • Use JPEG for photos and PNG or SVG for icons.
🔧

Recommended Tools

  • Squoosh: open-source image compression from Google.
  • ImageOptim: image optimization tool for macOS.
  • TinyPNG: online smart compression with WebP support.
  • Sharp: Node.js image processing library for automation.

4.2 Langsame First-Screen-Darstellung

Symptom: Der Nutzer öffnet die Webseite und sieht lange einen weißen Bildschirm.

Ursachen:

  • Zu viel unnötiger Code wird geladen
  • Der kritische Renderpfad ist blockiert
  • Kein Code Splitting

Lösungen:

  1. Code Splitting:
js
// Lazy Loading für Routen: Erst beim Zugriff laden
const routes = [
  {
    path: '/about',
    component: () => import('./views/About.vue')  // Erst laden, wenn /about aufgerufen wird
  }
]
  1. Kritische Ressourcen vorab laden (Preload):
html
<!-- Dem Browser mitteilen: Diese Ressourcen sind wichtig, priorisiert laden -->
<link rel="preload" href="critical.css" as="style">
<link rel="preload" href="hero-image.jpg" as="image">
  1. Kritisches CSS inline einbinden:
html
<!-- Das für den First Screen benötigte CSS direkt in HTML einbetten -->
<style>
  /* Kritische First-Screen-Styles */
  .hero { background: #000; color: #fff; }
</style>

4.3 Ruckelndes Scrollen

Symptom: Die Seite ruckelt beim Scrollen, läuft nicht flüssig.

Ursachen:

  • Zu viele DOM-Knoten werden gerendert (z.B. 10.000 Datensätze)
  • Komplexe Berechnungen in Scroll-Event-Listenern
  • Häufige Layout-Berechnungen werden ausgelöst

Lösungen:

  1. Virtuelles Scrollen (Virtual Scrolling):
vue
<!-- Nur den sichtbaren Bereich rendern -->
<RecycleScroller
  :items="10000"
  :item-size="50"
>
  <template #default="{ item }">
    <div>{{ item.name }}</div>
  </template>
</RecycleScroller>

👇 Selbst ausprobieren: Die folgende Demo vergleicht die Performance einer normalen Liste mit einer virtuellen Liste:

📜Virtual ScrollingRender only the list items visible in the viewport.
Total items
10,000
Actually rendered
8
Memory saved
~99.9%
1Item #1 - virtual scrolling list item content
2Item #2 - virtual scrolling list item content
3Item #3 - virtual scrolling list item content
4Item #4 - virtual scrolling list item content
5Item #5 - virtual scrolling list item content
6Item #6 - virtual scrolling list item content
7Item #7 - virtual scrolling list item content
8Item #8 - virtual scrolling list item content
💡How it works: Instead of rendering all 10000 items, it renders only the visible viewport items plus a small buffer. On scroll, it calculates which items should appear and uses absolute positioning to create the illusion of a full list. Performance improves from O(n) to O(1).
  1. Scroll-Events throttlen:
js
// Auslösefrequenz von Scroll-Events begrenzen (maximal alle 100 ms)
const throttledScroll = throttle(() => {
  updatePosition()
}, 100)

window.addEventListener('scroll', throttledScroll)
  1. CSS will-change verwenden:
css
/* Dem Browser mitteilen: Dieses Element wird sich ändern, bitte vorbereiten */
.scroll-container {
  will-change: transform;
}

4.4 Langsame Klick-Reaktion

Symptom: Nach einem Klick auf einen Button dauert es mehrere Sekunden, bis eine Reaktion erfolgt.

Ursachen:

  • Komplexe Berechnungen im Klick-Event-Handler (blockieren den Haupt-Thread)
  • Kein Debouncing (schnelles Mehrfachklicken löst mehrfache Berechnungen aus)

Lösungen:

  1. Klick-Events debouncen:
js
// Erst 300 ms nach dem letzten Klick ausführen
const debouncedClick = debounce(() => {
  submitForm()
}, 300)

button.addEventListener('click', debouncedClick)
  1. Web Worker verwenden (Berechnungen in Hintergrund-Thread auslagern):
js
// Haupt-Thread
const worker = new Worker('calculator.js')
button.addEventListener('click', () => {
  worker.postMessage({ data: largeData })
})

worker.onmessage = (e) => {
  // Berechnung abgeschlossen, Ergebnis anzeigen
  showResult(e.data.result)
}

// calculator.js (Worker-Thread)
self.onmessage = (e) => {
  const result = heavyCalculation(e.data.data)
  self.postMessage({ result })
}

5. Performance-Überwachungswerkzeuge

Performance-Optimierung ist keine einmalige Arbeit – sie muss kontinuierlich überwacht werden. Hier sind die gängigen Werkzeuge.

5.1 Browser-Entwicklertools

Chrome DevTools ist das am häufigsten verwendete Performance-Analysewerkzeug:

  • Network-Panel: Ressourcen-Ladevorgänge anzeigen
  • Performance-Panel: Laufzeit-Performance analysieren (FPS, Haupt-Thread-Aktivität)
  • Lighthouse: Performance-Bericht mit einem Klick erstellen

Wie man das Performance-Panel nutzt

  1. Chrome DevTools öffnen (F12)
  2. Zum Performance-Panel wechseln
  3. Auf „Record" klicken
  4. Die Webseite bedienen (scrollen, klicken usw.)
  5. Auf „Stop" klicken, um die Aufnahme zu beenden
  6. Ergebnisse analysieren: FPS (Framerate), Haupt-Thread-Aktivität, Long Tasks usw.

5.2 Lighthouse

Lighthouse ist ein von Google entwickeltes automatisiertes Performance-Testwerkzeug:

bash
# Verwendung über die Kommandozeile
lighthouse https://www.example.com --view

# Oder in Chrome DevTools verwenden
# DevTools öffnen → Lighthouse → Auf „Analyze page load" klicken

Lighthouse liefert:

  • Performance-Score (0–100 Punkte)
  • Kernmetriken (FCP, LCP, CLS, TBT, INP)
  • Optimierungsempfehlungen (nach Auswirkung sortiert)

5.3 WebPageTest

WebPageTest ist ein Online-Performance-Testwerkzeug, das von mehreren Standorten und mit verschiedenen Geräten testen kann:

bash
# https://www.webpagetest.org besuchen
# URL eingeben, Teststandort und Gerät auswählen, auf „Start Test" klicken

WebPageTest liefert:

  • Wasserfalldiagramm (Waterfall): Zeitstrahl für jede geladene Ressource
  • Videovergleich: Ladevorgang vor und nach der Optimierung als Video
  • Optimierungsempfehlungen

6. Performance-Optimierungs-Checkliste

Hier ist eine praktische Performance-Optimierungs-Checkliste – du kannst deine Webseite in dieser Reihenfolge optimieren:

6.1 Ladeoptimierung

  • Bilder komprimieren: WebP-Format verwenden, Kompressionsqualität 80–85 %
  • Responsive Bilder: Je nach Gerät unterschiedliche Bildgrößen laden
  • Lazy Loading: Bilder und Komponenten per Lazy Loading laden, nur sichtbare Inhalte
  • Code Splitting: Code nach Routen aufteilen, bei Bedarf laden
  • Code komprimieren: Gzip/Brotli-Kompression aktivieren
  • CDN verwenden: Statische Ressourcen auf CDN auslagern, Download beschleunigen
  • Kritische Ressourcen vorab laden: <link rel="preload"> verwenden

6.2 Render-Optimierung

  • Reflows und Repaints reduzieren: transform und opacity statt top und width verwenden
  • Virtuelle Listen: Bei großen Datenmengen virtuelles Scrollen verwenden
  • CSS-Animationen: CSS-Animationen vor JavaScript-Animationen bevorzugen
  • Kritischen Renderpfad optimieren: Kritisches CSS inline einbinden, nicht-kritisches CSS verzögert laden
  • @import vermeiden: @import blockiert das Rendern, stattdessen <link> verwenden

6.3 Interaktionsoptimierung

  • Debouncing und Throttling: Bei Scroll-, Eingabe- und Resize-Events Debouncing/Throttling verwenden
  • Web Worker: Komplexe Berechnungen in Hintergrund-Threads auslagern
  • Time Slicing: Große Aufgaben in kleine aufteilen, Long Tasks vermeiden
  • Synchrone Layouts vermeiden: Layout-Eigenschaften (wie offsetHeight) nicht in Schleifen lesen

6.4 Cache-Optimierung

  • HTTP-Caching: Cache-Control und ETag konfigurieren
  • Service Worker: Statische Ressourcen cachen, Offline-Zugriff ermöglichen
  • LocalStorage: API-Daten cachen, Anfragen reduzieren
  • In-Memory-Caching: Map/Object zum Cachen von Berechnungsergebnissen verwenden

6.5 Überwachungsoptimierung

  • Lighthouse CI: Bei jedem Commit automatisch Performance testen
  • Real User Monitoring: Performance-Daten echter Nutzer sammeln
  • Performance-Budget: Dateigrößenlimits setzen, bei Überschreitung Alarm auslösen
  • Regelmäßige Performance-Berichte: Wöchentliche/monatliche Performance-Trendberichte erstellen

7. Zusammenfassung

Lass uns die Kernkonzepte der Frontend-Performance-Optimierung mit einer Tabelle zusammenfassen:

KonzeptIn einem Satz erklärtGelöstes ProblemGängige Methoden
LadeoptimierungRessourcen schneller herunterladenLangsamer First Screen, lange WartezeitenBilder komprimieren, CDN, Code Splitting, Lazy Loading
Render-OptimierungSeite schneller „malen"Ruckelndes Scrollen, langsame KlicksVirtuelle Listen, Reflows/Repaints reduzieren, CSS-Animationen
InteraktionsoptimierungSchnellere ReaktionenKeine Reaktion auf Klicks, ruckelnde BedienungDebouncing/Throttling, Web Worker, Time Slicing
Cache-OptimierungWiederholte Downloads vermeidenLangsame wiederholte BesucheHTTP-Caching, Service Worker, LocalStorage
ÜberwachungsoptimierungKontinuierlich Probleme erkennenPerformance-VerschlechterungLighthouse, RUM, Performance-Budget

Zum Schluss

Performance-Optimierung ist ein sich ständig weiterentwickelndes Thema – Werkzeuge ändern sich, aber das Kernprinzip bleibt: Aus der Perspektive der Nutzer denken, Wartezeiten verkürzen und die Bedienung flüssiger machen.

Wenn du diese Grundprinzipien verstanden hast, kannst du dich unabhängig vom technologischen Wandel schnell einarbeiten und souverän handeln.

Wir hoffen, dass dieser Artikel dir hilft, ein umfassendes Verständnis der Frontend-Performance-Optimierung aufzubauen. Wenn du in deinen Projekten auf Performance-Probleme stößt, weißt du, wo du ansetzen, wie du sie lokalisieren und lösen kannst.