Minifieur JavaScript, gratuit

Compressez le code JavaScript en supprimant commentaires, espaces et caractères inutiles.

À propos de la minification JavaScript

JavaScript est le type de ressource le plus lourd sur la plupart des pages web, et pas seulement parce qu'il s'agit du fichier le plus volumineux. Le coût se décompose en cinq étapes : téléchargement (sur le réseau), analyse (le moteur lit les octets et construit un AST), compilation (V8 ou JavaScriptCore compile l'AST en bytecode), exécution (le bytecode s'exécute), et lors des visites suivantes, démarrage à chaud depuis le bytecode mis en cache si le moteur l'a conservé. Brotli en périphérie du CDN gère le coût de téléchargement. La minification aide aussi au téléchargement, mais elle aide également pour l'analyse et la compilation sur chaque appareil qui télécharge votre script, et sur un téléphone Android d'entrée de gamme, l'analyse et la compilation peuvent prendre plus de temps que le transfert réseau. Les articles Cost of JavaScript d'Addy Osmani ont montré à plusieurs reprises que ce qui ressemble à un problème réseau est souvent un problème de processeur, et que la réduction de 20-40% des octets par la minification se traduit assez directement par des millisecondes économisées sur le temps d'analyse pour la longue traîne des appareils lents.

L'optimisation d'analyse paresseuse de V8 reporte l'analyse complète de toute fonction jusqu'à ce qu'elle soit réellement appelée, ce qui signifie qu'un grand script avec de nombreuses fonctions inutilisées coûte moins cher que sa taille en octets ne le suggère. Le cache HTTP de Chrome stocke également le bytecode V8 (le "Code Cache") afin que les visites répétées ignorent entièrement l'étape d'analyse et de compilation. Rien de tout cela ne change l'équation de base : les scripts plus petits atteignent le cache chaud plus rapidement, s'analysent plus rapidement sur le chemin froid et se compilent plus rapidement. La minification est l'endroit le moins cher de toute la pile pour récupérer des millisecondes.

Les quatre (ou cinq) niveaux de minification JavaScript

Tous les minificateurs ne se valent pas, et le niveau dont vous avez besoin dépend de votre base de code. Niveau 1 : suppression des espaces et des commentaires. Le passage le plus simple, supprimer les espaces, tabulations, sauts de ligne et commentaires // ... / /* ... */. C'est ce qu'un passage regex peut faire en toute sécurité (avec précaution autour des chaînes, des littéraux de template et des littéraux regex). Réduction typique : 20-40% en octets bruts. Niveau 2 : renommage de symboles (mangling). Les noms de variables locales, les paramètres de fonction et (avec précaution) les noms de fonction sont réécrits en lettres uniques : function calculateTotal(itemList) devient function a(b). Cela nécessite un arbre syntaxique abstrait et une analyse complète de la portée pour savoir quels noms peuvent être renommés en toute sécurité, les noms globaux, les exports, les références aux propriétés de this, et tout ce qui est atteint via un accès par clé de chaîne (obj['name']) doivent tous rester intacts. Réduction supplémentaire typique : 10-25%. Niveau 3 : élimination de code mort (tree shaking). L'analyse statique au niveau du module identifie les imports et chemins de code qui ne s'exécutent jamais et les supprime. Nécessite des informations de type au niveau du module et une compréhension claire des effets de bord. Réduction supplémentaire typique : variable, mais peut être énorme sur les bibliothèques qui livrent de nombreuses fonctionnalités. Niveau 4 : inlining et pliage de constantes. Les expressions simples comme 2 * 60 * 60 sont évaluées au moment de la construction à 7200 ; les minuscules fonctions appelées une fois peuvent être intégrées dans leur appelant. Niveau 5 : mangling de propriétés. L'optimisation la plus agressive, les noms de propriétés d'objet sont aussi réécrits. Casse tout code qui utilise des clés de chaîne (obj['name'] vs obj.name) ou qui expose des noms de propriétés dans le cadre de son contrat public. Presque toujours opt-in et presque toujours limité à des identifiants spécifiques via une regex --mangle-props.

Une brève histoire des outils de minification JavaScript

