[ ANALYSIS ][ LIGHTHOUSE ][ PERFORMANCE ][ NEXTJS ][ CI_CD ]

Lighthouse CI — automatisierte Next.js-Performance-Audits in GitHub Actions (2026)

28. Mai 20269 Min. Lesezeit
Autor: DevStudio.itWeb & KI Studio

Core Web Vitals-Regressionen in PRs blockieren — Budgets, lighthouserc.json, GitHub-Actions-Workflow und Kompromiss GA4 vs. Google Ads.

READ_TIME: 9 MIN_COMPLEXITY: MED_
STAMP: VERIFIED_BY_DS_

Kurzfassung

Lighthouse CI (LHCI) führt bei jedem Pull Request einen Performance-Audit aus und blockiert den Merge, wenn LCP 2,5 s überschreitet, CLS 0,1 oder der Performance-Score unter 0,85 fällt. Für ein Next.js-15-Projekt auf Node 22 mit Build node scripts/build.cjs und Lint eslint ist das die günstigste Versicherung gegen „kleine CSS-Änderung“, die eine Woche später SEO und Google-Ads-Conversions schadet. Im Folgenden: fertiges lighthouserc.json, GitHub-Actions-Workflow und bewusster Tradeoff GA4 afterInteractive vs. Ads-Tags lazyOnload.

Für wen ist das

  • Next.js / React-Teams mit Deploy auf Vercel oder eigenem Hosting
  • Unternehmenswebsites, bei denen Marketing und Ads von schnellem LCP abhängen
  • Firmen ohne dediziertes Performance-QA — LHCI ist ein Bot, der Mobile nicht vergisst
  • Entwickler, die Lighthouse vierteljährlich manuell starten und hoffen, „dass es noch passt“

Keyword (SEO)

lighthouse ci nextjs, performance audit automatisieren, github actions lighthouse, core web vitals ci, lighthouserc.json, performance regression pull request

Warum ein Einmal-Audit nicht reicht

Jeder PR kann einführen:

  • neues Analyse-Skript ohne strategy="lazyOnload",
  • Hero-Bild ohne width/heightCLS-Sprung,
  • Import der ganzen Icon-Bibliothek statt Tree-Shaking,
  • Font ohne display: swap,
  • schwerere Client-Komponente statt Server Component.

Lighthouse auf next dev lokal täuscht oft — anderes Bundling, keine Produktionsoptimierung, anderer Cache. CI auf next build + next start nähert sich dem, was Nutzer und Google sehen.

Referenz-Stack (DevStudio / Next.js 15)

Element Wert
Framework Next.js 15.5.x
Node 22.x (engines in package.json)
Build npm run buildnode scripts/build.cjs
Lint npm run linteslint
Produktionsstart npm run startnext start
Analyse GA4 afterInteractive, Google Ads lazyOnload

Diese Tag-Aufteilung ist für LHCI wichtig: Ein PR, der ein weiteres Skript afterInteractive hinzufügt, kann funktional passen und Performance fallen lassen — genau das soll die Pipeline fangen.

Schwellenwerte (Mobile)

Metrik LHCI-Schwelle Warum
LCP 2500 ms Hero, erster Eindruck, SEO
CLS 0,1 Springendes Formular = weniger Leads
INP 200 ms (optional in assert) Menü, Chatbot, Interaktionen
Performance-Score 0,85 Landing-Page-Qualität (Ads, Search)

Schwellen sind bewusst streng für Marketing-Sites — eine SaaS-App mit Dashboard kann andere Budgets haben.

Datei lighthouserc.json — funktionierendes Beispiel

Im Repository-Root ablegen:

