JavaScript-Verkleinerer

Komprimieren Sie JavaScript-Code, indem Sie Kommentare, Whitespace und unnötige Zeichen entfernen.

Über die JavaScript-Minifizierung

JavaScript ist auf den meisten Webseiten der schwerste Ressourcentyp, und das nicht nur, weil es meist die größte Datei ist. Die Kosten verteilen sich auf fünf Stufen: Download (über das Netzwerk), Parsing (die Engine liest die Bytes und baut einen AST), Kompilierung (V8 oder JavaScriptCore kompiliert den AST zu Bytecode), Ausführung (der Bytecode läuft), und bei späteren Besuchen Warmstart aus dem gecachten Bytecode, falls die Engine ihn aufbewahrt hat. Brotli am CDN-Rand übernimmt die Download-Kosten. Minifizierung hilft auch beim Download, aber sie hilft auch beim Parsing und der Kompilierung auf jedem Gerät, das dein Skript herunterlädt, und auf einem leistungsschwachen Android-Telefon können Parsing und Kompilierung länger dauern als die Netzwerkübertragung. Addy Osmanis Artikel Cost of JavaScript haben wiederholt gezeigt, dass das, was wie ein Netzwerkproblem aussieht, oft ein CPU-Problem ist, und dass die 20-40-prozentige Byte-Reduktion durch Minifizierung sich ziemlich direkt in eingesparte Millisekunden Parsing-Zeit auf dem langen Schwanz der langsamen Geräte übersetzt.

V8's Lazy-Parsing-Optimierung verschiebt das vollständige Parsen jeder Funktion, bis sie tatsächlich aufgerufen wird, was bedeutet, dass ein großes Skript mit vielen ungenutzten Funktionen weniger kostet, als seine Byte-Anzahl vermuten lässt. Chromes HTTP-Cache speichert auch den V8-Bytecode (den "Code Cache"), sodass wiederholte Besuche die Parsing- und Kompilierstufe vollständig überspringen. Nichts davon ändert die Grundgleichung: Kleinere Skripte erreichen den warmen Cache schneller, parsen schneller auf dem kalten Pfad und kompilieren schneller. Minifizierung ist der billigste Ort auf dem gesamten Stack, um Millisekunden zurückzugewinnen.

Die vier (oder fünf) Stufen der JavaScript-Minifizierung

Nicht alle Minifizierer sind gleich, und die Stufe, die du brauchst, hängt von deiner Codebasis ab. Stufe 1: Entfernen von Leerzeichen und Kommentaren. Der einfachste Durchgang, Leerzeichen, Tabs, Zeilenumbrüche und Kommentare // ... / /* ... */ entfernen. Das kann ein Regex-Durchgang sicher leisten (mit Vorsicht bei Strings, Template-Literalen und Regex-Literalen). Typische Reduktion: 20-40% in rohen Bytes. Stufe 2: Symbol-Umbenennung (Mangling). Lokale Variablennamen, Funktionsparameter und (mit Vorsicht) Funktionsnamen werden zu einzelnen Buchstaben umgeschrieben: function calculateTotal(itemList) wird zu function a(b). Das erfordert einen abstrakten Syntaxbaum und eine vollständige Scope-Analyse, um zu wissen, welche Namen sicher umbenannt werden können, globale Namen, Exports, Referenzen auf this-Eigenschaften und alles, was über String-Schlüssel-Zugriff (obj['name']) erreicht wird, muss alles intakt bleiben. Typische zusätzliche Reduktion: 10-25%. Stufe 3: Tote-Code-Eliminierung (Tree Shaking). Statische Analyse auf Modulebene identifiziert Imports und Code-Pfade, die nie ausgeführt werden, und entfernt sie. Erfordert Typinformationen auf Modulebene und ein klares Verständnis von Nebeneffekten. Typische zusätzliche Reduktion: variabel, kann aber bei Bibliotheken, die viele Features ausliefern, enorm sein. Stufe 4: Inlining und Konstantenfaltung. Einfache Ausdrücke wie 2 * 60 * 60 werden zur Build-Zeit zu 7200 ausgewertet; winzige Funktionen, die einmal aufgerufen werden, können in ihren Aufrufer eingebettet werden. Stufe 5: Eigenschafts-Mangling. Die aggressivste Optimierung, auch Objekt-Eigenschaftsnamen werden umgeschrieben. Bricht jeden Code, der String-Schlüssel (obj['name'] vs obj.name) verwendet oder Eigenschaftsnamen als Teil seines öffentlichen Vertrags exponiert. Fast immer Opt-in und fast immer auf spezifische Bezeichner via einer --mangle-props-Regex begrenzt.