JSMin (2003). Douglas Crockford, oui, le même Crockford qui a promu JSON, a écrit JSMin en C en 2003. C'était un minuscule programme à fichier unique qui effectuait une suppression basique d'espaces et de commentaires sans AST, sans analyse de portée, et avec une approche délibérément conservatrice des cas limites d'ASI (Automatic Semicolon Insertion). Il a établi la barre de "la chose la plus simple qui fonctionne" et est l'ancêtre spirituel de tout minificateur JS basé sur regex depuis. YUI Compressor (2007). Julien Lecomte de Yahoo a annoncé YUI Compressor le 11 août 2007. Il utilisait le tokeniseur Rhino pour effectuer un renommage de symboles sécurisé, le premier outil Java largement utilisé à faire un véritable mangling basé sur AST pour JavaScript. Closure Compiler (2009). Google l'utilisait en interne depuis 2005 ; ils l'ont rendu open source sous Apache 2.0 le 5 novembre 2009. Closure était l'optimiseur le plus agressif de l'époque, conscient des types via les annotations JSDoc, avec un mode "advanced" qui pouvait réécrire les noms de propriétés en fonction de l'inférence de types. Le compromis était que vous deviez écrire votre code de manière compatible avec Closure ; les échecs du mode avancé étaient notoires.

UglifyJS (~2010-2012). UglifyJS de Mihai Bazon a été le premier minificateur natif JavaScript, écrit en JS, exécuté sur Node.js, et il est devenu la valeur par défaut npm pendant une décennie. UglifyJS 2 a ajouté la prise en charge des source maps et des fonctionnalités ES5 ; UglifyJS 3 a suivi avec un polissage ES5 continu mais n'a jamais pleinement acquis le support ES6+. Terser (août 2018). Fabricio Matté a forké UglifyJS en Terser spécifiquement pour ajouter le support ES6+ sans perturber l'API UglifyJS stable depuis longtemps. Terser est désormais le minificateur JS par défaut dans webpack 5, Rollup, Parcel 1 et les anciennes versions de Next.js. swc (2017/2019). swc de Donny "kdy1" Choi ("Speedy Web Compiler") est un compilateur JavaScript/TypeScript basé sur Rust avec un minificateur intégré 20-70x plus rapide que Terser. Next.js a basculé son minificateur par défaut de Terser à swc à partir de la version 12 en octobre 2021. esbuild (hiver 2019-2020). Evan Wallace, co-fondateur de Figma, a publié esbuild pendant les vacances d'hiver 2019-2020. Écrit en Go, il est 10-100x plus rapide que les bundlers basés sur JavaScript de l'époque et embarque son propre minificateur. esbuild est désormais le minificateur sous-jacent dans Vite, dans tsup et dans de nombreux modèles de framework. La direction générale au cours des cinq dernières années a été : parseur écrit dans un langage système rapide (Rust ou Go), optimisations basées sur AST, tree shaking intelligent conscient des modules ES. Le minificateur regex collé dans le navigateur, comme cet outil, se situe au bas de cette échelle, en faisant le travail le plus simple qui soit encore utile.

Source maps pour JavaScript minifié

Une source map est un fichier annexe JSON qui mappe les positions dans la sortie minifiée vers les positions dans la source originale. La spécification Source Map V3 a été rédigée par John Lenz (Google) et Nick Fitzgerald (Mozilla) en 2011, et a été adoptée par TC39 sous le nom d'ECMA-426 en juin 2024, le même format de source map s'applique à la fois à JavaScript et CSS. Les navigateurs consomment la carte via un commentaire de fin dans le fichier minifié : //# sourceMappingURL=app.js.map. Lorsque DevTools est ouvert et que la carte est récupérée, le panneau Sources affiche la source originale, avec les points d'arrêt, les erreurs de console et les traces de pile se référant tous à elle. Les minificateurs de production (Terser, swc, esbuild, Closure) émettent tous des source maps à la demande. Cet outil non, pour un outil one-shot dans le navigateur qui renvoie du texte plutôt qu'une paire de fichiers téléchargeables, les source maps ajoutent une complexité significative pour un bénéfice marginal. La divulgation honnête est que cet outil est un passage unidirectionnel ; les minificateurs de pipeline de build ont un argument bien plus fort pour les source maps car les sources originales se trouvent sur disque et le développeur doit déboguer à l'exécution.

Paramètres par défaut des bundlers modernes, la plupart des gens ont déjà un minificateur

