Ihr Production-Bundle liefert zwischen 200 KB und 800 KB JavaScript aus, und ein überraschender Teil davon löst Probleme, die der Browser bereits nativ beherrscht. Die Bibliothek date-fns, die ein paar Zeitstempel formatiert. Die lodash-Funktionen, die das tun, was Array.prototype-Methoden seit ES2015 können. Das core-js-Polyfill, das Funktionen nachrüstet, die jeder unterstützte Browser bereits mitbringt. Jede Abhängigkeit schien eine vernünftige Entscheidung, als sie jemand hinzugefügt hat. Die meisten wurden seitdem nie wieder hinterfragt.
Browser Baseline, eine gemeinsame Initiative von Google, Mozilla, Apple und Microsoft, gibt Ihnen das Werkzeug, das zu ändern. Sie erfasst präzise, welche Webplattform-Funktionen in allen großen Browsern verfügbar sind, und zwar lange genug, dass die Frage „Kann ich das nativ verwenden?" endlich eine definitive Antwort hat.
Dieser Leitfaden zeigt, wie Sie Ihre JavaScript-Abhängigkeiten gegen Baseline prüfen, erkennen, was durch native Browser-APIs ersetzt werden kann, und die realen Auswirkungen auf Bundle-Größe, Ladezeit und Wartungskosten messen.
Was Browser Baseline tatsächlich erfasst
Baseline nimmt die bekannte „Can I use"-Frage und formalisiert sie in zwei Stufen:
- Baseline 2023 (und ähnliche mit Jahreszahl versehene Meilensteine): Funktionen, die in allen vier großen Browser-Engines, Chrome, Edge, Safari und Firefox, in diesem Kalenderjahr verfügbar wurden.
- „Widely available": Funktionen, die seit mindestens 30 Monaten in allen vier Engines vorhanden sind. Das ist der sichere Standard für jedes Unternehmen, das die „aktuelle und vorherige Version" jedes Browsers unterstützt.
Die Daten liegen im Repository web-features auf GitHub und sind als echtes Dataset strukturiert, kein Blogbeitrag, kein Forenthread. Sie können es programmatisch abfragen, in Ihre CI-Pipeline integrieren und Dependency-Audits automatisieren. Das ist der Wechsel von „Ich hoffe, das funktioniert" zu „Ich kann nachweisen, dass es in jedem von uns unterstützten Browser funktioniert".
Warum das für die Bundle-Größe relevant ist
Die mediane JavaScript-Payload einer mobilen Webseite liegt bei rund 530 KB unkomprimiert (HTTP Archive, Daten Mitte 2025). Core-js-Polyfills allein machen in vielen Bundles 40-90 KB aus, weil Teams sie über @babel/preset-env einbinden, ohne ihre Browser-Targets explizit zu definieren. Dabei sind die Funktionen, die diese Polyfills abdecken, Array.prototype.flat, Object.fromEntries, String.prototype.replaceAll, seit über zwei Jahren Baseline-„widely available".
Eine einzelne veraltete Polyfill-Konfiguration zu entfernen, fühlt sich nicht heroisch an. Aber wenn Sie den vollständigen Abhängigkeitsbaum prüfen und ersetzen, was der Browser heute mitbringt, reduzieren Sie routinemäßig 30-35 % des gesamten JavaScript-Gewichts. Nicht durch clevere Code-Splitting- oder Tree-Shaking-Maßnahmen, sondern dadurch, dass Sie keinen Code ausliefern, den der Browser bereits enthält.
Schritt-für-Schritt-Dependency-Audit gegen Baseline
Hier ist der Prozess, den wir bei ProjectMakers verwenden, wenn wir Teams bei der Bundle-Optimierung beraten. Er funktioniert, egal ob Sie ihn selbst durchführen oder externe Hilfe holen.
Schritt 1: Ihr Dependency-Inventar erstellen
Beginnen Sie damit, alles aufzulisten, was Ihr Bundle tatsächlich ausliefert. npm ls --all zeigt den vollständigen Baum, aber für bundle-fokussierte Audits sind Tools wie Bundlephobia oder npx bundlephobia-deps <package> nützlicher, sie zeigen das minifizierte + gzippte Gewicht jeder Abhängigkeit einschließlich Unterabhängigkeiten.
# Full dependency tree with install size
npm ls --all --long 2>/dev/null | grep -E "^\|"
# Quick bundle weight analysis for your top-level deps
npx bundlephobia-deps date-fns lodash-es zod
Typische Ausgabe für das Frontend eines mittelgroßen SaaS-Produkts:
date-fns 12.3 kB gzip (tree-shakeable, but only if imported correctly)
lodash-es 4.2 kB per function (12-70 kB depending on usage)
core-js 45-90 kB (varies by config)
whatwg-fetch 3.3 kB
Notieren Sie diese Zahlen. Sie sind Ihre Baseline, Wortspiel beabsichtigt, zur Messung der Verbesserung.
Schritt 2: Abhängigkeiten nativen Browser-Ersetzungen zuordnen
Hier liegen die echten Einsparungen. Hier sind die häufigsten Kategorien und ihre nativen Entsprechungen:
Datumsformatierung und -manipulation
Bibliothek: date-fns, moment.js, dayjs → Nativ: Intl.DateTimeFormat, Intl.RelativeTimeFormat, Temporal (Stage 3, verfügbar in Chrome 128+/Firefox 132+)
Vorher (mit date-fns):
import { format, formatDistanceToNow } from 'date-fns';
import { de } from 'date-fns/locale';
const formatted = format(new Date(), 'dd.MM.yyyy HH:mm', { locale: de });
const relative = formatDistanceToNow(new Date(2026, 2, 1), { addSuffix: true, locale: de });
Nachher (native Intl-API, Baseline „widely available" seit 2024):
const formatter = new Intl.DateTimeFormat('de-DE', {
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit'
});
const formatted = formatter.format(new Date());
const rtf = new Intl.RelativeTimeFormat('de-DE', { numeric: 'auto' });
const relative = rtf.format(
Math.round((new Date(2026, 2, 1) - Date.now()) / (1000 * 60 * 60 * 24)),
'day'
);
Einsparung: Das Entfernen von date-fns aus einem tree-shaken Bundle spart typischerweise 12-30 KB gzippt, je nachdem, welche Funktionen Sie verwendet haben. Wenn Ihr Projekt noch moment.js nutzt, Glückwunsch, Sie werden zwischen 65 und 230 KB unminifiziert einsparen.
Utility-Funktionen (lodash, underscore)
Bibliothek: lodash-es/debounce, lodash-es/throttle, lodash-es/cloneDeep, lodash-es/merge → Nativ: Vanilla-JavaScript
Die am häufigsten verwendeten lodash-Funktionen haben native Äquivalente in ein oder zwei Zeilen:
// debounce, replaces lodash/debounce
function debounce(fn, ms = 300) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), ms);
};
}
// Deep clone, replaces lodash/cloneDeep (Baseline widely available 2024)
const clone = structuredClone(original);
// Object merging, replaces lodash/merge for shallow cases
const merged = { ...defaults, ...overrides };
// Array chunking, replaces lodash/chunk
function chunk(arr, size) {
return Array.from({ length: Math.ceil(arr.length / size) }, (_, i) =>
arr.slice(i * size, i * size + size)
);
}
structuredClone ist besonders wichtig: Es behandelt zirkuläre Referenzen, Date, Map, Set, RegExp, ArrayBuffer und Blob, Edge Cases, an denen selbstgebaute Clone-Implementierungen scheitern. Es ist seit Anfang 2024 Baseline-„widely available".
Einsparung: Selbst das Importieren einzelner lodash-es-Funktionen summiert sich in einem typischen Projekt auf 15-40 KB. Jede native Ersetzung kostet nichts.
Polyfills und Transpilierung
Bibliothek: core-js, whatwg-fetch, abortcontroller-polyfill → Nativ: in jedem modernen Browser enthalten
Wenn Ihre browserslist- oder @babel/preset-env-Konfiguration so aussieht:
{
"browserslist": "> 0.25%, not dead"
}
Sie polyfillen damit wahrscheinlich Funktionen, die jeder Browser, der dieser Abfrage entspricht, bereits unterstützt. Führen Sie npx browserslist aus, um die tatsächlich aufgelöste Browserliste zu sehen. Prüfen Sie dann jedes Polyfill gegen Baseline.
Noch besser: Verwenden Sie die Baseline-Browserkonfiguration, um Ihre Targets zu aktualisieren:
{
"browserslist": "baseline widely available"
}
Oder für feature-basiertes Targeting mit Vite:
// vite.config.js, Vite 6+ supports Baseline targeting
import { defineConfig } from 'vite';
export default defineConfig({
build: {
target: 'baseline-widely-available' // or 'baseline-2024'
}
});
Einsparung: die dramatischste einzelne Änderung. Teams, die von einer generischen browserslist zu explizitem Baseline-Targeting wechseln, reduzieren ihre Polyfill-Payload typischerweise um 50-120 KB. Ein redaktionelles Tool, das wir auditiert haben, ging von 340 KB auf 210 KB JavaScript zurück, nur durch straffere Browser-Targets und das Entfernen nicht mehr benötigter core-js-Importe.
URL- und Routing-Bibliotheken
Bibliothek: url-parse, qs (für einfache Fälle) → Nativ: URL, URLSearchParams, Baseline „widely available" seit 2020
// Instead of url-parse
const url = new URL('https://example.com/path?key=value');
// Instead of qs for simple query parsing (Baseline widely available)
const params = new URLSearchParams(window.location.search);
const value = params.get('key');
Schritt 3: Baseline-Compliance in Ihrer CI-Pipeline durchsetzen
Einmal zu auditieren ist gut. Regression zu verhindern ist besser. Zwei Ansätze:
Option A: ESLint-Plugin
npm install --save-dev eslint-plugin-compat
// .eslintrc.json
{
"plugins": ["compat"],
"env": {
"browser": true
},
"rules": {
"compat/compat": "warn"
},
"settings": {
"browserslist": ["baseline widely available"]
}
}
Das kennzeichnet jeden API-Aufruf, der in Ihren Ziel-Browsern nicht verfügbar ist, bevor er die Produktion erreicht.
Option B: Baseline-Prüfung zur Build-Zeit mit Vite
// vite.config.js
import { defineConfig } from 'vite';
import baseline from 'vite-plugin-baseline';
export default defineConfig({
plugins: [
baseline({
target: 'widely-available',
// warns on features not yet in baseline, blocks on removed features
violations: 'error'
})
]
});
Schritt 4: Die Auswirkungen messen
Nach dem Ersetzen von Abhängigkeiten durch native Entsprechungen führen Sie Ihre Bundle-Analyse erneut aus:
# Compare before/after bundle sizes
npx source-map-explorer dist/assets/*.js
# Or with Vite
npx vite-bundle-visualizer
Realistische Zahlen aus einem typischen Audit:
Das bedeutet 138-330 KB weniger JavaScript, das der Browser bei jedem Seitenaufruf herunterladen, parsen und ausführen muss. Bei einer 3G-Verbindung (1,5 Mbps effektiv) entspricht das einer 0,7-1,8 Sekunden schnelleren Time-to-Interactive. Bei schnellen Verbindungen sind allein die Einsparungen bei der Parse-Zeit messbar, die Parse-Kosten für JavaScript liegen bei etwa 0,25-0,5 ms pro KB auf einem Mittelklasse-Mobilgerät.
Wenn native APIs nicht ausreichen
Baseline sagt Ihnen, was überall funktioniert. Es sagt nicht immer, was überall gleich funktioniert. Zu beachtende Edge Cases:
Intl.DateTimeFormat-Ausgabeunterschiede: Nachgestellte Leerzeichen und geschützte Leerzeichen variieren zwischen Safari und Chromium. Wenn Sie formatierte Strings in Tests vergleichen, normalisieren Sie Leerzeichen.structuredClone-Einschränkungen: Kann keine Funktionen, DOM-Knoten oder bestimmte Error-Unterklassen klonen. Wenn Ihr Datenmodell solche enthält, benötigen Sie weiterhin eine spezialisierte Bibliothek.Temporal-API: Noch nicht Baseline-„widely available" (erwartet 2026-2027). Wenn SieTemporalspeziell benötigen, brauchen Sie möglicherweise weiterhin ein Polyfill, aber ein deutlich schlankeres.URL-Klasse in Nicht-Browser-Umgebungen: Node.js hatURLeingebaut, aber Edge-Runtimes wie Cloudflare Workers hatten bis vor kurzem Lücken. Verifizieren Sie das für Ihr Deployment-Ziel.
Für Teams, die ältere Browser unterstützen müssen (z. B. Unternehmensumgebungen, die auf Chrome 96 festgelegt sind), passt das Baseline-„widely available"-Target möglicherweise nicht. In solchen Fällen kann ein Team mit Erfahrung in Browser-Kompatibilität Ihnen helfen, die richtigen Grenzen zwischen polyfillten Funktionen und dem Baseline-sicheren Kern zu setzen.
Fünf Best Practices für weniger ausgeliefertes JavaScript
-
Setzen Sie ein explizites Baseline-Browser-Target, verlassen Sie sich nicht auf die Standard-browserslist
> 0.25%, not dead. Schreiben Siebaseline widely availableoderbaseline 2024und überprüfen Sie es alle 6 Monate, während Browser neue Funktionen ausliefern. -
Auditieren Sie, bevor Sie optimieren, führen Sie
npx bundlephobia-depsauf Ihrerpackage.jsonaus. Sortieren Sie nach Gzip-Größe. Gehen Sie zuerst die größten Abhängigkeiten an. Oft machen 3-4 Bibliotheken 70 % der ersetzbaren Bytes aus. -
Ersetzen Sie eine Abhängigkeit pro Sprint, versuchen Sie keine „Big-Bang"-Migration. Tauschen Sie
moment.jsin diesem Sprint, auditieren Sielodashim nächsten Sprint und straffen Sie die browserslist im übernächsten Sprint. Jede Änderung ist unabhängig test- und deploybar. -
Blockieren Sie polyfill-lastige PRs in der CI, die Aufnahme von
eslint-plugin-compatin Ihre Pipeline deckt inkompatible API-Nutzung und unnötige Polyfill-Importe in Pull Requests auf, nicht erst in Produktions-Performance-Reports. -
Messen Sie die Parse-Zeit, nicht nur die Download-Größe, eine 100-KB-JavaScript-Datei kostet weit mehr als ein 100-KB-Bild, weil der Browser sie parsen, kompilieren und ausführen muss. Nutzen Sie den Lighthouse-Audit „Reduce JavaScript execution time", um die realen Kosten dessen zu verfolgen, was Sie ausliefern.
Diese Art von Dependency-Audit fügt sich natürlich in eine breitere Frontend-Performance-Strategie ein. Wenn Ihr Team eine Webanwendung entwickelt oder modernisiert, kostet die frühzeitige Etablierung dieser Standards nur einen Bruchteil der späteren Nachrüstung, und jeder Sprint baut auf einem schlankeren, schnelleren Fundament auf.
Das Fazit
Die Webplattform hat stillschweigend absorbiert, was früher Drittanbieter-Bibliotheken erforderte. Baseline macht diesen Fortschritt messbar und umsetzbar. Ein Dependency-Audit gegen Baseline ist kein Rewrite, es ist das Entfernen von Code, den der Browser heute kostenlos mitliefert. Für die meisten mittelgroßen SaaS-Produkte bedeutet das 150-300 KB weniger JavaScript pro Seitenaufruf, schnellere Time-to-Interactive, weniger transitive Abhängigkeiten und eine kleinere Angriffsfläche in der Lieferkette.
Beginnen Sie mit dem Dependency-Inventar. Rechnen Sie die Zahlen durch. Liefern Sie weniger aus.
Quelle: Wie Baseline Ihnen helfen kann, weniger JavaScript auszuliefern