Cours Next.js · Module 2: Routing et layouts
Prefetching et optimisation de la navigation
Dans cette leçon10
À Metropolis Quantum, le système de transport avancé repose sur la prédiction et la planification proactive. Les véhicules Q-Link, avant même qu'un passager ne lance une commande de voyage, analysent déjà les itinéraires typiques, préparent les connexions les plus rapides et préchauffent les moteurs à température optimale. Cette technologie de « prefetching quantique » permet des voyages quasi instantanés après l'émission d'une commande, éliminant les délais et garantissant des déplacements fluides dans toute la ville.
Dans le monde de Next.js 16, des principes similaires s'appliquent aux mécanismes de prefetching et à l'optimisation de la navigation. Ces techniques améliorent considérablement l'expérience utilisateur, minimisent les délais et maximisent les performances de nos applications.
Comprendre le prefetching dans Next.js 16
Le prefetching est une technique qui consiste à charger des ressources en arrière-plan avant que l'utilisateur ne les demande directement. Dans Next.js 16, le prefetching est intégré au composant Link et fonctionne automatiquement, mais on peut aussi contrôler précisément son comportement.
Prefetching automatique
Dans Next.js 16, le prefetching est activé par défaut pour le composant Link, mais il ne fonctionne qu'en production (après next build et next start). Dès que le lien apparaît dans la fenêtre d'affichage du navigateur, Next.js récupère en arrière-plan les données de la page de destination : la page entière pour une route statique, et pour une route dynamique seulement la partie qui va jusqu'au fichier loading.tsx le plus proche (sans ce fichier, le prefetch d'une route dynamique est ignoré). Next.js 16 a reconstruit ce mécanisme : un layout partagé n'est téléchargé qu'une fois pour plusieurs liens, et seules les parties absentes du cache sont récupérées.
1// Prefetching automatique des liens dans la fenêtre d'affichage
2<Link href="/destinations/mars">
3 Explorer Mars
4</Link>Ce mécanisme fonctionne comme le système de prédiction du trafic de Metropolis Quantum - lorsqu'un véhicule approche d'un carrefour, le système planifie déjà les itinéraires optimaux pour toutes les directions possibles.
Contrôle du prefetching
On peut contrôler précisément le comportement du prefetching à l'aide de la propriété prefetch du composant Link :
1// Désactive le prefetching pour le lien
2<Link href="/rarely-visited-page" prefetch={false}>
3 Page rarement visitée
4</Link>Désactiver le prefetching peut être utile pour les liens rarement utilisés ou menant à des pages gourmandes en ressources. C'est comme désactiver le système de pré-préparation pour les destinations rarement choisies à Metropolis Quantum, ce qui économise énergie et ressources.
Impact sur les performances de l'application
Le prefetching a un impact significatif sur les performances de l'application et l'expérience utilisateur :
- Navigation plus rapide - Les pages se chargent presque instantanément car les ressources sont déjà préchargées.
- Moins d'attente après un clic - les données de la page sont déjà chargées quand l'utilisateur clique ; en contrepartie, il y a des requêtes supplémentaires vers le serveur, même pour les liens sur lesquels personne ne clique.
- Économie de ressources - L'utilisation sélective du prefetching économise des ressources pour les liens moins importants.
Optimisation du composant Link
Le composant Link bénéficie aussi de plusieurs améliorations qui optimisent davantage la navigation. Certaines existent depuis Next.js 13, et Next.js 16 y a ajouté le prefetching plus économe décrit plus haut.
Transfert automatique des attributs vers la balise <a>
Depuis Next.js 13, le composant Link transfère automatiquement tous les attributs à la balise <a> interne, ce qui simplifie le code et améliore le SEO :
1// Next.js 13+ (y compris 16) - syntaxe simplifiée
2<Link
3 href="/destinations/mars"
4 className="btn btn-primary"
5 aria-label="Explorer Mars"
6 target="_blank"
7 rel="noopener noreferrer"
8>
9 Explorer Mars
10</Link>Cette automatisation fonctionne comme les interfaces de véhicules intelligentes de Metropolis Quantum, qui ajustent automatiquement leurs réglages aux préférences des passagers sans configuration manuelle.
L'option scroll
Le composant Link permet aussi de contrôler le comportement de défilement de la page après la navigation :
1// Désactive le défilement automatique vers le haut de la page
2<Link href="/destinations" scroll={false}>
3 Voir les destinations
4</Link>Cette option est particulièrement utile quand on veut préserver la position de défilement, par ex. lors de la navigation dans une longue liste ou lors de l'implémentation d'effets de défilement personnalisés.
Liens vers des routes dynamiques
L'utilisation efficace des paramètres dynamiques dans les composants Link permet une navigation plus flexible :
1// Paramètres dynamiques dans le composant Link
2const destinations = ['mars', 'europa', 'titan'];
3
4return (
5 <ul>
6 {destinations.map(destination => (
7 <li key={destination}>
8 <Link href={`/destinations/${destination}`}>
9 Explorer {destination.charAt(0).toUpperCase() + destination.slice(1)}
10 </Link>
11 </li>
12 ))}
13 </ul>
14);Ce modèle permet de construire des menus et des listes de navigation dynamiques, à l'image du système de routes dynamiques de Metropolis Quantum, qui permet de choisir n'importe quelle combinaison de points intermédiaires.
Dans l'App Router, l'objet { pathname: '/destinations/[id]', query: { id } } n'insère pas le paramètre dans le chemin (on obtiendrait /destinations/[id]?id=mars) ; un objet avec query sert seulement aux paramètres de requête, par ex. { pathname: '/search', query: { q: 'mars' } }.
Prefetching programmatique avec useRouter
En plus du prefetching déclaratif avec le composant Link, Next.js 16 permet aussi le préchargement programmatique des pages à l'aide du hook useRouter.
Utilisation de base de router.prefetch
1'use client';
2
3import { useRouter } from 'next/navigation';
4import { useEffect } from 'react';
5
6export default function DestinationCard({
7 destination,
8}: {
9 destination: { id: string; name: string; description: string; isPopular?: boolean };
10}) {
11 const router = useRouter();
12
13 // Précharge la page de détails au survol de la souris
14 const handleHover = () => {
15 router.prefetch(`/destinations/${destination.id}`);
16 };
17
18 // Précharge les pages les plus visitées au montage du composant
19 useEffect(() => {
20 if (destination.isPopular) {
21 router.prefetch(`/destinations/${destination.id}`);
22 }
23 }, [destination, router]);
24
25 return (
26 <div
27 className="destination-card"
28 onMouseEnter={handleHover}
29 onClick={() => router.push(`/destinations/${destination.id}`)}
30 >
31 <h3>{destination.name}</h3>
32 <p>{destination.description}</p>
33 </div>
34 );
35}Ce modèle ressemble au système intelligent de Metropolis Quantum, qui prépare les véhicules au voyage lorsqu'un habitant approche d'une station, avant même qu'il ne prenne sa décision finale de voyage.
Prefetching stratégique
Dans des scénarios plus avancés, on peut appliquer un prefetching stratégique basé sur l'analyse du comportement de l'utilisateur :
1'use client';
2
3import { useRouter } from 'next/navigation';
4import { useEffect } from 'react';
5
6export default function Dashboard({ user }) {
7 const router = useRouter();
8
9 useEffect(() => {
10 // Prefetching des pages basé sur l'historique de l'utilisateur
11 if (user.mostVisitedDestinations) {
12 user.mostVisitedDestinations.forEach(destination => {
13 router.prefetch(`/destinations/${destination.id}`);
14 });
15 }
16
17 // Prefetching des pages basé sur l'heure de la journée
18 const currentHour = new Date().getHours();
19 if (currentHour >= 9 && currentHour <= 17) {
20 // Pendant les heures de bureau, précharge les destinations professionnelles
21 router.prefetch('/destinations/business');
22 } else {
23 // En dehors des heures de travail, précharge les destinations de loisirs
24 router.prefetch('/destinations/recreation');
25 }
26
27 // Prefetching des pages basé sur les événements à venir
28 if (user.upcomingTrip) {
29 router.prefetch(`/trips/${user.upcomingTrip.id}`);
30 router.prefetch(`/checklist/${user.upcomingTrip.id}`);
31 }
32 }, [user, router]);
33
34 return (
35 <div className="dashboard">
36 {/* Contenu du tableau de bord */}
37 </div>
38 );
39}Cette stratégie de prefetching avancée ressemble au système prédictif de Metropolis Quantum, qui analyse les schémas de trafic et les préférences des habitants pour préparer à l'avance les véhicules et les itinéraires.
Optimisation du chargement des données
Dans Next.js 16, l'optimisation de la navigation est étroitement liée à l'optimisation du chargement des données. L'App Router introduit de nouvelles méthodes pour une récupération et une mise en cache efficaces des données.
Charger les données dans les Server Components
Les Server Components dans Next.js 16 permettent de charger les données directement dans le composant, sans avoir besoin d'API supplémentaires :
1// app/destinations/[id]/page.tsx
2export default async function DestinationPage({ params }: { params: Promise<{ id: string }> }) {
3 // Chargement des données directement dans le composant
4 const destination = await fetchDestination((await params).id);
5
6 return (
7 <div className="destination-page">
8 <h1>{destination.name}</h1>
9 <p>{destination.description}</p>
10 {/* Plus de contenu */}
11 </div>
12 );
13}Cette méthode élimine les requêtes d'API supplémentaires typiques des applications React traditionnelles. C'est comparable au système intégré de Metropolis Quantum, qui combine la planification des itinéraires et le contrôle des véhicules en un seul processus, éliminant le besoin de communication entre différents systèmes.
Chargement parallèle des données
On peut optimiser le chargement des données grâce à l'exécution parallèle des requêtes :
1// app/destinations/[id]/page.tsx
2export default async function DestinationPage({ params }: { params: Promise<{ id: string }> }) {
3 // Chargement parallèle des données
4 const [destination, attractions, reviews] = await Promise.all([
5 fetchDestination((await params).id),
6 fetchAttractions((await params).id),
7 fetchReviews((await params).id)
8 ]);
9
10 return (
11 <div className="destination-page">
12 <h1>{destination.name}</h1>
13 <section className="attractions">
14 <h2>Attractions populaires</h2>
15 <AttractionsList attractions={attractions} />
16 </section>
17 <section className="reviews">
18 <h2>Avis des voyageurs</h2>
19 <ReviewsList reviews={reviews} />
20 </section>
21 </div>
22 );
23}Cette technique ressemble au système de transport de Metropolis Quantum, qui prépare en parallèle différents éléments du voyage - le véhicule, l'itinéraire et les points intermédiaires - pour réduire le temps de préparation total.
Utiliser generateMetadata et generateStaticParams
Next.js 16 fournit des fonctions spéciales pour optimiser les données des métadonnées et des paramètres statiques :
1// app/destinations/[id]/page.tsx
2import type { Metadata } from 'next';
3
4// Fonction générant les métadonnées de la page
5export async function generateMetadata(
6 { params }: { params: Promise<{ id: string }> }
7): Promise<Metadata> {
8 // Récupération des données uniquement pour les métadonnées
9 const destination = await fetchDestinationBasic((await params).id);
10
11 return {
12 title: `${destination.name} - Quantum Voyages`,
13 description: destination.shortDescription,
14 openGraph: {
15 images: [{ url: destination.imageUrl }],
16 },
17 };
18}
19
20// Fonction générant les paramètres statiques pour les destinations populaires
21export async function generateStaticParams() {
22 // Récupération des seules destinations les plus populaires pour le prérendu
23 const popularDestinations = await fetchPopularDestinations();
24
25 return popularDestinations.map((destination) => ({
26 id: destination.id,
27 }));
28}
29
30export default async function DestinationPage({ params }: { params: Promise<{ id: string }> }) {
31 // Récupération des données complètes de la page
32 const destination = await fetchDestinationFull((await params).id);
33
34 return (
35 <div className="destination-page">
36 {/* Contenu de la page */}
37 </div>
38 );
39}Ces fonctions spéciales permettent un chargement sélectif des données pour différents aspects de la page, à l'image du système de Metropolis Quantum, qui alloue les ressources aux différents aspects du voyage en fonction de leurs priorités.
Stratégies de mise en cache des données
Next.js 16 offre des stratégies de mise en cache des données flexibles, adaptables aux besoins spécifiques de chaque application. Les options de fetch ci-dessous appartiennent au modèle de cache par défaut de Next.js 16 (sans cacheComponents activé). N'oublie pas que depuis Next.js 15, les requêtes fetch ne sont plus mises en cache par défaut : tu actives donc le cache explicitement.
Mise en cache statique et dynamique
1// app/destinations/page.tsx
2export default async function DestinationsPage() {
3 // Données qui changent rarement - mise en cache statique
4 const categories = await fetchCategories({
5 next: { revalidate: 3600 } // Rafraîchit toutes les heures
6 });
7
8 // Données qui changent fréquemment - mise en cache dynamique
9 const featuredDestinations = await fetchFeaturedDestinations({
10 next: { revalidate: 60 } // Rafraîchit toutes les minutes
11 });
12
13 // Données uniques à chaque requête - pas de mise en cache
14 const userRecommendations = await fetchUserRecommendations({
15 cache: 'no-store'
16 });
17
18 return (
19 <div className="destinations-page">
20 <CategoriesList categories={categories} />
21 <FeaturedDestinations destinations={featuredDestinations} />
22 <RecommendationsList recommendations={userRecommendations} />
23 </div>
24 );
25}Cette stratégie de mise en cache flexible ressemble au système de transport de Metropolis Quantum, qui met en cache différents types d'informations avec différents cycles de rafraîchissement - les informations permanentes sur les monuments sont mises en cache plus longtemps, tandis que les informations dynamiques sur le trafic sont mises à jour plus fréquemment.
Revalidation à la demande
Next.js 16 permet aussi la revalidation à la demande des données mises en cache, ce qui est utile après des mises à jour de données. Remarque le second argument de revalidateTag : depuis Next.js 16, c'est un profil cacheLife, et la valeur recommandée 'max' signifie que l'utilisateur reçoit l'ancienne version pendant que la nouvelle se charge en arrière-plan. La forme à un seul argument est dépréciée :
1// app/api/revalidate/route.ts
2import { NextRequest } from 'next/server';
3import { revalidatePath, revalidateTag } from 'next/cache';
4
5export async function GET(request: NextRequest) {
6 const tag = request.nextUrl.searchParams.get('tag');
7 const path = request.nextUrl.searchParams.get('path');
8
9 if (tag) {
10 revalidateTag(tag, 'max');
11 return Response.json({ revalidated: true, tag });
12 }
13
14 if (path) {
15 revalidatePath(path);
16 return Response.json({ revalidated: true, path });
17 }
18
19 return Response.json({ revalidated: false, message: 'No tag or path provided' }, { status: 400 });
20}Cette fonctionnalité fonctionne comme le système de mise à jour des itinéraires de Metropolis Quantum, qui peut propager instantanément les informations sur les changements de l'infrastructure de la ville à tous les véhicules, sans attendre les cycles de mise à jour réguliers.
Optimisation du rendu des composants
L'optimisation de la navigation dans Next.js 16 inclut aussi l'optimisation du rendu des composants.
Streaming et Suspense
Next.js 16 prend en charge le streaming et Suspense, qui permettent un rendu progressif de l'interface utilisateur :
1// app/destinations/[id]/page.tsx
2import { Suspense } from 'react';
3import DestinationHeader from './DestinationHeader';
4import AttractionsList from './AttractionsList';
5import WeatherWidget from './WeatherWidget';
6import ReviewsList from './ReviewsList';
7import RelatedDestinations from './RelatedDestinations';
8
9export default async function DestinationPage({ params }: { params: Promise<{ id: string }> }) {
10 // Récupération des informations de base nécessaires immédiatement
11 const destinationInfo = await fetchDestinationInfo((await params).id);
12
13 return (
14 <div className="destination-page">
15 <DestinationHeader info={destinationInfo} />
16
17 <div className="destination-content grid grid-cols-1 lg:grid-cols-3 gap-6">
18 <div className="lg:col-span-2">
19 {/* Composant qui peut se charger lentement */}
20 <Suspense fallback={<div className="attractions-loading">Chargement des attractions...</div>}>
21 <AttractionsList destinationId={(await params).id} />
22 </Suspense>
23
24 {/* Un autre composant au temps de chargement potentiellement long */}
25 <Suspense fallback={<div className="reviews-loading">Chargement des avis...</div>}>
26 <ReviewsList destinationId={(await params).id} />
27 </Suspense>
28 </div>
29
30 <div className="lg:col-span-1">
31 {/* Composants de la colonne de droite */}
32 <Suspense fallback={<div className="weather-loading">Chargement de la météo...</div>}>
33 <WeatherWidget destinationId={(await params).id} />
34 </Suspense>
35
36 <Suspense fallback={<div className="related-loading">Chargement des destinations associées...</div>}>
37 <RelatedDestinations currentId={(await params).id} />
38 </Suspense>
39 </div>
40 </div>
41 </div>
42 );
43}Cette technique ressemble au système de transport de Metropolis Quantum, qui permet aux passagers de monter dans le véhicule et de commencer le voyage, même si certains systèmes embarqués (par ex. le divertissement ou les informations sur l'itinéraire) sont encore en cours de chargement.
Rendu sélectif avec Client et Server Components
Séparer correctement les composants en Server Components et Client Components peut considérablement améliorer les performances :
1// app/destinations/[id]/page.tsx - Server Component
2import { fetchDestination } from '@/lib/data';
3import DestinationDetails from './DestinationDetails';
4import InteractiveMap from './InteractiveMap'; // Client Component
5import TripPlanner from './TripPlanner'; // Client Component
6
7export default async function DestinationPage({ params }: { params: Promise<{ id: string }> }) {
8 // Chargement des données sur le serveur
9 const destination = await fetchDestination((await params).id);
10
11 return (
12 <div className="destination-page">
13 {/* Server Component - rendu sur le serveur */}
14 <DestinationDetails destination={destination} />
15
16 {/* Client Components - rendus de façon interactive côté client */}
17 <div className="interactive-components mt-8 flex flex-col lg:flex-row gap-6">
18 <InteractiveMap
19 coordinates={destination.coordinates}
20 points={destination.interestPoints}
21 />
22
23 <TripPlanner
24 destinationId={destination.id}
25 initialDates={destination.availableDates}
26 />
27 </div>
28 </div>
29 );
30}Cette stratégie de rendu hybride fonctionne comme le système optimisé de Metropolis Quantum, qui combine des éléments de planification centralisée (Server Components) avec le comportement autonome des véhicules (Client Components) pour optimiser l'ensemble de l'expérience.
Optimisation des images et des ressources statiques
L'optimisation des ressources statiques est essentielle pour une navigation rapide dans les applications Next.js 16.
Le composant Image
Next.js 16 fournit le composant Image, qui optimise automatiquement les images :
1// app/destinations/[id]/page.tsx
2import Image from 'next/image';
3
4export default async function DestinationPage({ params }: { params: Promise<{ id: string }> }) {
5 const destination = await fetchDestination((await params).id);
6
7 return (
8 <div className="destination-page">
9 <div className="destination-hero relative h-96 mb-8">
10 <Image
11 src={destination.imageUrl}
12 alt={destination.name}
13 fill
14 sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
15 preload={true} // Chargement avec une priorité élevée
16 className="object-cover rounded-lg"
17 />
18 </div>
19
20 <h1 className="text-4xl font-bold mb-4">{destination.name}</h1>
21 <p className="text-lg mb-8">{destination.description}</p>
22
23 <div className="attractions grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
24 {destination.attractions.map(attraction => (
25 <div key={attraction.id} className="attraction-card relative h-64">
26 <Image
27 src={attraction.imageUrl}
28 alt={attraction.name}
29 fill
30 sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
31 className="object-cover rounded-lg"
32 />
33 <div className="absolute inset-0 bg-gradient-to-t from-black/70 to-transparent rounded-lg">
34 <div className="absolute bottom-0 p-4 text-white">
35 <h3 className="text-xl font-semibold">{attraction.name}</h3>
36 </div>
37 </div>
38 </div>
39 ))}
40 </div>
41 </div>
42 );
43}Le composant Image optimise automatiquement les images en ajustant leur taille, leur format et leur chargement au contexte d'affichage, à l'image du système visuel de Metropolis Quantum, qui adapte dynamiquement les informations visuelles à l'appareil et aux préférences de l'utilisateur.
L'attribut preload (anciennement priority)
L'attribut preload du composant Image permet de définir les priorités de chargement des images. Dans Next.js 16, il a remplacé l'attribut priority, désormais déprécié, et fonctionne de la même façon : il ajoute une balise <link rel="preload"> dans le <head>, pour que l'image commence à se télécharger tout de suite. Utilise-le seulement pour l'image la plus importante (LCP) ; dans les autres cas, la documentation recommande loading="eager" ou fetchPriority="high" :
1// Image critique pour le LCP (Largest Contentful Paint)
2<Image
3 src="/hero-image.jpg"
4 alt="Découvre le cosmos avec Quantum Voyages"
5 width={1200}
6 height={600}
7 preload={true}
8/>Cette fonctionnalité fonctionne comme le système de priorité de Metropolis Quantum, qui dirige plus de ressources vers les aspects les plus importants du voyage, garantissant une répartition optimale de la puissance et de la bande passante.
Imports statiques d'images
Next.js 16 permet aussi les imports statiques d'images, ce qui autorise une optimisation et un typage automatiques :
1// Import statique d'image
2import marsImage from '@/public/images/destinations/mars.jpg';
3
4export default function MarsCard() {
5 return (
6 <div className="destination-card">
7 <Image
8 src={marsImage}
9 alt="Mars - la planète rouge"
10 />
11 <h3>Mars</h3>
12 <p>La planète rouge au potentiel de colonies futures.</p>
13 </div>
14 );
15}Cette technique ressemble au système d'identité visuelle de Metropolis Quantum, qui stocke des images pré-optimisées pour tous les composants standard de la ville, garantissant une présentation cohérente et efficace.
Stratégies de prefetching avancées
Les usages avancés du prefetching peuvent considérablement améliorer les performances de l'application.
Prefetching conditionnel basé sur l'interaction de l'utilisateur
1'use client';
2
3import { useState, useEffect } from 'react';
4import { useRouter } from 'next/navigation';
5
6export default function DestinationCard({
7 destination,
8}: {
9 destination: { id: string; name: string; description: string; isPopular?: boolean };
10}) {
11 const router = useRouter();
12 const [interactionCount, setInteractionCount] = useState(0);
13 const [interactionTime, setInteractionTime] = useState(0);
14
15 // Suit l'interaction de l'utilisateur
16 const trackInteraction = () => {
17 setInteractionCount(prev => prev + 1);
18 setInteractionTime(prev => prev + 0.5); // Simule le temps passé à survoler la carte
19 };
20
21 useEffect(() => {
22 // Prefetch uniquement si l'utilisateur montre un intérêt suffisant
23 if (interactionCount > 2 || interactionTime > 1.5) {
24 router.prefetch(`/destinations/${destination.id}`);
25 }
26 }, [interactionCount, interactionTime, destination.id, router]);
27
28 return (
29 <div
30 className="destination-card"
31 onMouseEnter={trackInteraction}
32 onMouseMove={trackInteraction}
33 onClick={() => router.push(`/destinations/${destination.id}`)}
34 >
35 <h3>{destination.name}</h3>
36 <p>{destination.description}</p>
37 </div>
38 );
39}Cette stratégie avancée fonctionne comme le système de prédiction adaptatif de Metropolis Quantum, qui analyse le niveau d'intérêt d'un habitant pour une direction précise et ajuste les préparatifs en conséquence.
Prefetching basé sur les schémas de navigation
On peut analyser les schémas de navigation typiques des utilisateurs et précharger les pages qu'ils sont susceptibles de visiter :
1'use client';
2
3import { useEffect } from 'react';
4import { useRouter, usePathname } from 'next/navigation';
5
6export default function NavigationAnalytics() {
7 const router = useRouter();
8 const pathname = usePathname();
9
10 useEffect(() => {
11 // Détermine les prochains chemins probables à partir du chemin actuel
12 const predictNextPages = (currentPath) => {
13 // Schémas de navigation déterminés à partir de l'analytique des utilisateurs
14 const navigationPatterns = {
15 '/destinations': ['/destinations/mars', '/destinations/europa', '/booking'],
16 '/destinations/mars': ['/booking/mars', '/destinations/europa', '/destinations'],
17 '/booking': ['/checkout', '/destinations', '/account'],
18 '/checkout': ['/confirmation', '/dashboard', '/account'],
19 };
20
21 return navigationPatterns[currentPath] || [];
22 };
23
24 // Prefetching des chemins prédits
25 const nextProbablePaths = predictNextPages(pathname);
26 nextProbablePaths.forEach(path => {
27 router.prefetch(path);
28 });
29 }, [pathname, router]);
30
31 // Ce composant ne rend rien, il analyse seulement la navigation
32 return null;
33}Ce système ressemble à la prédiction d'itinéraires avancée de Metropolis Quantum, qui analyse les schémas de voyage typiques des habitants et prépare les itinéraires qu'ils sont le plus susceptibles de choisir, à partir de données historiques et du contexte.
Surveiller et optimiser les Web Vitals
La surveillance des métriques Web Vitals est essentielle à l'optimisation de la navigation et à l'expérience utilisateur globale.
Suivre les Web Vitals
Next.js 16 propose des outils intégrés pour suivre les Web Vitals :
1// app/_components/web-vitals.tsx
2'use client';
3
4import { useReportWebVitals } from 'next/web-vitals';
5
6export function WebVitalsReporter() {
7 useReportWebVitals((metric) => {
8 // Envoi des métriques au système d'analytique
9 console.log(metric);
10 });
11
12 return null;
13}Le root layout reste un Server Component et se contente d'afficher ce composant, car les hooks comme useReportWebVitals ne fonctionnent que dans un Client Component :
1// app/layout.tsx (Server Component)
2import { WebVitalsReporter } from './_components/web-vitals';
3
4export default function RootLayout({ children }: { children: React.ReactNode }) {
5 return (
6 <html lang="fr">
7 <body>
8 <WebVitalsReporter />
9 {children}
10 </body>
11 </html>
12 );
13}Cette fonctionnalité fonctionne comme le système de surveillance de Metropolis Quantum, qui suit tous les aspects du voyage, du temps d'attente du véhicule à la fluidité du trajet, afin d'optimiser en continu l'expérience des habitants.
Optimiser le Largest Contentful Paint (LCP)
L'optimisation du LCP est essentielle pour améliorer la vitesse de chargement perçue :
1// app/page.tsx
2import Image from 'next/image';
3import heroImage from '@/public/images/hero.jpg';
4
5export default function HomePage() {
6 return (
7 <div className="home-page">
8 {/* Optimisation du LCP via le chargement prioritaire de l'image principale */}
9 <div className="hero-section relative h-[80vh]">
10 <Image
11 src={heroImage}
12 alt="Quantum Voyages - ta porte vers le cosmos"
13 fill
14 preload={true} // Important pour le LCP
15 className="object-cover"
16 />
17 <div className="absolute inset-0 flex items-center justify-center">
18 <div className="text-center text-white">
19 <h1 className="text-5xl font-bold mb-4">Découvre le cosmos avec Quantum Voyages</h1>
20 <p className="text-xl mb-8">Ta porte vers les voyages interplanétaires</p>
21 <button className="bg-indigo-600 hover:bg-indigo-700 text-white py-3 px-8 rounded-full">
22 Commence ton voyage
23 </button>
24 </div>
25 </div>
26 </div>
27
28 {/* Reste du contenu de la page */}
29 </div>
30 );
31}Cette technique d'optimisation fonctionne comme le système de première impression de Metropolis Quantum, qui garantit que les éléments les plus importants de l'expérience de voyage sont livrés en premier, créant une première impression positive.
Minimiser le Cumulative Layout Shift (CLS)
Réduire les décalages de mise en page est essentiel pour une expérience fluide :
1// app/destinations/[id]/page.tsx
2import Image from 'next/image';
3
4export default async function DestinationPage({ params }: { params: Promise<{ id: string }> }) {
5 const destination = await fetchDestination((await params).id);
6
7 return (
8 <div className="destination-page">
9 {/* Évite le CLS en spécifiant les dimensions de l'image */}
10 <div className="destination-hero relative aspect-[16/9] mb-8">
11 <Image
12 src={destination.imageUrl}
13 alt={destination.name}
14 fill
15 sizes="100vw"
16 className="object-cover rounded-lg"
17 />
18 </div>
19
20 {/* Évite le CLS en réservant de l'espace pour le contenu dynamique */}
21 <div className="content-container min-h-[500px]">
22 <h1 className="text-4xl font-bold mb-4">{destination.name}</h1>
23 <p className="text-lg mb-8">{destination.description}</p>
24
25 {/* Plus de contenu */}
26 </div>
27 </div>
28 );
29}Cette technique ressemble au système de stabilisation de Metropolis Quantum, qui garantit que les éléments de la ville ne se déplacent pas de façon inattendue, même lorsque de nouvelles informations ou services sont ajoutés en temps réel.
Résumé
Le prefetching et l'optimisation de la navigation dans Next.js 16 sont des outils puissants qui améliorent considérablement l'expérience utilisateur et les performances de l'application. Comme le système de transport avancé de Metropolis Quantum, qui utilise la technologie de « prefetching quantique » pour éliminer les délais, Next.js 16 offre tout un éventail de fonctionnalités et de stratégies permettant de créer des applications extrêmement réactives et efficaces :
Prefetching automatique - le composant
Linkcharge automatiquement les ressources en arrière-plan lorsqu'un lien apparaît dans la fenêtre d'affichage.Prefetching programmatique - le hook
useRouterpermet un préchargement stratégique des pages basé sur l'interaction de l'utilisateur, les schémas de navigation et d'autres facteurs.Optimisation du chargement des données - les Server Components, les requêtes parallèles et les stratégies de mise en cache flexibles minimisent les délais liés à la récupération des données.
Rendu sélectif - une bonne utilisation des Server et Client Components permet une séparation optimale de la logique de rendu.
Streaming et Suspense - le rendu progressif de l'interface utilisateur offre une expérience réactive même pendant le chargement des éléments les plus lents.
Optimisation des ressources statiques - le composant
Imageet d'autres outils optimisent automatiquement les images et autres ressources.Surveillance et optimisation des Web Vitals - des outils pour suivre et améliorer les métriques de performance clés.
En appliquant ces techniques, notre application Quantum Voyages peut offrir une navigation quasi instantanée et une expérience fluide, à l'image du système de transport avancé de Metropolis Quantum, qui élimine les délais et garantit des déplacements fluides dans toute la ville.
Dans la prochaine leçon, tu verras comment changer l'URL sans recharger la page (shallow routing).
Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Comment désactives-tu le préchargement automatique pour un seul composant Link ?
2. Quelle méthode de useRouter permet de précharger une page de façon programmatique (par exemple au survol de la souris) ?
Tâches pratiques dans le jeu
- Tri horizontal
Ordonne la syntaxe d’ouverture d’un composant Link qui désactive le défilement automatique vers le haut