Si vous utilisez un pipeline de build moderne, votre minificateur est déjà en cours d'exécution. webpack 5 utilise terser-webpack-plugin avec Terser par défaut. Vite utilise esbuild pour la minification par défaut ; Lightning CSS pour le CSS. Parcel utilise swc. Next.js est passé de Terser à swc en v12 (octobre 2021), et de Babel à swc pour l'ensemble du pipeline de build dans la même version. Remix, Astro, SvelteKit, Nuxt, Rollup, esbuild autonome, tous intègrent la minification dans les builds de production sans intervention du développeur. Le résultat est que pour quiconque utilise un pipeline de build moderne, la minification JS se produit automatiquement avec des optimisations bien au-delà de ce qu'un outil regex à fichier unique peut faire. Les cas où ce minificateur dans le navigateur gagne sa place : pages HTML faites main avec des blocs <script> inline ; thèmes WordPress livrés sans chaîne d'outils Node ; générateurs de sites statiques qui n'intègrent pas la minification ; snippets ponctuels collés dans un CMS ou un modèle d'e-mail ; expériences rapides où la mise en place d'un pipeline de build prendrait plus de temps que le script lui-même.

Périmètre honnête : ce que cet outil fait et ne fait pas

Cet outil est un minificateur basé sur regex, environ 30 lignes de JavaScript. Il tokenise les littéraux de chaîne, les littéraux de template et les littéraux regex en placeholders afin que les transformations ultérieures ne puissent pas corrompre leur contenu ; supprime les commentaires // ... et /* ... */ ; réduit les séquences d'espaces ; supprime les espaces autour de la ponctuation qui n'en a pas besoin ; et restaure les littéraux tokenisés. La sortie typique est 20-40% plus petite que l'entrée en octets bruts. Ce que cet outil ne fait pas, et que gèrent les minificateurs de production (Terser, swc, esbuild, Closure) : il ne renomme pas les variables locales en lettres uniques (pas de mangling conscient de la portée) ; il n'effectue pas d'élimination de code mort ni de tree-shaking ; il n'effectue pas de pliage de constantes ni de simplification d'expression ; il n'émet pas de source maps ; il ne comprend pas la syntaxe TypeScript (ne collez que du JavaScript pur) ; il ne tree-shake pas les imports de modules ES ; il ne réécrit pas les noms de propriétés. Le cadrage honnête : collez le JavaScript sorti de votre éditeur ou de votre main, récupérez une version dépouillée typiquement 20-40% plus petite en octets bruts, et utilisez-la comme artefact de déploiement rapide. Pour les projets ayant un pipeline de build, utilisez Terser, swc ou esbuild dans ce pipeline ; les optimisations conscientes de l'AST sont la différence entre la réduction de 20-40% de cet outil et les 60-80% d'un minificateur de production.

Les pièges du minificateur regex

Un passage basé sur regex qui ne comprend pas la grammaire JavaScript peut corrompre le code de manière subtile. Les pièges classiques : les littéraux de template utilisent des backticks et peuvent contenir des expressions interpolées (`Hello ${name}!`) qui ressemblent à des candidats à la suppression de commentaires si la regex n'est pas prudente. Les littéraux regex comme /^\/\*/g contiennent des barres obliques, des séquences de type commentaire et du contenu de type chaîne ; les mal gérer transforme une regex en code syntaxiquement cassé. Les chaînes contenant du texte de type commentaire (const url = "// example.com"), une suppression naïve des commentaires supprimerait tout après le //. Les pièges ASI, l'Automatic Semicolon Insertion est la fonctionnalité JS qui vous permet d'omettre les points-virgules la plupart du temps, mais elle interagit mal avec le stripping d'espaces lorsque le token suivant commence par une parenthèse, un crochet ou un opérateur ((/regex/), [arr], +1), une réduction d'espaces imprudente peut transformer "deux instructions" en "une instruction avec une erreur d'analyse". L'atténuation dans cet outil est le passage de tokenisation des littéraux qui s'exécute en premier, remplaçant chaque chaîne et regex par un placeholder unique, faisant le travail de commentaire+espaces sur le code nettoyé, puis restaurant les placeholders. Ce n'est pas parfait, mais cela couvre les cas courants. Si vous soupçonnez que le minificateur a cassé votre code, la première chose à vérifier est un littéral regex contenant une séquence de barre oblique manquée par le tokeniseur.

Confidentialité : pourquoi le tout-navigateur compte ici

