Optimiser les performances Svelte
Pourquoi Optimiser les performances Svelte ?
Optimiser les performances Svelte est crucial pour assurer une expérience utilisateur fluide, surtout dans des applications plus complexes ou traitant de grandes quantités de données. Un développeur qui travaille sur un gestionnaire de tâches ou un blog avec beaucoup d'articles doit s'assurer que l'application reste rapide et réactive même quand le nombre de données augmente.
Un cas d'utilisation concret est la mise en place d'un système de notifications instantanées : chaque fois qu'une nouvelle notification arrive, l'interface utilisateur doit mettre à jour en temps réel sans une recharge complète de la page.
Prerequis
- Connaissances en Svelte et JavaScript ES6+
- Maîtrise des concepts de base de Svelte (components, props, state)
- Node.js installé (v14+ recommandé)
- npm ou yarn pour gérer les dépendances
Concepts fondamentaux
1. Lazy Evaluation
Svelte utilise la lazy evaluation par défaut pour les bindings et les props, ce qui signifie qu'il n'évalue une expression qu'une fois qu'elle est nécessaire. Cela peut être optimisé en utilisant createMemo pour éviter des recalculs inutiles.
<script>
import { createMemo } from 'svelte';
let count = 0;
const memoizedCount = createMemo(() => {
// Ce code ne sera exécuté que si count change
return count * 2;
});
</script>
<button on:click={() => count++}>Click me ({memoizedCount})</button>
2. Keyed List Rendering
Lorsque vous affichez une liste d'éléments, Svelte utilise l'identifiant key pour identifier les éléments et minimiser les mises à jour.
<script>
let items = ['Item 1', 'Item 2', 'Item 3'];
function addItem() {
items.push(`Item ${items.length + 1}`);
}
</script>
<ul>
{#each items as item, index (index)}
<li>{item}</li>
{/each}
</ul>
<button on:click={addItem}>Add Item</button>
3. Store and Actions
Les stores et les actions permettent de gérer le state de manière décentralisée et reactive.
<script>
import { writable } from 'svelte/store';
const count = writable(0);
function increment() {
count.update(n => n + 1);
}
function decrement() {
count.update(n => n - 1);
}
</script>
<button on:click={increment}>Increment</button>
<button on:click={decrement}>Decrement</button>
<script context="module">
export const actions = {
logCount: ({ store }) => (node) => {
store.subscribe(value => console.log('Count:', value));
}
};
</script>
<div use:logCount=store: count>
{count}
</div>
4. Transitions and Animations
Les transitions et les animations peuvent être utilisées pour améliorer l'expérience utilisateur en ajoutant des effets visuels.
<script>
import { fade } from 'svelte/transition';
let show = true;
function toggle() {
show = !show;
}
</script>
<button on:click={toggle}>Toggle</button>
{#if show}
<div transition:fade duration="500">
Hello, Svelte!
</div>
{/if}
Mise en pratique : projet fil rouge
Mini-Projet : Gestionnaire de Tâches
Étape 1 : Initialisation du Projet
Créez un nouveau projet Svelte avec create-svelte.
npx degit sveltejs/template svelte-todo
cd svelte-todo
npm install
Étape 2 : Création des Components
Créez un component pour les tâches.
<!-- src/TodoItem.svelte -->
<script>
export let task;
export let onDelete;
function handleDelete() {
onDelete(task.id);
}
</script>
<div class="todo-item">
<span>{task.text}</span>
<button on:click={handleDelete}>Delete</button>
</div>
<style>
.todo-item {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
</style>
Étape 3 : Création du Store
Créez un store pour gérer les tâches.
<!-- src/stores.js -->
import { writable } from 'svelte/store';
const tasks = writable([]);
export default tasks;
Étape 4 : Application principale
Modifier le component principal pour utiliser les components et le store.
<!-- src/App.svelte -->
<script>
import TodoItem from './TodoItem.svelte';
import tasksStore from './stores';
let newTaskText = '';
function addTask() {
if (newTaskText.trim()) {
tasksStore.update(tasks => [
...tasks,
{ id: Date.now(), text: newTaskText }
]);
newTaskText = '';
}
}
function deleteTask(id) {
tasksStore.update(tasks => tasks.filter(task => task.id !== id));
}
</script>
<main>
<h1>Todo List</h1>
<input bind:value={newTaskText} placeholder="Add a new task" />
<button on:click={addTask}>Add Task</button>
{#each $tasksStore as task (task.id)}
<TodoItem {task} onDelete={(id) => deleteTask(id)} />
{/each}
</main>
Étape 5 : Lancer le Projet
Lancez le projet avec la commande suivante :
npm run dev
Erreurs frequentes et debugging
Erreur 1: Uncaught TypeError: Cannot read property 'bind' of null
Cela se produit quand vous essayez de lier une valeur à un élément qui n'existe pas.
<!-- ❌ Mauvais -->
<input bind:value={nonExistentValue} />
<!-- ✅ Correct -->
<input {value} on:input={(e) => value = e.target.value} />
Erreur 2: Uncaught ReferenceError: Cannot access 'store' before initialization
Cela se produit quand vous essayez d'utiliser un store avant sa déclaration.
<!-- ❌ Mauvais -->
<script>
import { writable } from 'svelte/store';
let count = store.get(); // Erreur
const store = writable(0);
</script>
<!-- ✅ Correct -->
<script>
import { writable } from 'svelte/store';
const store = writable(0);
let count = store.get();
</script>
Erreur 3: Uncaught SyntaxError: Unexpected token 'await'
Cela se produit quand vous essayez d'utiliser await en dehors d'une fonction asynchrone.
<!-- ❌ Mauvais -->
<script>
let data = fetch('api/data').then(response => response.json()); // Erreur
</script>
<!-- ✅ Correct -->
<script>
async function fetchData() {
let response = await fetch('api/data');
let data = await response.json();
// Utilisez data ici
}
</script>
Pour aller plus loin
1. Avancer avec les Hooks de Svelte
Enseignez-vous comment utiliser les hooks comme onMount, onDestroy, etc., pour gérer des effets de bord.
2. Optimiser les performances avec la virtualisation
Apprenez à utiliser la virtualisation pour afficher des listes très longues efficacement.
3. Utiliser SSR et hydration
Découvrez comment utiliser le serveur-side rendering (SSR) et la hydration pour améliorer les temps de premier paint.
Défi pratique: Créer un Component d'Accordéon
Enseignez-vous à créer un component d'accordéon réactif et performant, en utilisant des stores et des actions.