Français

Exploitez la puissance de l'instrumentation Next.js pour obtenir des informations approfondies sur les performances de votre application, identifier les goulots d'étranglement et optimiser l'expérience utilisateur. Apprenez à mettre en œuvre efficacement les hooks de surveillance d'application.

Instrumentation Next.js : Hooks de surveillance d'application pour des informations de production

L'instrumentation de Next.js fournit un mécanisme puissant pour observer et mesurer les performances de votre application en production. En tirant parti des hooks de surveillance d'application, vous pouvez obtenir des informations approfondies sur la gestion des requêtes, le rendu côté serveur, la récupération de données et d'autres aspects critiques du comportement de votre application. Cela vous permet d'identifier les goulots d'étranglement, de diagnostiquer les problèmes de performance et d'optimiser votre application pour une meilleure expérience utilisateur. C'est particulièrement important lors du déploiement d'applications Next.js à l'échelle mondiale, où la latence du réseau et les utilisateurs répartis géographiquement peuvent introduire des défis uniques.

Comprendre l'instrumentation de Next.js

La fonctionnalité d'instrumentation dans Next.js vous permet d'enregistrer des hooks qui sont exécutés à différentes étapes du cycle de vie de l'application. Ces hooks peuvent être utilisés pour collecter des métriques, des traces et des logs, qui peuvent ensuite être envoyés à un système de surveillance de la performance des applications (APM) ou à d'autres outils d'observabilité. Cela fournit une vue complète des performances de votre application en temps réel.

Contrairement à la surveillance traditionnelle côté client qui ne capture que l'expérience du navigateur, l'instrumentation de Next.js offre une observabilité à la fois côté client et côté serveur, permettant une vue complète des performances de votre application. C'est essentiel pour comprendre l'impact du rendu côté serveur, des routes d'API et de la récupération de données sur l'expérience utilisateur globale.

Principaux avantages de l'instrumentation

Mettre en place l'instrumentation dans Next.js

Pour activer l'instrumentation dans votre application Next.js, vous devez créer un fichier instrumentation.js (ou instrumentation.ts) à la racine de votre projet. Ce fichier contiendra les hooks que vous souhaitez enregistrer.

Voici un exemple de base d'un fichier instrumentation.ts :

// instrumentation.ts

export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    const { trace } = await import('./utils/tracing');

    trace('registering-tracing');
  }
}

Dans cet exemple, nous importons une fonction trace depuis un fichier ./utils/tracing et l'appelons dans la fonction register. La fonction register est automatiquement appelée par Next.js au démarrage de l'application.

Exécution conditionnelle basée sur le runtime

La variable process.env.NEXT_RUNTIME est cruciale pour déterminer le contexte d'exécution. Elle vous permet d'exécuter du code de manière conditionnelle selon que l'application s'exécute dans un environnement Node.js (pour le rendu côté serveur, les routes d'API, etc.) ou dans un environnement Edge Runtime (pour les fonctions edge). C'est important car certaines bibliothèques ou outils de surveillance peuvent n'être compatibles qu'avec l'un ou l'autre des runtimes.

Par exemple, vous pourriez vouloir utiliser un agent APM spécifique pour les environnements Node.js et un outil différent pour les environnements Edge Runtime. L'utilisation de process.env.NEXT_RUNTIME vous permet de charger les modules appropriés uniquement lorsque cela est nécessaire.

Mise en œuvre des hooks de surveillance d'application

Voyons maintenant quelques exemples de mise en œuvre de hooks de surveillance d'application dans Next.js.

1. Mesurer le temps de traitement des requêtes

Un cas d'utilisation courant de l'instrumentation est de mesurer le temps nécessaire au traitement des requêtes entrantes. Cela peut vous aider à identifier les points de terminaison lents et à optimiser leurs performances.

Voici un exemple de la manière de mesurer le temps de traitement des requêtes en utilisant l'API performance :

// utils/tracing.ts

import { performance } from 'perf_hooks';

export function trace(eventName: string) {
  const start = performance.now();

  return () => {
    const end = performance.now();
    const duration = end - start;

    console.log(`[${eventName}] took ${duration}ms`);
    // Dans une application réelle, vous enverriez ces données à un système APM.
  };
}

Dans le fichier instrumentation.ts :

// instrumentation.ts

export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    const { trace } = await import('./utils/tracing');

    const endTrace = trace('request-handling');

    // Simulate request handling
    await new Promise((resolve) => setTimeout(resolve, 100));

    endTrace();
  }
}