Les minificateurs JS côté serveur (outils en ligne qui envoient votre code en POST vers un serveur, le passent par Terser là-bas et renvoient le résultat) exigent le téléversement de votre source. Pour du code de bibliothèque ordinaire, c'est sans danger. Pour des outils internes, du code produit non publié, du JavaScript contenant des clés API en ligne ou des identifiants de services tiers, ou tout code qui révèle des algorithmes propriétaires ou de la logique métier, ce ne l'est pas. Un minificateur purement navigateur, du JavaScript s'exécutant dans votre onglet qui ne fait aucune requête réseau après le chargement initial de la page, contourne le problème. Vous pouvez vérifier en ouvrant l'onglet Réseau de DevTools, en collant le code, en cliquant sur Minifier et en surveillant toute requête sortante. Mieux encore, déconnectez-vous d'Internet (ou activez le mode avion) après le chargement de la page et l'outil fonctionnera toujours, ce qui est la preuve empirique la plus solide que rien n'est téléversé.

Questions fréquentes

De combien mon code sera-t-il plus petit ?

Pour du code formaté à la main avec commentaires et indentation, attendez-vous à une réduction de taille de 20-40% en octets bruts. Les minificateurs de production (Terser, swc, esbuild) avec optimisations AST complètes atteignent 60-80%, l'écart vient du renommage de symboles, de l'élimination de code mort et du pliage de constantes, dont rien ne peut être fait en toute sécurité par un outil regex uniquement. Après compression Brotli en périphérie du CDN, l'économie supplémentaire de la minification est plus modeste (5-15% au-delà de Brotli sur l'original non minifié) mais elle n'est pas nulle, et à l'échelle, cela s'additionne.

La sortie minifiée cassera-t-elle mon code ?

Pour la grande majorité du code, non. Les cas limites connus concernent les littéraux regex avec des séquences de barre oblique (/foo\/bar/), les littéraux de template avec des interpolations intégrées s'étendant sur plusieurs lignes, et les contextes d'Automatic Semicolon Insertion où la suppression d'un saut de ligne change l'analyse. Le passage de tokenisation des littéraux de l'outil gère les cas courants, mais si votre code est exceptionnellement chargé en l'un de ces patterns, testez la sortie minifiée dans un navigateur avant de déployer. Pour un pipeline de build de production, utilisez Terser ou swc, ils ont une conscience AST complète et gèrent ces cas correctement.

Cet outil renomme-t-il les variables ?

Non. Le mangling de variables, transformer function calculateTotal(itemList) en function a(b), nécessite une analyse complète de la portée sur un AST pour savoir quels noms peuvent être renommés en toute sécurité. Un passage regex ne peut pas faire cela en toute sécurité. Pour le renommage de symboles, utilisez Terser, UglifyJS ou swc dans un pipeline de build ; ils implémentent correctement le mangling conscient de la portée. La réduction de taille supplémentaire de 10-25% qu'il produit est réelle et vaut la peine d'être faite pour le code de production.

Puis-je coller du TypeScript ?

Non, cet outil est un minificateur JavaScript uniquement. TypeScript ajoute des annotations de type (function add(a: number, b: number): number), des interfaces, des enums, des décorateurs et d'autres syntaxes qui ne sont pas du JavaScript valide. Compilez d'abord votre TypeScript en JavaScript avec tsc, swc, esbuild ou Babel, puis collez la sortie JavaScript ici. La plupart des projets TypeScript passent déjà par l'un de ces compilateurs dans le cadre de la construction, donc le JavaScript existe quelque part.

Devrais-je utiliser ceci si j'ai déjà un pipeline de build ?

Probablement pas, votre bundler le fait pour vous, avec des optimisations basées sur AST bien au-delà de ce qu'un outil regex peut offrir. webpack 5 livre terser-webpack-plugin avec Terser ; Vite utilise esbuild pour JS par défaut ; Parcel utilise swc ; Next.js utilise swc depuis v12 (octobre 2021). Cet outil est pour les cas que votre pipeline de build ne couvre pas : pages HTML faites main, thèmes WordPress livrés sans chaîne d'outils Node, générateurs de sites statiques qui n'intègrent pas la minification, snippets ponctuels ou expériences rapides où la mise en place d'un build prendrait plus de temps que le script lui-même.

Mes fichiers sont-ils téléversés ?

Non. Le minificateur est du JavaScript s'exécutant dans votre navigateur. Le code que vous collez ne traverse jamais le réseau, vérifiez dans l'onglet Réseau de DevTools pendant que vous cliquez sur Minifier, ou mettez la page hors ligne après son chargement et confirmez que l'outil fonctionne toujours. Les outils internes, le code produit non publié, les scripts contenant des clés API en ligne ou de la logique métier propriétaire restent sur votre appareil.

Outils associés