{
  "ci": {
    "collect": {
      "numberOfRuns": 3,
      "startServerCommand": "npm run start",
      "startServerReadyPattern": "Ready",
      "startServerReadyTimeout": 120000,
      "url": [
        "http://localhost:3000/pl",
        "http://localhost:3000/en",
        "http://localhost:3000/pl/strony-www"
      ],
      "settings": {
        "preset": "desktop",
        "onlyCategories": ["performance", "accessibility", "best-practices", "seo"]
      }
    },
    "assert": {
      "preset": "lighthouse:recommended",
      "assertions": {
        "categories:performance": ["error", { "minScore": 0.85 }],
        "largest-contentful-paint": ["error", { "maxNumericValue": 2500 }],
        "cumulative-layout-shift": ["error", { "maxNumericValue": 0.1 }],
        "interactive": ["warn", { "maxNumericValue": 3800 }],
        "total-blocking-time": ["warn", { "maxNumericValue": 300 }]
      }
    },
    "upload": {
      "target": "temporary-public-storage"
    }
  }
}

Praktische Hinweise:

  • numberOfRuns: 3 — Median aus drei Läufen reduziert LHCI-Rauschen.
  • URLs geschäftskritisch wählen (Home PL/EN + wichtige Service-Seite).
  • Für Mobile preset auf "perf" setzen oder separaten Job mit emulatedFormFactor: "mobile" (eigene Config oder Matrix in Actions).
  • upload.target: temporary-public-storage — schnelle Report-Links im PR ohne eigenen LHCI-Server (Produktion: LHCI Server oder GitHub-Artefakte).

GitHub Actions — vollständiger Workflow

Datei .github/workflows/lighthouse.yml:

name: Lighthouse CI

on:
  pull_request:
    branches: [main, master]
  push:
    branches: [main, master]

jobs:
  lhci:
    runs-on: ubuntu-latest
    timeout-minutes: 25

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Lint
        run: npm run lint

      - name: Build
        run: npm run build
        env:
          NODE_ENV: production

      - name: Run Lighthouse CI
        run: |
          npm install -g @lhci/cli@0.14.x
          lhci autorun
        env:
          LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}

Optional separater Job mit Vercel-Preview-URL (näher am CDN):

      - name: Collect against Vercel Preview
        if: github.event_name == 'pull_request'
        run: lhci collect --url="${{ steps.vercel.outputs.preview_url }}/pl"

Preview spiegelt Edge-Cache besser, braucht aber stabile URL und Secrets — localhost nach next build ist ein guter Start ohne Extra-Infrastruktur.

Pipeline-Reihenfolge — was vor LHCI laufen muss

  1. npm ci
  2. npm run lint — schneller Fail vor teurem Build
  3. npm run buildderselbe Build wie Produktion (scripts/build.cjs)
  4. lhci autorun — Server starten, 3× URL, assert

Ohne Schritt 3 misst LHCI den Dev-Server — falsches Grün.

Typische in PRs erkannte Regressionen

Marketing-Skripte

gtag ohne strategy="lazyOnload" in next/script erhöht TBT und verzögert LCP. Auf der Referenzseite:

  • GA4afterInteractive (generate_lead bei schnellem Submit nicht verlieren),
  • Google Ads (AW-...)lazyOnload (Performance schützen).

Ein PR, der alle Tags auf afterInteractive setzt, kann Ads reparieren und Performance zerstören — LHCI sollte das zeigen; Marketing muss den Kompromiss kennen (separater Artikel: Google-Ads-Conversion-Tracking).

Bilder und Fonts

  • Hero: priority, feste Maße, AVIF/WebP wo möglich.
  • Font: next/font oder display: swap.
  • Logo in der Fußzeile ohne width/heightCLS beim Font-Laden.

JavaScript

  • Dynamic Import für Chatbot und schwere Widgets.
  • Große Pakete nicht im Server-Component-Layout.

Integration mit Vercel und RUM

Schicht Nutzen
LHCI im PR Synthetik vor Merge — blockiert Regression
Vercel Analytics / Speed Insights RUM echter Nutzer nach Deploy
Search Console Core Web Vitals Google-Felddaten mit Verzögerung

LHCI ersetzt RUM nicht — beides nutzen. LHCI = Qualitätsgate; RUM = Wahrheit im Feld (schwache Geräte, 3G, Adblock).