Cet exemple mesure le temps nécessaire au traitement de la requête et affiche la durée dans la console. Dans une application réelle, vous enverriez ces données à un système APM pour une analyse plus approfondie.

2. Surveiller le temps de rendu côté serveur

Le rendu côté serveur (SSR) est une fonctionnalité clé de Next.js, mais il peut aussi être un goulot d'étranglement de performance. Surveiller le temps nécessaire pour rendre les pages sur le serveur est crucial pour garantir une expérience utilisateur rapide.

Vous pouvez utiliser l'instrumentation pour mesurer le temps d'exécution des fonctions getServerSideProps ou getStaticProps. Ces fonctions sont responsables de la récupération des données et de leur préparation pour le rendu sur le serveur.

// pages/index.tsx

import { GetServerSideProps } from 'next';
import { trace } from '../utils/tracing';

interface Props {
  data: string;
}

export const getServerSideProps: GetServerSideProps = async () => {
  const endTrace = trace('getServerSideProps');
  const data = await fetchData();
  endTrace();

  return {
    props: { data },
  };
};

async function fetchData() {
  // Simuler la récupération de données depuis une API externe
  await new Promise((resolve) => setTimeout(resolve, 50));
  return 'Data from API';
}

export default function Home({ data }: Props) {
  return 

{data}

; }

Dans cet exemple, nous utilisons la fonction trace pour mesurer le temps d'exécution de la fonction getServerSideProps. Cela nous permet d'identifier les problèmes de performance dans le processus de récupération des données.

3. Suivre la performance des routes d'API

Les routes d'API de Next.js vous permettent de créer des fonctions serverless qui gèrent les requêtes API. La surveillance des performances de ces routes d'API est essentielle pour garantir un backend réactif.

Vous pouvez utiliser l'instrumentation pour mesurer le temps nécessaire au traitement des requêtes API dans vos routes d'API.

// pages/api/hello.ts

import type { NextApiRequest, NextApiResponse } from 'next'
import { trace } from '../../utils/tracing';

type Data = {
  name: string
}

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const endTrace = trace('api-hello');
  // Simuler un certain travail
  await new Promise((resolve) => setTimeout(resolve, 25));
  endTrace();
  res.status(200).json({ name: 'John Doe' })
}

Cet exemple mesure le temps nécessaire pour traiter la requête API et renvoie une réponse JSON. Cela vous aide à comprendre les performances de votre backend et à identifier les points de terminaison API lents.

4. Surveiller la performance de l'Edge Runtime

L'Edge Runtime de Next.js vous permet de déployer votre application à la périphérie (edge), plus près de vos utilisateurs. Cela peut améliorer considérablement les performances, en particulier pour les applications distribuées à l'échelle mondiale. Cependant, il est important de surveiller les performances de votre application dans l'Edge Runtime pour s'assurer qu'elle fonctionne efficacement.

L'instrumentation peut être utilisée pour surveiller les performances de votre application dans l'Edge Runtime. Cela vous permet d'identifier les problèmes de performance spécifiques à l'environnement Edge Runtime.

Note importante : Tous les outils de surveillance ne prennent pas en charge l'Edge Runtime. Vous devrez peut-être utiliser des outils ou des bibliothèques spécialisés conçus pour l'environnement Edge Runtime.

