Nuxt : quelles optimisations entre Lazy et ClientOnly ?

Astucejavascript

Publié par (membre du staff)
le (63 lectures)

performance Nuxt

Nuxt est un framework que nous apprécions pour son efficacité dans de multiples situations, projets de sites ou d'applications web. Il comporte nativement des aides bien agréables pour contrôler plus finement la performance et la façon dont les composants sont compilés et chargés, notamment Lazy et ClientOnly.

Ce ne sont pas les seules approches possibles, mais souvent les plus rapides à intégrer, et parfois combinées.

Préfixer un composant par Lazy

Exemple :

<LazyMonComposant />

Le préfixe Lazy active le code-splitting automatique via des imports dynamiques (defineAsyncComponent).

  • Poids du bundle : Réduit. Le code du composant n'est plus inclus dans le bundle JavaScript initial. Nuxt le isole dans un chunk séparé.
  • Point fort : Le bundle initial étant plus léger, le navigateur télécharge et analyse le JavaScript plus rapidement (amélioration du FCP et du TTI).
  • Fonctionnement : Si le composant 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, le code n'est téléchargé sur le client qu'au moment où la condition passe à true.

Dans les outils de bundling comme Vite, Webpack, Rollup, un chunk désigne un fichier généré contenant une partie du code de l'application ou du site. Cela permet de :

  • Diviser le code en morceaux pour optimiser le chargement (ex. : code splitting).
  • Charger dynamiquement et de façon asynchrone des parties de l'application, c'est à dire ne charger qu'à la demande certaines fonctionnalités quand on en a réellement besoin, et pas par défaut.

Encadrer par <ClientOnly>

Exemple :

<ClientOnly>
  <MonComposant/>
</ClientOnly>

<ClientOnly> désactive le rendu côté serveur (SSR) pour la partie du code ciblée. Comme son nom l'indique, le code est destiné exclusivement au "client" c'est-à-dire au navigateur.

  • Poids du bundle : Aucun impact. Le composant reste inclus dans le bundle JavaScript principal. Son code est toujours téléchargé et évalué lors de la charge initiale de la page.
  • Point fort : Allège le travail du serveur lors de la génération du HTML (gain léger sur le TTFB) et évite les erreurs d'hydratation si le composant utilise des API navigateur (window, document).
  • Inconvénient : Le contenu n'existe pas dans le HTML initial. Cela peut provoquer un décalage visuel (CLS ou Cumulative Layout Shift) pendant le rendu client, et le contenu encadré n'est pas indexable par le SEO.

Combiner les deux !

Combiner les deux permet de différer à la fois le SSR et le chargement du JavaScript.

  • Poids du bundle : Gain optimal : le composant est exclu du bundle principal (grâce à Lazy) et n'est pas requis pour le rendu serveur (grâce à <ClientOnly>).
  • Cas d'usage idéal : Parfait pour les composants lourds, interactifs et non critiques pour le SEO (ex. : un éditeur WYSIWYG, des graphiques type Chart.js, ou une carte interactive).
  • 👉 Résultat : Le serveur répond vite, la page initiale s'affiche immédiatement avec un bundle minimal, puis le composant charge son chunk séparé en arrière-plan sur 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>.

Comparatif

Approche Poids bundle initial SSR (Serveur) Chargement du JS
Composant standard Inclus Rendu sur le serveur Immédiat
Lazy Exclu (chunk séparé) Rendu si présent au load À la volée (ou préchargé)
<ClientOnly> Inclus Ignoré Évalué au montage client
ClientOnly + Lazy Exclu (chunk séparé) Ignoré Téléchargé au montage client

Rodolphe fait partie de l'agence Alsacréations, contactez-nous pour des projets de qualité !

Commenter

Vous devez être inscrit et identifié pour utiliser cette fonction.

Connectez-vous

Oubli de mot de passe ? Pas de panique, on va le retrouver

Pas encore inscrit ? C'est très simple et gratuit.