Servir du code moderne aux navigateurs récents
Évitez de transpiler du JavaScript inutilement : servez du code moderne aux navigateurs récents et un repli aux anciens pour alléger vos bundles.
Faire fonctionner un site sur tous les navigateurs majeurs est un principe fondateur du Web ouvert. Mais dès que l’on veut utiliser des fonctionnalités JavaScript récentes, il faut les transcompiler vers des formats rétrocompatibles pour les navigateurs qui ne les comprennent pas. Cette transpilation a un coût : elle génère généralement plus de code que la version d’origine.
L’idée est donc de ne transpiler que ce qui est nécessaire, et de servir le code moderne, plus léger, aux navigateurs qui le supportent. Pour le SEO, l’intérêt est direct : des bundles plus petits se téléchargent et s’exécutent plus vite, ce qui améliore les performances de chargement, un facteur d’expérience utilisateur suivi par Google ; cette optique complète l’effort plus général pour réduire le coût de démarrage du JavaScript.
Beaucoup de sites transpilent encore leur JavaScript pour des navigateurs qui ont disparu de leur audience depuis longtemps, et alourdissent leurs bundles pour rien. Avant de configurer Babel, je regarde les navigateurs réellement utilisés. Servir du code moderne aux navigateurs récents est un gain de poids gratuit, à condition de cibler juste.
Les navigateurs modernes prennent désormais en charge les fonctionnalités JavaScript nécessaires pour servir du code moderne sans transpilation. Les techniques décrites ici ne sont donc plus systématiquement recommandées. Elles restent toutefois utiles si vous devez encore prendre en charge d’anciens navigateurs incompatibles avec les fonctionnalités JavaScript modernes.
Cibler précisément les navigateurs avec Babel
Babel est l’outil le plus utilisé pour compiler une syntaxe récente vers un code compréhensible par différents navigateurs. Plutôt que d’ajouter des plug-ins un par un, @babel/preset-env regroupe les transformations et les polyfills, et n’inclut que ceux requis par les navigateurs ciblés. C’est un levier d’allègement parmi d’autres, à associer au fractionnement du code JavaScript pour ne livrer que le strict nécessaire.
Le champ targets s’appuie sur browserslist, une configuration partagée entre de nombreux outils. Une valeur comme « >0.25% » demande à Babel de ne couvrir que les navigateurs représentant plus de 0,25 % de l’usage mondial, ce qui évite d’embarquer du code transpilé pour des navigateurs quasi inutilisés.
{
"presets": [
[
"@babel/preset-env",
{
"targets": ">0.25%"
}
]
]
}
Comparer les stratégies de ciblage
Toutes les requêtes de ciblage ne se valent pas. Certaines maintiennent la prise en charge de navigateurs abandonnés et gonflent inutilement vos bundles. Le tableau suivant compare les approches courantes pour vous aider à choisir.
| Réglage | Effet | Recommandation |
|---|---|---|
« >0.25% » |
Cible les navigateurs au-dessus de 0,25 % d’usage mondial |
Approche recommandée dans la plupart des cas |
« last 2 versions » |
Couvre les deux dernières versions de chaque navigateur |
Risque d’inclure des navigateurs abandonnés |
« esmodules »: true |
Cible les navigateurs compatibles avec les modules ES |
Simplifie l’envoi de code moderne uniquement |
« bugfixes »: true |
Convertit la syntaxe défectueuse vers l’équivalent le plus proche |
Réduit le code transformé (Babel 7.10+) |
Servir deux versions avec module et nomodule
Les modules ES sont pris en charge par tous les navigateurs majeurs. Les navigateurs compatibles ignorent les scripts portant l’attribut nomodule, tandis que ceux qui ne le sont pas ignorent les balises avec type= »module ». Vous pouvez donc livrer une version moderne et un repli compilé côte à côte, en cohérence avec une stratégie plus large pour optimiser le chargement des ressources.
Dans l’exemple ci-dessous, les navigateurs récents récupèrent et exécutent main.mjs en ignorant compiled.js ; les anciens font l’inverse. Les scripts de module étant différés par défaut, l’attribut defer est ajouté au script nomodule pour un comportement identique.
<script type="module" src="main.mjs"></script>
<script nomodule src="compiled.js" defer></script>
Cette approche HTML offre des gains de performance, mais certains navigateurs ont tendance à télécharger deux fois les scripts lorsque les versions module et nomodule sont déclarées ensemble. Vérifiez le comportement réel sur vos navigateurs cibles et envisagez les contournements documentés si vous constatez ce double chargement.
À faire
- analyser les navigateurs réels de vos visiteurs
- cibler par part d’usage avec @babel/preset-env
- activer l’option bugfixes
- servir une version module et un repli nomodule
À éviter
- transpiler pour des navigateurs abandonnés
- utiliser « last 2 versions » sans réflexion
- transpiler des fonctionnalités déjà natives
- ignorer le risque de double téléchargement
Points clés à retenir
- Identifier les navigateurs réellement utilisés par votre audience
- Cibler avec @babel/preset-env et browserslist
- Activer l'option bugfixes pour limiter le code transformé
- Combiner type="module" et nomodule pour gérer les deux cas
- Vérifier l'absence de double téléchargement sur vos cibles
Servir du code moderne réduit la taille des bundles pour la majorité des visiteurs.
Quiz : testez vos connaissances
Quiz : testez vos connaissances
-
Pourquoi la transpilation du code récent vers un format rétrocompatible alourdit-elle généralement le bundle ?
- Parce qu'elle duplique systématiquement chaque fichier source en trois exemplaires
- Parce qu'elle empêche toute compression gzip ou Brotli du résultat
- Parce que réécrire une syntaxe récente produit plus de code et ajoute des polyfills
Transpiler une fonctionnalité moderne vers un équivalent ancien génère davantage de lignes et nécessite des polyfills, ce qui augmente mécaniquement la taille du bundle.
-
Comment fonctionne la livraison de deux versions avec les attributs module et nomodule ?
- Tous les navigateurs exécutent les deux versions l'une après l'autre pour plus de sécurité
- Les navigateurs compatibles ES ignorent les scripts nomodule, et les navigateurs incompatibles ignorent les balises type="module"
- Le serveur choisit lui-même la version à envoyer selon l'adresse IP du visiteur
Un navigateur qui gère les modules ES ignore les scripts marqués
nomodule, tandis qu’un navigateur ancien ignore les balisestype="module", ce qui permet de servir une version moderne et un repli. -
Quel intérêt principal y a-t-il à servir du code moderne aux navigateurs récents ?
- Supprimer le besoin de tester les performances sur mobile
- Réduire la taille des bundles pour la majorité des visiteurs
- Garantir le fonctionnement sur des navigateurs déjà abandonnés
Servir directement du code moderne évite les transformations inutiles et allège les bundles pour la plupart des visiteurs, dont les navigateurs comprennent déjà cette syntaxe.
Besoin d'un accompagnement SEO ?
Vos bundles transportent du code inutile pour la plupart de vos visiteurs ? Faites auditer votre chaîne de build et allégez votre JavaScript.