Eine kurze Geschichte der JavaScript-Minifizierungswerkzeuge

JSMin (2003). Douglas Crockford, ja, derselbe Crockford, der JSON gefördert hat, schrieb JSMin 2003 in C. Es war ein winziges Single-File-Programm, das grundlegende Leerzeichen- und Kommentar-Entfernung ohne AST, ohne Scope-Analyse und mit einem bewusst konservativen Ansatz für ASI-Randfälle (Automatic Semicolon Insertion) durchführte. Es setzte die Messlatte für "das Einfachste, was funktioniert" und ist der spirituelle Vorfahre jedes regex-basierten JS-Minifizierers seither. YUI Compressor (2007). Yahoos Julien Lecomte kündigte den YUI Compressor am 11. August 2007 an. Er verwendete den Rhino-Tokenizer, um sichere Symbol-Umbenennung durchzuführen, das erste weit verbreitete Java-Werkzeug, das echtes AST-basiertes Mangling für JavaScript durchführte. Closure Compiler (2009). Google nutzte ihn intern seit 2005; sie veröffentlichten ihn am 5. November 2009 unter Apache 2.0 als Open Source. Closure war der aggressivste Optimierer der Ära, typbewusst über JSDoc-Annotationen, mit einem "advanced"-Modus, der Eigenschaftsnamen basierend auf Typinferenz umschreiben konnte. Der Kompromiss war, dass du deinen Code auf Closure-freundliche Weise schreiben musstest; Advanced-Mode-Fehler waren berüchtigt.

UglifyJS (~2010-2012). Mihai Bazons UglifyJS war der erste JavaScript-native Minifizierer, in JS geschrieben, auf Node.js laufend, und er wurde ein Jahrzehnt lang der npm-Standard. UglifyJS 2 fügte Source-Map-Unterstützung und ES5-Features hinzu; UglifyJS 3 folgte mit fortgesetzter ES5-Politur, erhielt aber nie volle ES6+-Unterstützung. Terser (August 2018). Fabricio Matté forkte UglifyJS speziell zu Terser, um ES6+-Unterstützung hinzuzufügen, ohne die seit langem stabile UglifyJS-API zu stören. Terser ist jetzt der Standard-JS-Minifizierer in webpack 5, Rollup, Parcel 1 und den älteren Next.js-Versionen. swc (2017/2019). Donny "kdy1" Chois swc ("Speedy Web Compiler") ist ein Rust-basierter JavaScript/TypeScript-Compiler mit einem eingebauten Minifizierer, der 20-70x schneller als Terser ist. Next.js wechselte seinen Standard-Minifizierer ab Version 12 im Oktober 2021 von Terser zu swc. esbuild (Winter 2019-2020). Evan Wallace, Mitgründer von Figma, veröffentlichte esbuild über die Winterferien 2019-2020. In Go geschrieben, ist es 10-100x schneller als die JavaScript-basierten Bundler der Zeit und bringt seinen eigenen Minifizierer mit. esbuild ist jetzt der zugrundeliegende Minifizierer in Vite, in tsup und in vielen Framework-Templates. Die allgemeine Richtung der letzten fünf Jahre war: Parser geschrieben in einer schnellen Systemsprache (Rust oder Go), AST-basierte Optimierungen, intelligentes ES-Modul-bewusstes Tree-Shaking. Der im Browser eingefügte Regex-Minifizierer wie dieses Werkzeug sitzt am unteren Ende dieser Leiter und erledigt die einfachste Arbeit, die noch nützlich ist.

Source-Maps für minifiziertes JavaScript

