Optimisation des polices et images

Dans le chapitre précédent, vous avez appris à styliser votre application Next.js. Continuons à travailler sur votre page d'accueil en ajoutant une police personnalisée et une image hero.

Pourquoi optimiser les polices ?

Les polices jouent un rôle important dans le design d'un site web, mais l'utilisation de polices personnalisées dans votre projet peut affecter les performances si les fichiers de police doivent être récupérés et chargés.

Le Décalage Cumulatif de Mise en Page (CLS) est une métrique utilisée par Google pour évaluer les performances et l'expérience utilisateur d'un site web. Avec les polices, le décalage de mise en page se produit lorsque le navigateur affiche initialement le texte dans une police de secours ou système, puis le remplace par une police personnalisée une fois qu'elle est chargée. Ce remplacement peut entraîner des changements de taille, d'espacement ou de mise en page du texte, déplaçant les éléments autour.

Maquette d'interface montrant le chargement initial d'une page, suivi d'un décalage de mise en page lors du chargement de la police personnalisée.

Next.js optimise automatiquement les polices dans l'application lorsque vous utilisez le module next/font. Il télécharge les fichiers de police au moment de la construction et les héberge avec vos autres ressources statiques. Cela signifie qu'aucune requête réseau supplémentaire n'est nécessaire pour les polices lorsqu'un utilisateur visite votre application, ce qui pourrait impacter les performances.

Ajout d'une police principale

Ajoutons une police Google personnalisée à votre application pour voir comment cela fonctionne.

Dans votre dossier /app/ui, créez un nouveau fichier appelé fonts.ts. Vous utiliserez ce fichier pour conserver les polices qui seront utilisées dans toute votre application.

Importez la police Inter depuis le module next/font/google - ce sera votre police principale. Ensuite, spécifiez le sous-ensemble que vous souhaitez charger. Dans ce cas, 'latin' :

/app/ui/fonts.ts
import { Inter } from 'next/font/google';
 
export const inter = Inter({ subsets: ['latin'] });

Enfin, ajoutez la police à l'élément <body> dans /app/layout.tsx :

/app/layout.tsx
import '@/app/ui/global.css';
import { inter } from '@/app/ui/fonts';
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={`${inter.className} antialiased`}>{children}</body>
    </html>
  );
}

En ajoutant Inter à l'élément <body>, la police sera appliquée dans toute votre application. Ici, vous ajoutez également la classe Tailwind antialiased qui lisse la police. Il n'est pas nécessaire d'utiliser cette classe, mais elle apporte une touche agréable.

Ouvrez votre navigateur, accédez aux outils de développement et sélectionnez l'élément body. Vous devriez voir que Inter et Inter_Fallback sont maintenant appliqués dans les styles.

Exercice : Ajout d'une police secondaire

Vous pouvez également ajouter des polices à des éléments spécifiques de votre application.

À vous de jouer ! Dans votre fichier fonts.ts, importez une police secondaire appelée Lusitana et passez-la à l'élément <p> dans votre fichier /app/page.tsx. En plus de spécifier un sous-ensemble comme précédemment, vous devez également spécifier différentes épaisseurs de police. Par exemple, 400 (normal) et 700 (gras).

Une fois prêt, développez l'extrait de code ci-dessous pour voir la solution.

Indices :

Enfin, le composant <AcmeLogo /> utilise également Lusitana. Il était commenté pour éviter les erreurs, vous pouvez maintenant le décommenter :

/app/page.tsx
// ...
 
export default function Page() {
  return (
    <main className="flex min-h-screen flex-col p-6">
      <div className="flex h-20 shrink-0 items-end rounded-lg bg-blue-500 p-4 md:h-52">
        <AcmeLogo />
        {/* ... */}
      </div>
    </main>
  );
}

Super, vous avez ajouté deux polices personnalisées à votre application ! Passons maintenant à l'ajout d'une image hero sur la page d'accueil.

Pourquoi optimiser les images ?

