Passage en Production

Avant de mettre en production votre application Next.js, voici quelques recommandations pour garantir la meilleure expérience utilisateur.

Recommandations générales

Mise en cache

Exemples

La mise en cache améliore les temps de réponse et réduit le nombre de requêtes vers des services externes. Next.js ajoute automatiquement des en-têtes de cache aux ressources immuables servies depuis /_next/static, incluant JavaScript, CSS, images statiques et autres médias.

Cache-Control: public, max-age=31536000, immutable

Les en-têtes Cache-Control définis dans next.config.js seront écrasés en production pour garantir une mise en cache efficace des ressources statiques. Si vous avez besoin de revalider le cache d'une page générée statiquement, vous pouvez le faire en définissant revalidate dans la fonction getStaticProps de la page. Si vous utilisez next/image, vous pouvez configurer minimumCacheTTL pour le chargeur d'optimisation d'image par défaut.

Bon à savoir : Lorsque vous exécutez votre application localement avec next dev, vos en-têtes sont écrasés pour empêcher la mise en cache locale.

Cache-Control: no-cache, no-store, max-age=0, must-revalidate

Vous pouvez aussi utiliser des en-têtes de cache dans getServerSideProps et les Routes API pour les réponses dynamiques. Par exemple, en utilisant stale-while-revalidate.

// Cette valeur est considérée comme fraîche pendant dix secondes (s-maxage=10).
// Si une requête est répétée dans les 10 secondes suivantes,
// la valeur précédemment mise en cache sera toujours fraîche. Si la requête est répétée avant 59 secondes,
// la valeur mise en cache sera périmée mais toujours affichée (stale-while-revalidate=59).
//
// En arrière-plan, une requête de revalidation sera faite pour peupler le cache
// avec une nouvelle valeur. Si vous rafraîchissez la page, vous verrez la nouvelle valeur.
export async function getServerSideProps({ req, res }) {
  res.setHeader(
    'Cache-Control',
    'public, s-maxage=10, stale-while-revalidate=59'
  )

  return {
    props: {},
  }
}

Par défaut, les en-têtes Cache-Control seront définis différemment selon la façon dont votre page récupère les données.

  • Si la page utilise getServerSideProps ou getInitialProps, elle utilisera l'en-tête Cache-Control par défaut défini par next start pour empêcher la mise en cache accidentelle de réponses qui ne peuvent pas être mises en cache. Si vous souhaitez un comportement de cache différent avec getServerSideProps, utilisez res.setHeader('Cache-Control', 'valeur_de_votre_choix') dans la fonction comme montré ci-dessus.
  • Si la page utilise getStaticProps, elle aura un en-tête Cache-Control de s-maxage=REVALIDATE_SECONDS, stale-while-revalidate, ou si revalidate n'est pas utilisé, s-maxage=31536000, stale-while-revalidate pour une mise en cache maximale.

Bon à savoir : Votre fournisseur de déploiement doit supporter la mise en cache pour les réponses dynamiques. Si vous auto-hébergez, vous devrez ajouter cette logique vous-même en utilisant un système de stockage clé/valeur comme Redis. Si vous utilisez Vercel, la mise en cache Edge fonctionne sans configuration.

Réduction de la taille JavaScript

Exemples

Pour réduire la quantité de JavaScript envoyée au navigateur, vous pouvez utiliser les outils suivants pour comprendre ce qui est inclus dans chaque bundle JavaScript :

  • Import Cost – Affiche la taille des paquets importés dans VSCode.
  • Package Phobia – Estime le coût d'ajout d'une nouvelle dépendance à votre projet.
  • Bundle Phobia – Analyse l'impact d'une dépendance sur la taille des bundles.
  • Webpack Bundle Analyzer – Visualise la taille des fichiers de sortie webpack avec une carte interactive et zoomable.
  • bundlejs – Un outil en ligne pour bundler et minifier rapidement vos projets, tout en visualisant la taille compressée gzip/brotli, exécuté localement dans votre navigateur.

Chaque fichier dans votre répertoire pages/ sera automatiquement divisé en son propre bundle JavaScript lors de next build. Vous pouvez aussi utiliser l'import dynamique pour charger à la demande des composants et bibliothèques. Par exemple, vous pourriez vouloir reporter le chargement du code de votre modal jusqu'à ce qu'un utilisateur clique sur le bouton d'ouverture.

Journalisation

Exemples

Puisque Next.js s'exécute à la fois côté client et serveur, plusieurs formes de journalisation sont supportées :

  • console.log dans le navigateur
  • stdout sur le serveur

Si vous souhaitez un système de journalisation structuré, nous recommandons Pino. Si vous utilisez Vercel, il existe des intégrations de journalisation pré-construites compatibles avec Next.js.

Gestion des erreurs

Exemples

Lorsqu'une exception non gérée survient, vous pouvez contrôler l'expérience de vos utilisateurs avec la page 500. Nous recommandons de la personnaliser selon votre marque plutôt que d'utiliser le thème par défaut de Next.js.

Vous pouvez aussi journaliser et suivre les exceptions avec un outil comme Sentry. Cet exemple montre comment capturer et reporter des erreurs côté client et serveur, en utilisant le SDK Sentry pour Next.js. Il existe aussi une intégration Sentry pour Vercel.

Performances de chargement

Pour améliorer les performances de chargement, vous devez d'abord déterminer quoi mesurer et comment le mesurer. Core Web Vitals est un bon standard industriel mesurable avec votre propre navigateur. Si vous n'êtes pas familier avec les métriques Core Web Vitals, consultez ce billet de blog et déterminez quelles métriques spécifiques guideront vos optimisations. Idéalement, vous devriez mesurer les performances de chargement dans les environnements suivants :

  • En laboratoire, en utilisant votre propre ordinateur ou un simulateur.
  • Sur le terrain, en utilisant des données réelles de visiteurs.
  • Localement, avec un test exécuté sur votre appareil.
  • À distance, avec un test exécuté dans le cloud.

Une fois capable de mesurer les performances, utilisez les stratégies suivantes pour les améliorer itérativement : appliquez une stratégie, mesurez les nouvelles performances et ajustez jusqu'à ne plus voir d'amélioration significative. Passez ensuite à la stratégie suivante.

  • Utilisez des régions de cache proches de celles où votre base de données ou API est déployée.
  • Comme décrit dans la section mise en cache, utilisez une valeur stale-while-revalidate qui ne surchargera pas votre backend.
  • Utilisez la régénération statique incrémentale pour réduire le nombre de requêtes vers votre backend.
  • Supprimez le JavaScript inutilisé. Consultez ce billet de blog pour comprendre quelles métriques Core Web Vitals sont affectées par la taille des bundles et quelles stratégies utiliser pour la réduire, comme :
    • Configurer votre éditeur de code pour voir les coûts et tailles des imports
    • Trouver des paquets alternatifs plus légers
    • Charger dynamiquement les composants et dépendances