Eine Source-Map ist eine JSON-Begleitdatei, die Positionen in der minifizierten Ausgabe auf Positionen in der ursprünglichen Quelle abbildet. Die Source-Map-V3-Spezifikation wurde 2011 von John Lenz (Google) und Nick Fitzgerald (Mozilla) verfasst und im Juni 2024 von TC39 als ECMA-426 übernommen, dasselbe Source-Map-Format gilt sowohl für JavaScript als auch für CSS. Browser konsumieren die Karte über einen abschließenden Kommentar in der minifizierten Datei: //# sourceMappingURL=app.js.map. Wenn DevTools geöffnet ist und die Karte abgerufen wird, zeigt das Sources-Panel die Originalquelle an, wobei Breakpoints, Konsolenfehler und Stack-Traces alle auf sie verweisen. Produktions-Minifizierer (Terser, swc, esbuild, Closure) geben alle auf Anfrage Source-Maps aus. Dieses Werkzeug nicht, für ein In-Browser-One-Shot-Werkzeug, das Text statt eines herunterladbaren Datei-Paares zurückgibt, fügen Source-Maps signifikante Komplexität für marginalen Nutzen hinzu. Die ehrliche Offenlegung ist, dass dieses Werkzeug ein Einwegdurchgang ist; Build-Pipeline-Minifizierer haben ein viel stärkeres Argument für Source-Maps, weil die Originalquellen auf der Festplatte liegen und der Entwickler zur Laufzeit debuggen muss.

Standardeinstellungen moderner Bundler, die meisten haben bereits einen Minifizierer

Wenn du eine moderne Build-Pipeline verwendest, läuft dein Minifizierer bereits. webpack 5 verwendet standardmäßig terser-webpack-plugin mit Terser. Vite verwendet standardmäßig esbuild für die Minifizierung; Lightning CSS für CSS. Parcel verwendet swc. Next.js wechselte in v12 (Oktober 2021) von Terser zu swc und in derselben Version von Babel zu swc für die gesamte Build-Pipeline. Remix, Astro, SvelteKit, Nuxt, Rollup, eigenständiges esbuild, alle bündeln Minifizierung in Produktions-Builds ohne Entwicklerintervention. Das Ergebnis ist, dass für alle, die eine moderne Build-Pipeline verwenden, JS-Minifizierung automatisch mit Optimierungen weit über das hinaus geschieht, was ein Single-File-Regex-Werkzeug leisten kann. Die Fälle, in denen dieser In-Browser-Minifizierer seinen Platz verdient: handgemachte HTML-Seiten mit Inline-<script>-Blöcken; WordPress-Themes, die ohne Node-Toolchain ausgeliefert werden; Static-Site-Generatoren, die keine Minifizierung bündeln; einmalige Snippets, die in ein CMS oder eine E-Mail-Vorlage eingefügt werden; schnelle Experimente, bei denen das Einrichten einer Build-Pipeline länger dauern würde als das Skript selbst.

Ehrlicher Umfang: Was dieses Werkzeug tut und nicht tut

Dieses Werkzeug ist ein regex-basierter Minifizierer, ungefähr 30 Zeilen JavaScript. Es tokenisiert String-Literale, Template-Literale und Regex-Literale zu Platzhaltern, sodass nachfolgende Transformationen ihren Inhalt nicht beschädigen können; entfernt Kommentare // ... und /* ... */; kollabiert Whitespace-Folgen; entfernt Leerzeichen um Interpunktion, die sie nicht braucht; und stellt die tokenisierten Literale wieder her. Typische Ausgabe ist 20-40% kleiner als die Eingabe in rohen Bytes. Was dieses Werkzeug nicht tut und das Produktions-Minifizierer (Terser, swc, esbuild, Closure) handhaben: Es benennt lokale Variablen nicht in einzelne Buchstaben um (kein scope-bewusstes Mangling); es führt keine Tote-Code-Eliminierung oder Tree-Shaking durch; es führt keine Konstantenfaltung oder Ausdrucksvereinfachung durch; es gibt keine Source-Maps aus; es versteht die TypeScript-Syntax nicht (füge nur reines JavaScript ein); es führt kein Tree-Shaking von ES-Modul-Imports durch; es schreibt Eigenschaftsnamen nicht um. Die ehrliche Einordnung: Füge das JavaScript ein, das aus deinem Editor oder deiner Hand kam, erhalte eine entkernte Version zurück, die typischerweise 20-40% kleiner in rohen Bytes ist, und verwende sie als Schnell-Deploy-Artefakt. Für Projekte mit einer Build-Pipeline verwende Terser, swc oder esbuild in dieser Pipeline; die AST-bewussten Optimierungen sind der Unterschied zwischen der 20-40-prozentigen Reduktion dieses Werkzeugs und den 60-80% eines Produktions-Minifizierers.

