Pourquoi vos pages mettent du temps à charger ? Le code splitting est la réponse
Vous avez probablement déjà visité un site où le premier écran mettait plusieurs secondes à s’afficher. Ce ralentissement est souvent dû à un bundle JavaScript trop volumineux. Le code splitting, ou découpage de code, est une technique qui consiste à diviser votre code en plusieurs fichiers chargés à la demande. Au lieu de télécharger l’intégralité du code JavaScript dès le départ, seules les parties nécessaires au rendu initial sont envoyées. Le reste est chargé plus tard, lorsque l’utilisateur en a besoin. Résultat : un chargement initial plus rapide, une meilleure expérience utilisateur et un meilleur score SEO.
Comprendre le code splitting en profondeur
Définition et principe de base
Le code splitting est une fonctionnalité offerte par les bundlers modernes comme Webpack, Parcel ou Vite. Elle permet de créer plusieurs bundles plutôt qu’un seul fichier géant. Ces bundles sont ensuite chargés dynamiquement en fonction de la navigation de l’utilisateur. Par exemple, une application de commerce électronique peut charger le code de la page d’accueil immédiatement, puis charger le code du panier uniquement lorsque l’utilisateur clique sur le bouton “Voir le panier”.
Pourquoi le code splitting est-il essentiel aujourd’hui ?
Les applications web modernes utilisent de nombreuses bibliothèques et frameworks. Sans code splitting, le bundle peut atteindre plusieurs mégaoctets, ce qui pénalise le temps de chargement, surtout sur les connexions mobiles. Google utilise le temps d’interactivité (Time to Interactive) comme facteur de ranking. Un site lent sera donc moins bien référencé. De plus, les utilisateurs s’attendent à des pages qui se chargent en moins de deux secondes. Le code splitting est donc un levier majeur pour satisfaire à la fois les utilisateurs et les moteurs de recherche.
Les différentes approches du code splitting
Découpage au niveau des points d’entrée
Cette méthode consiste à séparer manuellement le code en fonction des différentes pages ou sections de votre application. Par exemple, dans une application React, vous pouvez avoir un point d’entrée pour la page d’accueil, un autre pour la page de connexion, etc. C’est simple à mettre en œuvre, mais cela demande une certaine organisation.
Découpage dynamique avec import()
La méthode la plus courante et la plus flexible est l’utilisation de l’importation dynamique avec la syntaxe import(). Elle permet de charger un module à la demande, lorsque cela est nécessaire. Voici un exemple en JavaScript natif :
button.addEventListener('click', () => {
import('./module-lourd.js').then(module => {
module.faireQuelqueChose();
});
});
Cette approche est supportée par la plupart des bundlers et des navigateurs modernes.
Découpage avec React.lazy et Suspense
Pour les applications React, React.lazy permet de charger un composant uniquement lorsqu’il est rendu. Il doit être enveloppé dans un composant Suspense qui affiche un fallback pendant le chargement. Exemple :
const MonComposant = React.lazy(() => import('./MonComposant'));
function App() {
return (
<Suspense fallback={<div>Chargement...</div>}>
<MonComposant />
</Suspense>
);
}
Découpage avec Vue.js et Async Components
Dans Vue.js, vous pouvez définir un composant asynchrone en utilisant une fonction d’importation dynamique :
Vue.component('mon-composant', () => import('./MonComposant.vue'));
Ou avec Vue Router pour charger les routes à la demande.
Comment implémenter le code splitting dans vos projets
Étape 1 : Analyser votre bundle actuel
Avant de découper, il faut savoir ce qui prend de la place. Utilisez des outils comme Webpack Bundle Analyzer ou source-map-explorer pour visualiser la composition de votre bundle. Identifiez les modules lourds ou rarement utilisés.
Étape 2 : Choisir les points de découpage
Posez-vous les questions : quels composants ou pages ne sont pas nécessaires immédiatement ? Par exemple, un éditeur de texte riche, une bibliothèque de graphiques, ou une page de paramètres rarement visitée sont de bons candidats.
Étape 3 : Implémenter les importations dynamiques
Remplacez les importations statiques par des dynamiques pour les modules identifiés. Testez que le chargement se fait correctement et que l’expérience utilisateur reste fluide (affichez un indicateur de chargement si nécessaire).
Étape 4 : Configurer votre bundler
Webpack, par exemple, supporte nativement le code splitting via les importations dynamiques. Vérifiez que votre configuration n’empêche pas le découpage (par exemple, évitez de définir optimization.splitChunks de manière trop restrictive).
Bonnes pratiques et pièges à éviter
À faire
- Découper par route : c’est le cas d’usage le plus courant et le plus efficace.
- Utiliser le lazy loading pour les images et les composants lourds.
- Précharger les bundles critiques avec
<link rel="preload">pour les ressources nécessaires au rendu initial. - Mesurer l’impact avec Lighthouse ou WebPageTest pour valider les gains.
À éviter
- Ne pas découper trop finement : trop de petits bundles augmentent le nombre de requêtes HTTP et peuvent dégrader les performances.
- Oublier le fallback : si vous utilisez React.lazy, enveloppez toujours avec Suspense pour éviter une erreur en cas d’échec de chargement.
- Ignorer les dépendances communes : Webpack peut extraire les modules partagés dans un chunk séparé. Utilisez l’option
splitChunkspour optimiser le cache.
Cas pratiques : code splitting dans différents frameworks
React avec React Router
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Home = React.lazy(() => import('./routes/Home'));
const About = React.lazy(() => import('./routes/About'));
function App() {
return (
<Router>
<Suspense fallback={<div>Chargement...</div>}>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</Switch>
</Suspense>
</Router>
);
}
Vue.js avec Vue Router
const routes = [
{
path: '/',
component: () => import('./views/Home.vue')
},
{
path: '/about',
component: () => import('./views/About.vue')
}
];
Angular avec loadChildren
const routes: Routes = [
{ path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) }
];
Questions fréquentes sur le code splitting
Le code splitting est-il compatible avec le SEO ?
Oui, car il améliore le temps de chargement initial, ce qui est un facteur de ranking. Cependant, assurez-vous que le contenu important est chargé dans le bundle initial pour que Googlebot puisse l’indexer.
Faut-il découper le code pour les petits sites ?
Si votre bundle fait moins de 50 Ko, le code splitting n’est pas nécessaire. Au-delà de 100-200 Ko, il devient intéressant.
Quel est l’impact sur le cache navigateur ?
Le code splitting peut améliorer le cache : si vous mettez à jour un seul module, seul le chunk correspondant est invalidé, les autres restent en cache.
Le code splitting fonctionne-t-il avec les bibliothèques tierces ?
Oui, vous pouvez découper les bibliothèques lourdes comme Moment.js ou Lodash en les important dynamiquement uniquement là où elles sont utilisées.
Checklist pour implémenter le code splitting
- Analyser la taille du bundle avec un outil de visualisation.
- Identifier les routes ou composants rarement utilisés.
- Implémenter les importations dynamiques (React.lazy, Vue async components, etc.).
- Ajouter un indicateur de chargement (spinner, skeleton).
- Tester avec Lighthouse pour vérifier l’amélioration du Time to Interactive.
- Vérifier que le contenu critique est chargé dans le bundle initial.
- Configurer le cache des chunks avec des hashs de contenu.
- Surveiller les performances en production avec des outils comme Sentry ou New Relic.
Pour aller plus loin : combiner code splitting et autres optimisations
Le code splitting n’est qu’une pièce du puzzle. Pour des performances optimales, combinez-le avec :
- La minification et la compression (gzip, Brotli).
- Le tree shaking pour éliminer le code mort.
- Le lazy loading des images et des vidéos.
- L’utilisation d’un CDN pour servir vos chunks.
- La mise en cache des ressources statiques.
En adoptant ces bonnes pratiques, vous offrirez une expérience utilisateur rapide et fluide, tout en améliorant votre référencement naturel. Le code splitting est désormais une technique incontournable pour tout développeur web soucieux de la performance.
Photo by Kit (formerly ConvertKit) on Unsplash