Praktischer Ablauf in einem kleinen Team: Entwickler öffnet PR → LHCI kommentiert LCP/CLS-Delta → Merge nur bei Grün → nach Deploy prüft Marketing Speed Insights auf der Produktionsdomain. Weicht RUM stark von LHCI ab, liegt das oft an Third-Party-Skripten (Ads, Chat-Widget), Consent-Bannern oder regionalem CDN — nicht automatisch am letzten Code-Diff. Dokumentieren Sie solche Abweichungen, damit niemand die LHCI-Schwellen „lockert“, obwohl echte Nutzer leiden.

Bot-Kommentar im PR

Mit LHCI_GITHUB_APP_TOKEN (offizielle Lighthouse-CI-App) landen Reports im Kommentar mit PR vs. Base. Ohne Token: Log in Actions und temporary-public-storage.

Erweitertes assert — SEO und Barrierefreiheit

Zusätzlich sinnvoll:

"categories:seo": ["warn", { "minScore": 0.9 }],
"categories:accessibility": ["warn", { "minScore": 0.9 }],
"categories:best-practices": ["warn", { "minScore": 0.9 }]

Zuerst warn, nach Stabilisierung error. Sonst wird jeder PR mit kleiner axe-Regel rot und das Team schaltet LHCI ab.

CI-Zeitkosten

Schätzung: 3 Läufe × 3 URLs × ~40–60 s6–10 Minuten + Next-Build (2–8 Min). Beschleunigung:

  • Cache ~/.npm und .next/cache in Actions,
  • weniger URLs im collect (nur /pl auf Feature-Branch),
  • voller URL-Satz nur auf main.

Immer noch günstiger als eine Woche Conversion-Einbruch nach LCP-Regression.

FAQ

Ersetzt Lighthouse CI manuelles PageSpeed Insights?

Nein — PSI bleibt für Ad-hoc-Checks. LHCI automatisiert dasselbe pro PR. PSI auf Produktions-URL nach Release als Kontrolle.

Nur Desktop testen?

Möglich, aber Google nutzt Mobile für CWV in Search. Minimum: ein Mobile-Job auf main, Desktop auf PR wenn CI-Zeit wehtut.

Build braucht Umgebungsvariablen — was in CI?

Nicht-geheime Variablen im Job-env:; Secrets in GitHub Secrets. build.cjs lädt oft dasselbe wie Vercel — ohne das bricht der Build vor LHCI.

PR setzt GA4 auf afterInteractive — Fehler?

Nicht immer — bewusste Produktentscheidung (Leads nicht verlieren). LHCI kann Performance-Regression zeigen — dann andere Stelle optimieren (Bilder, Fonts, Code-Split), nicht zwingend GA4 zurückdrehen.

eslint im selben Workflow wie LHCI?

Ja — schneller Fail. Separates Lint-Workflow auch OK; wichtig: Produktionsbuild als Gate vor lhci autorun.

Lokaler Lauf vor dem PR

Auf der Entwicklermaschine (Node 22):

npm run build
npm run start
# zweites Terminal:
npx @lhci/cli autorun

Wenn lokal grün und CI rot — Unterschiede in Umgebungsvariablen, Node-Version und Cache prüfen. Wenn lokal rot und Vercel OK — vermutlich dev statt production build gemessen.

Tipp für Windows-Entwickler: PowerShell und Git Bash unterscheiden sich manchmal bei Pfaden und Env-Loading — CI läuft auf Ubuntu. Wenn LHCI lokal auf Windows scheitert, aber Actions grün sind, zuerst WSL oder Docker mit Node 22 nutzen, bevor Schwellen angepasst werden. Das spart falsche „CI ist kaputt“-Diskussionen im Team.

Checkliste — Implementierung an einem Tag

  • lighthouserc.json im Repo mit LCP / CLS / Performance-Schwellen
  • Workflow mit Node 22, npm ci, lint, build, lhci autorun
  • 2–3 conversion-kritische URLs
  • Secret LHCI_GITHUB_APP_TOKEN (optional Kommentare)
  • Team weiß: GA4 früh, Ads spät — nicht „alles lazyOnload“
  • Nach Merge: RUM auf Produktion zur Verifikation

Beispiel-Job Mobile (eigene Matrix)