Die Fallen des Regex-Minifizierers

Ein regex-basierter Durchgang, der die JavaScript-Grammatik nicht versteht, kann Code auf subtile Weise beschädigen. Die klassischen Fallen: Template-Literale verwenden Backticks und können interpolierte Ausdrücke enthalten (`Hello ${name}!`), die wie Kandidaten für Kommentar-Entfernung aussehen, wenn die Regex nicht vorsichtig ist. Regex-Literale wie /^\/\*/g enthalten Schrägstriche, kommentarartige Sequenzen und stringartigen Inhalt; sie falsch zu handhaben verwandelt eine Regex in syntaktisch kaputten Code. Strings, die kommentarartigen Text enthalten (const url = "// example.com"), naive Kommentar-Entfernung würde alles nach dem // entfernen. ASI-Stolperfallen, Automatic Semicolon Insertion ist das JS-Feature, das es dir ermöglicht, Semikola die meiste Zeit wegzulassen, aber es interagiert schlecht mit Whitespace-Entfernung, wenn das nächste Token mit einer Klammer, eckigen Klammer oder einem Operator beginnt ((/regex/), [arr], +1), unvorsichtiges Whitespace-Kollabieren kann "zwei Anweisungen" in "eine Anweisung mit einem Parser-Fehler" verwandeln. Die Abhilfe in diesem Werkzeug ist der Literal-Tokenisierungs-Durchgang, der zuerst läuft und jeden String und jede Regex durch einen eindeutigen Platzhalter ersetzt, die Kommentar+Whitespace-Arbeit auf dem bereinigten Code erledigt und dann die Platzhalter wiederherstellt. Es ist nicht perfekt, aber es deckt die häufigen Fälle ab. Wenn du vermutest, dass der Minifizierer deinen Code gebrochen hat, ist das Erste, was zu prüfen ist, ein Regex-Literal, das eine Schrägstrich-Sequenz enthält, die der Tokenizer übersehen hat.

Privatsphäre: Warum reiner Browser hier wichtig ist

Serverseitige JS-Minifizierer (Online-Werkzeuge, die deinen Code per POST an einen Server senden, ihn dort durch Terser jagen und das Ergebnis zurückgeben) erfordern das Hochladen deiner Quelle. Für gewöhnlichen Bibliothekscode ist das harmlos. Für interne Werkzeuge, unveröffentlichten Produktcode, JavaScript mit Inline-API-Schlüsseln oder Drittanbieter-Service-Anmeldedaten oder jeden Code, der proprietäre Algorithmen oder Geschäftslogik offenbart, ist es das nicht. Ein rein browserbasierter Minifizierer, JavaScript, das in deinem Tab läuft und nach dem ersten Seitenladen nie eine Netzwerkanfrage stellt, umgeht das Problem. Du kannst es überprüfen, indem du den Netzwerk-Tab von DevTools öffnest, den Code einfügst, auf Minifizieren klickst und auf ausgehende Anfragen achtest. Noch besser: Trenne dich nach dem Laden der Seite vom Internet (oder aktiviere den Flugmodus) und das Werkzeug funktioniert weiterhin, was der stärkste empirische Beweis dafür ist, dass nichts hochgeladen wird.

Häufig gestellte Fragen

Wie viel kleiner wird mein Code?

