Performance-Budgets: Standards festlegen und durchsetzen
Wie Sie Performance-Budgets definieren, messen und durchsetzen, um zu verhindern, dass Ihre Webanwendung mit der Zeit unbemerkt langsamer wird.

Jede Webanwendung startet schnell. Dann fügt jemand eine Carousel-Bibliothek hinzu. Dann ein Analytics-Skript. Dann einen Datepicker, der gleich das komplette Moment.js mitbringt. Sechs Monate später braucht die Landingpage 8 Sekunden zum Laden, und niemand kann auf einen einzelnen Commit zeigen, der das verursacht hat.
Performance-Budgets machen dieses schleichende Wachstum sichtbar und verhinderbar. Es sind harte Zahlen — maximale Bundle-Größe, maximaler Wert für Time to Interactive, maximale Anzahl an Requests —, die der Build-Prozess automatisch durchsetzt.
Was budgetiert werden sollte
Performance-Budgets lassen sich in drei Kategorien einteilen: Timing-Metriken, Größen-Metriken und Zähl-Metriken. Jede erkennt eine andere Art von Regression.
# performance-budget.yml
timing:
first-contentful-paint: 1800 # ms
largest-contentful-paint: 2500 # ms
time-to-interactive: 3500 # ms
cumulative-layout-shift: 0.1 # unitless
size:
total-bundle: 250 # KB (compressed)
javascript: 170 # KB (compressed)
css: 50 # KB (compressed)
images-per-page: 500 # KB
count:
requests: 50
third-party-scripts: 3Beginnen Sie mit den Metriken, die für Ihre Anwendung am wichtigsten sind. Ein E-Commerce-Shop priorisiert wahrscheinlich Largest Contentful Paint (Produktbilder). Ein Dashboard priorisiert eher Time to Interactive (komplexes JavaScript). Eine Content-Seite priorisiert eher First Contentful Paint (Textrendering).
Budget-Einhaltung messen
Lighthouse CI integriert Performance-Budget-Prüfungen direkt in Ihre CI-Pipeline. Es führt Lighthouse gegen Ihre deployte oder lokal servierte App aus und vergleicht die Ergebnisse mit den festgelegten Schwellenwerten.
// lighthouserc.js
module.exports = {
ci: {
collect: {
url: ['http://localhost:3000/', 'http://localhost:3000/dashboard'],
numberOfRuns: 3,
},
assert: {
assertions: {
'first-contentful-paint': ['warn', { maxNumericValue: 1800 }],
'largest-contentful-paint': ['error', { maxNumericValue: 2500 }],
'interactive': ['error', { maxNumericValue: 3500 }],
'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }],
'total-byte-weight': ['warn', { maxNumericValue: 500000 }],
},
},
upload: {
target: 'temporary-public-storage',
},
},
};Die Unterscheidung zwischen warn und error ist wichtig. Warnings markieren Regressionen in den Pull-Request-Kommentaren. Errors blockieren den Merge. Nutzen Sie Warnings für ambitionierte Ziele und Errors für nicht verhandelbare Grenzwerte.
Bundle-Größe überwachen
Die Bundle-Größe ist die vorhersehbarste Performance-Metrik. Anders als Timing-Metriken (die je nach Gerät und Netzwerk schwanken) ist die Bundle-Größe deterministisch — gleicher Code, gleiche Größe, jedes Mal.
// bundlesize.config.js — or use bundlewatch, size-limit
module.exports = [
{
path: 'dist/main.*.js',
maxSize: '120 KB',
compression: 'gzip',
},
{
path: 'dist/vendor.*.js',
maxSize: '80 KB',
compression: 'gzip',
},
{
path: 'dist/*.css',
maxSize: '30 KB',
compression: 'gzip',
},
];Tools wie size-limit gehen noch weiter — sie messen nicht nur die Dateigröße, sondern auch die tatsächliche Ausführungszeit und die Parse-Kosten:
# package.json
{
"size-limit": [
{
"path": "dist/index.js",
"limit": "15 KB",
"running": true
}
],
"scripts": {
"size": "size-limit",
"size:check": "size-limit --why"
}
}size-limit --why auszuführen zeigt genau, welche Abhängigkeiten zu Ihrem Bundle beitragen — so findet man die 200-KB-Bibliothek, die jemand für eine einzige Hilfsfunktion importiert hat.
Webpack-Bundle-Analyse
Wenn ein Budget überschritten wird, müssen Sie verstehen, warum. Bundle-Analyzer visualisieren, was in Ihren Bundles steckt.
// webpack.config.js
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: 'bundle-report.html',
openAnalyzer: false,
}),
],
};Typische Befunde einer Bundle-Analyse:
- Doppelte Abhängigkeiten: zwei Versionen derselben Bibliothek (z. B. lodash 4.x und 3.x) durch transitive Abhängigkeiten
- Ungenutzte Exports: eine ganze Bibliothek importieren, obwohl nur eine Funktion genutzt wird — Tree Shaking funktioniert nur mit ES-Modulen
- Locale-Daten: Bibliotheken wie Moment.js oder date-fns liefern standardmäßig alle Locales mit
// ❌ Imports entire lodash — 70KB+ in your bundle
import _ from 'lodash';
const result = _.groupBy(items, 'category');
// ✅ Cherry-pick the function — ~1KB
import groupBy from 'lodash/groupBy';
const result = groupBy(items, 'category');Performance-Budgets für Bilder
Bilder machen typischerweise 50–70 % des Seitengewichts aus. Ein Bild-Budget verhindert, dass das Muster „nur noch ein Hero-Bild mehr" die Ladezeiten ruiniert.
interface ImageBudget {
maxSizeKB: number;
maxDimensions: { width: number; height: number };
requiredFormats: string[];
}
const imageBudgets: Record<string, ImageBudget> = {
hero: {
maxSizeKB: 150,
maxDimensions: { width: 1920, height: 1080 },
requiredFormats: ['webp', 'avif'],
},
thumbnail: {
maxSizeKB: 30,
maxDimensions: { width: 400, height: 300 },
requiredFormats: ['webp'],
},
avatar: {
maxSizeKB: 15,
maxDimensions: { width: 200, height: 200 },
requiredFormats: ['webp'],
},
};Setzen Sie Bild-Budgets zur Build-Zeit mit automatisierter Kompression durch. Weisen Sie Bilder, die das Budget überschreiten, zurück, bevor sie in Produktion gelangen.
Budgets in CI/CD durchsetzen
Das Budget funktioniert nur, wenn es nicht ignoriert werden kann. Integrieren Sie die Prüfungen in den Pull-Request-Workflow, damit Regressionen vor dem Merge sichtbar sind.
# .github/workflows/performance.yml
name: Performance Budget
on: [pull_request]
jobs:
budget-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm ci
- run: npm run build
- name: Check bundle size
run: npx size-limit
- name: Lighthouse CI
run: |
npm install -g @lhci/cli
lhci autorunWenn ein Budget reißt: Untersuchen Sie die Ursache, bevor Sie das Limit anheben. Die meisten Regressionen lassen sich günstiger beheben als durch eine Budgeterhöhung — Lazy Loading, Code Splitting oder das Ersetzen einer überdimensionierten Abhängigkeit.
Die wichtigsten Erkenntnisse
- Legen Sie Budgets frühzeitig fest — Performance zu erhalten ist einfacher, als sie wiederherzustellen
- Budgetieren Sie zuerst die Bundle-Größe — sie ist deterministisch und in CI messbar, ohne einen laufenden Server zu brauchen
- Nutzen Sie
errorfür harte Grenzen undwarnfür Ziele — blockieren Sie Merges nur bei nicht verhandelbaren Schwellenwerten - Analysieren Sie, bevor Sie Limits anheben — die meisten Regressionen lassen sich mit kleineren Eingriffen beheben als mit einer Budgeterhöhung
- Bild-Budgets haben den höchsten ROI — Bilder sind auf den meisten Seiten das größte Gewicht
- Automatisieren Sie die Durchsetzung in CI — ein Budget, das niemand prüft, ist ein Budget, das niemand einhält


