Code splitting et tree shaking : définitions simples

Code splitting et tree shaking : ce que ces deux techniques changent pour la vitesse de votre site, comment elles marchent et les erreurs à éviter.

Bannière « Code splitting et tree shaking » : illustration 3D du sujet sur fond noir

Le code splitting, qu'est-ce que c'est ?

Le code splitting (littéralement « découpage du code ») est une technique qui divise le JavaScript d'un site ou d'une application en plusieurs paquets distincts, chargés seulement quand l'utilisateur en a besoin. Sans lui, un outil de build comme webpack ou Vite assemble tout le code dans un seul fichier, le « bundle ». Le navigateur doit alors télécharger ce bloc entier avant d'afficher quoi que ce soit d'interactif.

Avec le code splitting, ce bundle unique est remplacé par un fichier principal léger et des morceaux secondaires. La page d'accueil charge le strict nécessaire. Le module de paiement, l'espace client ou le configurateur produit ne sont téléchargés que lorsque le visiteur y accède.

D'où vient le terme ?

Le mot vient de l'écosystème JavaScript, où les applications sont devenues assez lourdes pour que tout charger d'un coup pose problème. On parle aussi de « js code splitting » ou de « code splitting react » selon l'outil utilisé, mais le principe reste le même partout : ne livrer au navigateur que ce qui sert tout de suite.

Le tree shaking, qu'est-ce que c'est ?

Le tree shaking (« secouer l'arbre ») est une optimisation qui élimine le code mort au moment de la compilation. L'image est parlante : on secoue l'arbre des dépendances, et les feuilles mortes, c'est-à-dire les fonctions jamais appelées, tombent. Elles n'apparaissent donc pas dans le fichier livré au visiteur.

Prenons une bibliothèque de dates qui propose deux cents fonctions. Votre site n'en utilise que trois. Sans tree shaking, les deux cents partent dans le bundle. Avec, seules les trois utiles sont conservées.

La condition technique : les modules ES

Le tree shaking repose sur la syntaxe import et export des modules JavaScript modernes. Comme ces imports sont statiques, l'outil de build peut savoir à l'avance quelles fonctions de chaque module sont réellement appelées. Avec l'ancienne syntaxe require, cette analyse est beaucoup moins fiable, et le code inutile reste souvent en place.

À quoi servent ces deux techniques pour votre site ?

Pour un dirigeant, la question n'est pas technique : un site lent fait fuir des visiteurs avant qu'ils ne voient votre offre. Moins de JavaScript à télécharger, à analyser et à exécuter, c'est un affichage et une réactivité plus rapides, surtout sur un smartphone milieu de gamme en 4G.

Améliorer les Core Web Vitals

Google mesure l'expérience de chargement à travers les Core Web Vitals. Un gros bundle JavaScript bloque le fil principal du navigateur, ce qui dégrade notamment la réactivité aux clics (l'indicateur INP). Réduire le code du chargement initial est l'un des leviers les plus directs pour améliorer ces scores.

Profiter du cache plus finement

Quand le code est découpé, une modification sur une page n'invalide qu'un seul morceau. Les autres restent dans le cache navigateur des visiteurs réguliers. Avec un bundle unique, la moindre correction oblige tout le monde à retélécharger l'ensemble.

  • Un affichage plus rapide de la première page, celle qui convainc ou fait partir.
  • Moins de données consommées pour les visiteurs sur mobile.
  • Des mises à jour qui pénalisent moins les visiteurs réguliers.
  • Une application qui peut grossir sans ralentir chaque page.

Comment fonctionne le code splitting ?

Il existe trois grandes façons de découper le code. On les combine souvent dans un même projet, selon le type de site.

Le découpage par route

C'est la méthode la plus courante. Chaque page (ou route) de l'application devient un morceau séparé. Les frameworks récents comme Next.js, Nuxt ou SvelteKit le font par défaut : quand le visiteur arrive sur la page Contact, il ne télécharge pas le code de la page Catalogue.

L'import dynamique

