Le framework Nuxt propose deux aides natives, Lazy et ClientOnly, pour contrôler plus finement la performance des sites et applications web ainsi que la manière dont les composants sont compilés et chargés. Ces deux approches ne sont pas les seules possibles, mais elles sont souvent les plus rapides à intégrer, et il arrive qu’on les combine.
Préfixer un composant par Lazy
Il suffit d’ajouter le préfixe Lazy au nom d’un composant, par exemple . Ce préfixe active le code-splitting automatique, c’est-à-dire la découpe du code en plusieurs parties, grâce à des imports dynamiques (defineAsyncComponent).
Le principal effet concerne le poids du bundle, le fichier JavaScript qui regroupe le code de la page. Ce poids est réduit, car le code du composant n’est plus inclus dans le bundle initial : Nuxt l’isole dans un chunk séparé. Un bundle plus léger permet au navigateur de télécharger et d’analyser le JavaScript plus rapidement, ce qui améliore le FCP et le TTI.
Le fonctionnement varie selon la situation du composant. S’il est rendu lors du SSR initial, son chunk est préchargé en parallèle. S’il est masqué par un v-if à l’état initial, son code n’est téléchargé sur le client qu’au moment où la condition passe à true. Le SSR, ou rendu côté serveur, consiste à générer le HTML sur le serveur.
Dans les outils de bundling comme Vite, Webpack ou Rollup, un chunk désigne un fichier contenant une partie du code de l’application ou du site. Il permet de diviser le code pour optimiser le chargement, mais aussi de ne charger certaines fonctionnalités qu’à la demande, et non par défaut.
Encadrer par ClientOnly
Le composant s’utilise en entourant le composant ciblé, comme dans . Il désactive le rendu côté serveur pour la partie du code concernée. Comme son nom l’indique, ce code est destiné exclusivement au client, c’est-à-dire au navigateur.
Dans ce cas, le poids du bundle n’est pas affecté. Le composant reste inclus dans le bundle JavaScript principal, et son code est toujours téléchargé et évalué lors du chargement initial de la page. En revanche, le serveur a moins de travail pour générer le HTML, ce qui apporte un gain léger sur le TTFB, et les erreurs d’hydratation sont évitées lorsque le composant utilise des API du navigateur, comme window ou document.
L’approche présente aussi un inconvénient : le contenu encadré n’existe pas dans le HTML initial. Cela peut provoquer un décalage visuel pendant le rendu côté client, et ce contenu n’est pas indexable par le SEO.
Combiner les deux
Associer Lazy et ClientOnly permet de différer à la fois le SSR et le chargement du JavaScript. Le composant est alors exclu du bundle principal grâce à Lazy, et il n’est pas requis pour le rendu serveur grâce à ClientOnly. Cette combinaison est présentée comme idéale pour les composants lourds, interactifs et non critiques pour le SEO, comme un éditeur WYSIWYG, des graphiques de type Chart.js ou une carte interactive.
Le serveur répond rapidement, la page s’affiche immédiatement avec un bundle minimal, puis le composant charge son chunk séparé en arrière-plan, dans le navigateur. Pour éviter un saut visuel (CLS) le temps que le chunk soit téléchargé et exécuté, il faut utiliser le slot #fallback ou #placeholder de ClientOnly.



