Pourquoi Optimiser les performances Astro ?
Dans un monde où l'expérience utilisateur est la clé du succès, optimiser les performances de vos applications Astro est essentiel. Un développeur doit être capable d'anticiper et de réduire les temps de chargement pour offrir une expérience fluide à ses utilisateurs. En effet, si la page ne charge pas rapidement, l'utilisateur peut partir avant même d'avoir eu le temps de lire un seul mot.
Un cas concret est le site web d'une startup qui a besoin de répondre rapidement aux besoins des utilisateurs pour rester compétitive sur le marché. Un retard de chargement pourrait entraîner une baisse significative de sa visibilité et de ses conversions.
Prerequis
- Connaissances en JavaScript/TypeScript
- Connaissance de la syntaxe Astro et React (pour ce tutoriel)
- Node.js v14+ installé sur votre machine
- npm ou yarn installé pour gérer les dépendances
Concepts fondamentaux
1. Code splitting avec React.lazy
Le code splitting est un concept permettant de charger uniquement le code nécessaire pour une partie donnée d'une application, plutôt que tout le code à la fois. Cela réduit l'initial load time.
// Composant principal qui utilise React.lazy et Suspense
import { lazy, Suspense } from 'react';
const LazyComponent = lazy(() => import('./LazyComponent'));
export default function App() {
return (
<div>
<h1>Code Splitting Example</h1>
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
</div>
);
}
2. Utilisation de React.memo pour optimiser les rendus
La memoisation est une technique qui permet de ne re-render un composant que s'il y a des changements dans ses props.
// Composant qui utilise React.memo
import React from 'react';
const MyComponent = React.memo(({ data }) => {
return (
<div>
{data.map(item => (
<div key={item.id}>{item.name}</div>
))}
</div>
);
});
export default MyComponent;
3. Optimisation des images avec astro-optimized-images
La gestion efficace des images est cruciale pour les performances. astro-optimized-images est un plugin qui optimise vos images de manière automatique.
npm install @astrojs/optimized-images --save-dev
Ajoutez la configuration suivante dans votre fichier astro.config.mjs :
import optimizedImages from '@astrojs/optimized-images';
export default {
integrations: [
optimizedImages({
// Configuration des options d'optimisation
formats: ['webp'],
quality: {
webp: 80,
},
}),
],
};
4. Utilisation de useTransition pour une meilleure expérience utilisateur
La transition entre les routes peut être fluide en utilisant la hook useTransition fournie par React.
// Composant qui utilise useTransition
import { useTransition } from 'react';
import { Link, navigate } from '@reach/router';
export default function App() {
const [isPending, startTransition] = useTransition();
return (
<div>
<h1>Navigation with Transition</h1>
<button onClick={() => startTransition(() => navigate('/about'))}>
Go to About
</button>
{isPending && <p>Loading...</p>}
</div>
);
}
Mise en pratique : projet fil rouge
Étape 1 : Création du Projet
npm create astro@latest my-astro-app --template react-ts
cd my-astro-app
Étape 2 : Structure de base du projet
Créez les fichiers suivants :
src/pages/index.astrosrc/components/Navbar.astrosrc/components/Footer.astrosrc/components/TaskList.astro
Structure des fichiers :
src/
├── components/
│ ├── Navbar.astro
│ ├── Footer.astro
│ └── TaskList.astro
├── pages/
│ └── index.astro
└── assets/
└── logo.svg
Étape 3 : Code source
src/pages/index.astro
---
// Import des composants
import Navbar from '../components/Navbar.astro';
import TaskList from '../components/TaskList.astro';
const tasks = [
{ id: 1, name: 'Buy groceries', completed: false },
{ id: 2, name: 'Finish project', completed: true },
];
---
<Navbar />
<main>
<h1>Task Manager</h1>
<TaskList tasks={tasks} />
</main>
<Footer />
src/components/Navbar.astro
---
// Composant Navbar
---
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
src/components/Footer.astro
---
// Composant Footer
---
<footer>
<p>© {new Date().getFullYear()} Task Manager</p>
</footer>
src/components/TaskList.astro
---
// Composant TaskList
import { useState } from 'react';
const initialTasks = [
{ id: 1, name: 'Buy groceries', completed: false },
{ id: 2, name: 'Finish project', completed: true },
];
const TaskList = ({ tasks }) => {
const [taskList, setTaskList] = useState(tasks);
const toggleTask = (id) => {
setTaskList(
taskList.map((task) =>
task.id === id ? { ...task, completed: !task.completed } : task
)
);
};
return (
<ul>
{taskList.map((task) => (
<li key={task.id}>
<input
type="checkbox"
checked={task.completed}
onChange={() => toggleTask(task.id)}
/>
{task.name}
</li>
))}
</ul>
);
};
export default TaskList;
Étape 4 : Execution du projet
npm run dev
Erreurs frequentes et debugging
1. Cannot read property 'map' of undefined
Code incorrect :
const tasks = data.map(task => <div key={task.id}>{task.name}</div>);
Code correct :
{tasks && tasks.map(task => <div key={task.id}>{task.name}</div>)}
2. React Hook "useState" must be called inside a React function component or a custom hook
Code incorrect :
const [count, setCount] = useState(0);
Code correct :
import { useState } from 'react';
const MyComponent = () => {
const [count, setCount] = useState(0);
return <div>{count}</div>;
};
3. TypeError: Cannot read property 'map' of null
Code incorrect :
{data.map(item => <div key={item.id}>{item.name}</div>)}
Code correct :
{data ? data.map(item => <div key={item.id}>{item.name}</div>) : <div>No data</div>}
Pour aller plus loin
Utilisation de
React.lazyavecSuspensepour charger des composants à la demande.Optimisation des images avec le plugin
@astrojs/optimized-images.Utilisation de la hook
useTransitionpour une meilleure expérience utilisateur lors de la navigation entre les routes.
Défi pratique
- Créez un CLI tool en utilisant Astro et TypeScript qui permette d'ajouter, modifier et supprimer des tâches dans une base de données locale (par exemple, avec
sqlite3).
En suivant ce tutoriel, vous devriez être en mesure d'optimiser significativement les performances de vos applications Astro et de créer des expériences utilisateur fluides et réactives.