Im selben Workflow zweiter Schritt mit Mobile-Preset — kritisch für Google CWV:

      - name: Run Lighthouse CI (mobile)
        run: |
          npm install -g @lhci/cli@0.14.x
          lhci autorun --config=lighthouserc.mobile.json

Datei lighthouserc.mobile.json — Kopie der Basis mit:

"settings": {
  "preset": "perf",
  "formFactor": "mobile",
  "screenEmulation": { "mobile": true }
}

LCP/CLS-Asserts gleich lassen — Mobile ist strenger; wer Mobile in CI besteht, ist auf Desktop meist sicher.

Was tun, wenn LHCI nach Merge fehlschlägt

  1. Report aus temporary-public-storage oder Bot-Kommentar öffnen.
  2. Opportunities prüfen (Bilder, unused JS, render-blocking).
  3. Diff mit Base-Branch — welcher PR brachte Regression.
  4. Schwellen nicht dauerhaft senken ohne Business-Grund — besser einmalige Ausnahme mit Ticket als permanent minScore: 0.7.

Typischer Win: Skript nach lazyOnload, priority auf LCP-Bild, dynamic(() => import(...)) für Chatbot.

Wann Schwellen temporär lockern (selten)

Manchmal liefert ein PR messbare Business-Verbesserung mit minimaler Performance-Einbuße — z. B. zusätzliches Analytics-Event, das Marketing zwingend braucht. Statt dauerhaft minScore: 0.7 zu setzen: einmaliger LHCI-Waiver im PR mit Ticket, Follow-up-Task für Optimierung in der nächsten Iteration. Permanent niedrigere Schwellen machen LHCI wertlos; das Team gewöhnt sich an Gelb und verpasst echte Regressionen bei Hero-Bildern oder Font-Imports.

Bezug zu Google Ads und Landing-Page-Qualität

Google bewertet Landing-Page-Erlebnis u. a. über Geschwindigkeit und Layout-Stabilität. LCP-Regression in einem gemergten PR kann CPC erhöhen und Quality Score senken — Kosten in Ads, nicht nur in Lighthouse. Wer AW--Tags hinzufügt, sollte rotes LHCI sehen, bevor die Kampagne auf langsamerer Seite lernt.

scripts/build.cjs — warum nicht rohes next build

Im Produktionsprojekt umschließt der Build oft Env-Validierung, Prisma, Asset-Kopien vor next build. LHCI muss dieselbe Kommandozeile wie Vercel (npm run build) nutzen, sonst messen Sie ein anderes Bundle. Build in CI wegen fehlendem DATABASE_URLMock oder DB-Skip nur im LHCI-Job, in README dokumentieren.

Dokumentieren Sie im Team-Wiki außerdem, welche URLs in lighthouserc.json Conversion-kritisch sind — Marketing und Dev sollten dieselbe Liste pflegen, wenn neue Landing Pages dazukommen.

Zusammenfassung

Lighthouse CI auf Next.js 15 ist die Spielregel: lint → Produktionsbuild → Audit → assert. Schwellen LCP ≤ 2,5 s, CLS ≤ 0,1, Performance ≥ 0,85 schützen SEO und Landing-Page-Qualität unter Ads. Denken Sie an den Analyse-Tradeoff: GA4 afterInteractive vs. Google Ads lazyOnload — die Pipeline soll Kosten von PRs zeigen, die das Gleichgewicht stören. Synthetik in CI + RUM nach Deploy = vollständiges Bild. Node 22, eslint und scripts/build.cjs — dieselbe Qualitätskette wie Produktion.

Performance-Pipeline bei Ihnen?

Über den Autor

Wir bauen schnelle Websites, Web/Mobile-Apps, KI-Chatbots und Hosting — mit Fokus auf SEO und Conversion.

Empfohlene Links

Von Theorie zu Produktion — Branchly, Hosting-Stack, Betreuung und Referenzen.

GEFÄLLT EUCH UNSERE ARCHITEKTUR DES DENKENS? LASST UNS GEMEINSAM BAUEN.

[ PROJEKT_KONFIGURATION_STARTEN ]