Für handformatierten Code mit Kommentaren und Einrückung erwarte eine Größenreduktion von 20-40% in rohen Bytes. Produktions-Minifizierer (Terser, swc, esbuild) mit vollständigen AST-basierten Optimierungen erreichen 60-80%, die Lücke sind Symbol-Umbenennung, Tote-Code-Eliminierung und Konstantenfaltung, von denen ein reines Regex-Werkzeug nichts sicher tun kann. Nach Brotli-Kompression am CDN-Rand ist die zusätzliche Ersparnis durch Minifizierung bescheidener (5-15% über Brotli auf dem unminifizierten Original hinaus), aber sie ist nicht null und summiert sich im Maßstab.

Wird die minifizierte Ausgabe meinen Code brechen?

Für die überwältigende Mehrheit des Codes nein. Die bekannten Randfälle drehen sich um Regex-Literale mit Schrägstrich-Sequenzen (/foo\/bar/), Template-Literale mit eingebetteten Interpolationen, die mehrere Zeilen umfassen, und Automatic-Semicolon-Insertion-Kontexte, in denen das Entfernen eines Zeilenumbruchs das Parsing ändert. Der Literal-Tokenisierungs-Durchgang des Werkzeugs handhabt die häufigen Fälle, aber wenn dein Code in einem dieser Muster ungewöhnlich stark ist, teste die minifizierte Ausgabe in einem Browser, bevor du sie ausrollst. Für eine Produktions-Build-Pipeline verwende Terser oder swc, sie haben volle AST-Awareness und handhaben diese Fälle korrekt.

Benennt dieses Werkzeug Variablen um?

Nein. Variablen-Mangling, also function calculateTotal(itemList) in function a(b) zu verwandeln, erfordert eine vollständige Scope-Analyse auf einem AST, um zu wissen, welche Namen sicher umbenannt werden können. Ein Regex-Durchgang kann das nicht sicher tun. Für Symbol-Umbenennung verwende Terser, UglifyJS oder swc in einer Build-Pipeline; sie implementieren scope-bewusstes Mangling korrekt. Die 10-25%ige zusätzliche Größenreduktion, die es erzeugt, ist real und für Produktionscode wert.

Kann ich TypeScript einfügen?

Nein, dieses Werkzeug ist ein reiner JavaScript-Minifizierer. TypeScript fügt Typ-Annotationen hinzu (function add(a: number, b: number): number), Interfaces, Enums, Decorators und andere Syntax, die kein gültiges JavaScript ist. Kompiliere dein TypeScript zuerst zu JavaScript mit tsc, swc, esbuild oder Babel und füge dann die JavaScript-Ausgabe hier ein. Die meisten TypeScript-Projekte laufen bereits als Teil des Builds durch einen dieser Compiler, sodass das JavaScript irgendwo existiert.

Sollte ich dies verwenden, wenn ich bereits eine Build-Pipeline habe?

Wahrscheinlich nicht, dein Bundler erledigt das für dich, mit AST-basierten Optimierungen weit über das hinaus, was ein Regex-Werkzeug bieten kann. webpack 5 liefert terser-webpack-plugin mit Terser; Vite verwendet standardmäßig esbuild für JS; Parcel verwendet swc; Next.js verwendet swc seit v12 (Oktober 2021). Dieses Werkzeug ist für die Fälle, die deine Build-Pipeline nicht abdeckt: handgemachte HTML-Seiten, WordPress-Themes ohne Node-Toolchain, Static-Site-Generatoren, die keine Minifizierung bündeln, einmalige Snippets oder schnelle Experimente, bei denen das Einrichten eines Builds länger dauern würde als das Skript selbst.

Werden meine Dateien hochgeladen?

Nein. Der Minifizierer ist JavaScript, das in deinem Browser läuft. Der Code, den du einfügst, überquert nie das Netzwerk, überprüfe es im Netzwerk-Tab von DevTools, während du auf Minifizieren klickst, oder nimm die Seite nach dem Laden offline und bestätige, dass das Werkzeug noch funktioniert. Interne Werkzeuge, unveröffentlichter Produktcode, Skripte mit Inline-API-Schlüsseln oder proprietärer Geschäftslogik bleiben auf deinem Gerät.

Verwandte Tools