6 Comments
Merci pour cet article très clair ! J’utilise React et je me demandais : est-ce que React.lazy fonctionne aussi avec Next.js ou est-ce réservé à create-react-app ?
React.lazy fonctionne avec Next.js, mais Next.js propose également son propre système de chargement dynamique avec `next/dynamic`. En général, il est recommandé d’utiliser `next/dynamic` pour les pages Next.js car il gère mieux le rendu côté serveur. Mais React.lazy reste utilisable pour des composants purement côté client.
Je viens de mettre en place le code splitting sur mon site avec Webpack, mais je remarque que certains petits modules sont chargés séparément, ce qui multiplie les requêtes HTTP. Est-ce que ça ne risque pas de dégrader les performances ?
Bonne question ! En effet, trop de petits bundles peuvent augmenter le nombre de requêtes et nuire aux performances. Il faut trouver un équilibre. Vous pouvez utiliser l’option `splitChunks` de Webpack pour regrouper les petits modules réutilisés dans un chunk commun. L’idéal est d’avoir des chunks de taille raisonnable (quelques dizaines à centaines de Ko) et de limiter le nombre de requêtes initiales.
Super guide, je comprends mieux l’importance du code splitting pour le SEO. Une question : est-ce que le code splitting a un impact sur le référencement des pages qui chargent du contenu dynamiquement (comme un panier) ? Google indexe-t-il bien ce contenu ?
Bon point ! Google indexe généralement le contenu statique chargé initialement. Pour le contenu chargé dynamiquement (comme un panier), le référencement peut être affecté si le contenu n’est pas présent dans le HTML initial. Pour le SEO, il est conseillé d’utiliser le rendu côté serveur (SSR) ou le pré-rendu pour les parties critiques. Le code splitting reste bénéfique pour l’expérience utilisateur, mais pour le contenu indexable, mieux vaut le charger de manière synchrone ou via SSR.