Par exemple, Vercel fournit des analyses intégrées qui peuvent être utilisées pour surveiller les performances de votre application dans l'Edge Runtime. Vous pouvez également utiliser des outils de surveillance tiers qui prennent en charge l'Edge Runtime, tels que Datadog ou New Relic.

Intégration avec les systèmes APM

Les données collectées par vos hooks d'instrumentation sont plus utiles lorsqu'elles sont envoyées à un système APM (Application Performance Monitoring). Les systèmes APM fournissent des outils pour visualiser, analyser et alerter sur les données de performance. Les systèmes APM populaires incluent :

Les étapes spécifiques pour l'intégration avec un système APM varient en fonction du système que vous choisissez. Cependant, le processus général comprend les étapes suivantes :

  1. Installez l'agent ou le SDK de l'APM dans votre application Next.js.
  2. Configurez l'agent APM avec la clé API ou les identifiants de votre système APM.
  3. Utilisez l'API de l'agent APM pour envoyer des métriques, des traces et des logs depuis vos hooks d'instrumentation.

Exemple d'utilisation d'OpenTelemetry avec Datadog :

OpenTelemetry est un framework d'observabilité open-source qui fournit un moyen standard de collecter et d'exporter des données de télémétrie. Il peut être utilisé pour s'intégrer à une variété de systèmes APM, y compris Datadog.

// utils/tracing.ts

import { trace, context } from '@opentelemetry/api';

const tracer = trace.getTracer('my-app-tracer');

export function traceFunction any>(
  operationName: string,
  fn: T
): T {
  return function tracedFunction(...args: Parameters): ReturnType {
    const span = tracer.startSpan(operationName);
    const ctx = trace.setSpan(context.active(), span);

    try {
      return context.with(ctx, () => fn(...args));
    } finally {
      span.end();
    }
  } as T;
}

Utilisation dans `getServerSideProps` :

// pages/index.tsx

import { GetServerSideProps } from 'next';
import { traceFunction } from '../utils/tracing';

interface Props {
  data: string;
}

async function fetchData() {
  // Simuler la récupération de données depuis une API externe
  await new Promise((resolve) => setTimeout(resolve, 50));
  return 'Data from API';
}

export const getServerSideProps: GetServerSideProps = async () => {
  const tracedFetchData = traceFunction('fetchData', fetchData);
  const data = await tracedFetchData();

  return {
    props: { data },
  };
};

export default function Home({ data }: Props) {
  return 

{data}

; }

Cet exemple simplifié d'OpenTelemetry montre comment envelopper une fonction avec un span de traçage. La configuration et l'installation réelles du SDK OpenTelemetry et de l'agent Datadog sont plus complexes et nécessitent des étapes supplémentaires, notamment la définition de variables d'environnement, la configuration de l'exportateur et l'initialisation du SDK dans votre fichier instrumentation.ts. Consultez la documentation d'OpenTelemetry et de Datadog pour des instructions complètes.

Meilleures pratiques pour l'instrumentation Next.js

Pièges courants et solutions

Conclusion

L'instrumentation de Next.js fournit un mécanisme puissant pour observer et mesurer les performances de votre application en production. En mettant en œuvre des hooks de surveillance d'application, vous pouvez obtenir des informations approfondies sur la gestion des requêtes, le rendu côté serveur, la récupération de données et d'autres aspects critiques du comportement de votre application. Cela vous permet d'identifier les goulots d'étranglement, de diagnostiquer les problèmes de performance et d'optimiser votre application pour une meilleure expérience utilisateur.

En suivant les meilleures pratiques décrites dans ce guide, vous pouvez exploiter efficacement l'instrumentation de Next.js pour améliorer les performances et la fiabilité de vos applications, peu importe où se trouvent vos utilisateurs. N'oubliez pas de choisir le bon système APM pour vos besoins et de surveiller en permanence les performances de votre application pour identifier et résoudre les problèmes de manière proactive.