Pour aller plus loin, le développeur remplace un import classique par un import dynamique, écrit import('./module'). Cette fonction renvoie une promesse : le module n'est téléchargé qu'à l'instant où le code l'appelle, par exemple au clic sur un bouton. Webpack, Vite ou Rollup détectent ces appels et placent automatiquement le module dans un fichier séparé.

En React, Vue et Angular

Le code splitting en React s'appuie sur React.lazy et le composant Suspense, qui affiche un état d'attente pendant le chargement du morceau. Vue.js propose defineAsyncComponent et des routes chargées à la demande. En Angular, on parle de « lazy loaded routes » via loadComponent ou loadChildren. Côté outillage, le code splitting avec Vite fonctionne sans configuration particulière dès qu'un import dynamique est présent.

Le découpage des dépendances

Enfin, les bibliothèques tierces, qui changent rarement, peuvent être isolées dans un fichier « vendor ». Elles restent ainsi en cache longtemps, pendant que votre propre code évolue. Webpack gère ce cas avec son option splitChunks.

Code splitting vs lazy loading : quelle différence ?

Les deux notions sont souvent confondues. Le code splitting est l'action de découper le code en plusieurs fichiers au moment du build. Le lazy loading, ou chargement différé, désigne le fait de ne charger une ressource qu'au moment où elle devient utile. Le lazy loading s'applique aussi aux images et aux vidéos, pas seulement au JavaScript.

En pratique, l'un ne va pas sans l'autre pour le code. Découper sans différer ne sert à rien, puisque tous les morceaux seraient chargés d'emblée. Différer sans découper est impossible, puisqu'il n'y a qu'un fichier. Le code splitting crée les morceaux, le lazy loading décide quand les télécharger.

Les erreurs courantes à éviter

Mal utilisées, ces techniques peuvent produire l'effet inverse de celui recherché. Voici les pièges que nous rencontrons le plus souvent lors d'audits de performance.

Découper trop finement

Chaque morceau représente une requête réseau. Découper un site en des dizaines de micro-fichiers multiplie les allers-retours et peut ralentir l'ensemble. Le bon découpage suit les usages réels : pages, fonctions lourdes, outils rarement ouverts.

Différer ce qui est visible tout de suite

Charger en différé un composant situé dans la zone above the fold retarde l'affichage de ce que le visiteur voit en premier. C'est exactement l'inverse de l'objectif. Le contenu du haut de page doit faire partie du chargement initial.

Casser le tree shaking sans le savoir

Importer toute une bibliothèque avec import * au lieu des seules fonctions utiles, utiliser des modules au format CommonJS ou mal déclarer les « side effects » dans le package.json empêche l'élimination du code mort. Le bundle grossit sans que personne ne s'en aperçoive.

Oublier de mesurer

Un outil comme webpack-bundle-analyzer ou rollup-plugin-visualizer montre ce que contient réellement chaque fichier. Sans cette vérification, on optimise à l'aveugle. Ces réglages complètent d'ailleurs la minification CSS et JS, qui réduit le poids du code conservé. Lors d'une création de site internet, nous intégrons ces contrôles dès la mise en production.

Questions fréquentes

C'est le découpage d'une application React en plusieurs fichiers JavaScript chargés à la demande. On l'obtient avec React.lazy, qui charge un composant via un import dynamique, et Suspense, qui affiche un indicateur d'attente. Les frameworks comme Next.js découpent en plus chaque page automatiquement.

Le tree shaking supprime le code jamais utilisé : le volume total diminue. Le code splitting répartit le code utile en plusieurs fichiers pour n'en charger qu'une partie au départ. Les deux se complètent et s'activent souvent ensemble dans webpack ou Vite.

Sur un WordPress classique, le JavaScript est surtout fourni par le thème et les extensions, et le code splitting n'y est pas géré comme dans une application moderne. Les gains passent plutôt par la limitation des extensions, le chargement conditionnel des scripts et la mise en cache. Le code splitting prend tout son sens sur un site ou une application développés avec un framework JavaScript.

À lire aussi. Sur le même thème.