Next.js peut servir des ressources statiques, comme des images, dans le dossier de premier niveau /public. Les fichiers à l'intérieur de /public peuvent être référencés dans votre application.

Avec du HTML classique, vous ajouteriez une image comme suit :

<img
  src="/hero.png"
  alt="Captures d'écran du projet de tableau de bord montrant la version desktop"
/>

Cependant, cela signifie que vous devez manuellement :

  • Vous assurer que votre image est réactive sur différentes tailles d'écran.
  • Spécifier les tailles d'image pour différents appareils.
  • Empêcher le décalage de mise en page lors du chargement des images.
  • Charger de manière différée les images hors de la vue de l'utilisateur.

L'optimisation des images est un vaste sujet dans le développement web qui pourrait être considéré comme une spécialité en soi. Au lieu d'implémenter manuellement ces optimisations, vous pouvez utiliser le composant next/image pour optimiser automatiquement vos images.

Le composant <Image>

Le composant <Image> est une extension de la balise HTML <img>, et offre une optimisation automatique des images, comme :

  • Empêcher automatiquement le décalage de mise en page lors du chargement des images.
  • Redimensionner les images pour éviter d'envoyer de grandes images à des appareils avec une fenêtre plus petite.
  • Charger les images de manière différée par défaut (les images se chargent lorsqu'elles entrent dans la vue).
  • Servir les images dans des formats modernes, comme WebP et AVIF, lorsque le navigateur les prend en charge.

Ajout de l'image hero desktop

Utilisons le composant <Image>. Si vous regardez dans le dossier /public, vous verrez qu'il y a deux images : hero-desktop.png et hero-mobile.png. Ces deux images sont complètement différentes et seront affichées selon que l'appareil de l'utilisateur est un desktop ou un mobile.

Dans votre fichier /app/page.tsx, importez le composant depuis next/image. Ensuite, ajoutez l'image sous le commentaire :

/app/page.tsx
import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
import { lusitana } from '@/app/ui/fonts';
import Image from 'next/image';
 
export default function Page() {
  return (
    // ...
    <div className="flex items-center justify-center p-6 md:w-3/5 md:px-28 md:py-12">
      {/* Ajoutez les images hero ici */}
      <Image
        src="/hero-desktop.png"
        width={1000}
        height={760}
        className="hidden md:block"
        alt="Captures d'écran du projet de tableau de bord montrant la version desktop"
      />
    </div>
    //...
  );
}

Ici, vous définissez la width à 1000 et la height à 760 pixels. Il est recommandé de définir la width et la height de vos images pour éviter le décalage de mise en page, ces valeurs doivent avoir un rapport d'aspect identique à celui de l'image source. Ces valeurs ne correspondent pas à la taille d'affichage de l'image, mais à la taille réelle du fichier image utilisée pour comprendre le rapport d'aspect.

Vous remarquerez également la classe hidden pour supprimer l'image du DOM sur les écrans mobiles, et md:block pour afficher l'image sur les écrans desktop.

Voici à quoi devrait ressembler votre page d'accueil maintenant :

Page d'accueil stylisée avec une police personnalisée et une image hero

Exercice : Ajout de l'image hero mobile

À vous de jouer ! Sous l'image que vous venez d'ajouter, ajoutez un autre composant <Image> pour hero-mobile.png.

  • L'image doit avoir une width de 560 et une height de 620 pixels.
  • Elle doit être affichée sur les écrans mobiles et masquée sur desktop - vous pouvez utiliser les outils de développement pour vérifier que les images desktop et mobile sont correctement échangées.

Une fois prêt, développez l'extrait de code ci-dessous pour voir la solution.

Génial ! Votre page d'accueil a maintenant une police personnalisée et des images hero.

Lectures recommandées

Il y a beaucoup plus à apprendre sur ces sujets, y compris l'optimisation des images distantes et l'utilisation de fichiers de police locaux. Si vous souhaitez approfondir les polices et images, consultez :

On this page