Pourquoi Optimiser les performances Nuxt ?
Dans un monde où la vitesse est la clé, le temps d'attente peut faire la différence entre une expérience utilisateur satisfaisante et une frustration croissante. Un développeur Nuxt a besoin de comprendre comment optimiser les performances pour assurer une application réactive et fluide. Un cas concret : un site e-commerce avec beaucoup de produits nécessitant une charge rapide et optimisée pour maintenir l'engagement des utilisateurs.
Prerequis
- Connaissance avancée de Nuxt.js
- Expérience en gestion de projet et en performance front-end
- Familiarité avec les Outils suivants :
- Node.js (v14+)
- npm ou yarn
- L'éditeur de code de votre choix (VSCode, WebStorm, etc.)
- Base en HTML, CSS et JavaScript
Concepts fondamentaux
1. Code Splitting
Le code splitting est un pattern qui permet de diviser le bundle JavaScript en plusieurs parties plus petites. Cela augmente l'efficacité du chargement initial de la page.
Schéma mental :
[Entrée] -> [Code Principal] + [Code Async]
Exemple de code :
// nuxt.config.js
export default {
build: {
splitChunks: {
layouts: true,
pages: true,
vendor: true
}
}
}
2. Lazy Loading
Le lazy loading permet de charger des composants et des images uniquement lorsque ils sont nécessaires. Cela améliore la performance en réduisant le temps d'initialisation.
Schéma mental :
[Entrée] -> [Composants Importés Eagerly]
[Utilisateur Navigue] -> [Composants Importés Lazy]
Exemple de code :
// pages/index.vue
<template>
<div>
<button @click="loadComponent">Charger le Composant</button>
<component v-if="showComponent" is="LazyComponent"></component>
</div>
</template>
<script>
export default {
data() {
return {
showComponent: false
};
},
methods: {
loadComponent() {
import('~/components/LazyComponent.vue').then((module) => {
this.$options.components.LazyComponent = module.default;
this.showComponent = true;
});
}
}
};
</script>
3. Service Worker
Un service worker est un script qui s'exécute en arrière-plan et peut intercepter les requêtes réseau pour optimiser l'expérience utilisateur.
Schéma mental :
[Entrée] -> [Service Worker Intercepte Requête]
[Utilisateur Relance Page] -> [Cache Utilisé, Non Réseau]
Exemple de code :
// nuxt.config.js
export default {
pwa: {
workboxOptions: {
skipWaiting: true,
clientsClaim: true
}
}
}
4. Prendre en charge les Assets
Optimiser les images et les assets est crucial pour améliorer la performance de l'application.
Schéma mental :
[Entrée] -> [Assets Optimisés (Minifiés, Comprimés)]
[Utilisateur Navigue] -> [Temps de Chargement Réduit]
Exemple de code :
// nuxt.config.js
export default {
build: {
extend(config) {
config.module.rules.push({
test: /\.(png|jpe?g|gif|svg)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 1024 * 10 // 10Ko
}
},
{
loader: 'image-webpack-loader'
}
]
});
}
}
}
Mise en pratique : Projet fil rouge
Étape 1 : Initialisation du projet Nuxt.js
npx create-nuxt-app my-project
cd my-project
npm install
Structure de base du projet :
my-project/
├── assets/
├── components/
├── layouts/
│ └── default.vue
├── middleware/
├── pages/
│ ├── index.vue
├── plugins/
├── static/
├── store/
├── nuxt.config.js
└── package.json
Étape 2 : Ajout d'une feature de Lazy Loading
Créez un composant LazyComponent.vue :
<!-- components/LazyComponent.vue -->
<template>
<div class="lazy-component">
<h1>Ceci est un Composant Lazy</h1>
</div>
</template>
<script>
export default {
name: 'LazyComponent'
};
</script>
<style scoped>
.lazy-component {
padding: 20px;
background-color: #f0f0f0;
}
</style>
Étape 3 : Intégration du Lazy Loading
Mettez à jour pages/index.vue pour utiliser le lazy loading :
<!-- pages/index.vue -->
<template>
<div>
<button @click="loadComponent">Charger le Composant</button>
<component v-if="showComponent" is="LazyComponent"></component>
</div>
</template>
<script>
export default {
data() {
return {
showComponent: false
};
},
methods: {
loadComponent() {
import('~/components/LazyComponent.vue').then((module) => {
this.$options.components.LazyComponent = module.default;
this.showComponent = true;
});
}
}
};
</script>
Étape 4 : Ajout d'un Service Worker
Mettez à jour nuxt.config.js pour activer le service worker :
// nuxt.config.js
export default {
pwa: {
workboxOptions: {
skipWaiting: true,
clientsClaim: true
}
}
}
Étape 5 : Optimisation des Assets
Ajoutez une configuration pour optimiser les images et les assets dans nuxt.config.js :
// nuxt.config.js
export default {
build: {
extend(config) {
config.module.rules.push({
test: /\.(png|jpe?g|gif|svg)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 1024 * 10 // 10Ko
}
},
{
loader: 'image-webpack-loader'
}
]
});
}
}
}
Erreurs frequentes et debugging
Erreur 1 : Le composant n'est pas chargé correctement
Code incorrect :
import('~/components/LazyComponent.vue').then((module) => {
this.$options.components.LazyComponent = module.default;
});
Code correct :
import('~/components/LazyComponent.vue').then(({ default: LazyComponent }) => {
this.$options.components.LazyComponent = LazyComponent;
});
Erreur 2 : Le service worker n'est pas enregistré
Code incorrect :
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js');
});
}
Code correct :
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js').then(registration => {
console.log('Service Worker registered with scope:', registration.scope);
}).catch(error => {
console.error('Service Worker registration failed:', error);
});
});
}
Erreur 3 : Les assets ne sont pas optimisés
Code incorrect :
module.exports = {
build: {
extend(config) {
config.module.rules.push({
test: /\.(png|jpe?g|gif)$/i,
use: ['url-loader']
});
}
}
};
Code correct :
module.exports = {
build: {
extend(config) {
config.module.rules.push({
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 1024 * 10 // 10Ko
}
},
{
loader: 'image-webpack-loader'
}
]
});
}
}
};
Pour aller plus loin
1. Utiliser Next.js pour un meilleur contrôle du rendu côté serveur
Next.js offre des outils avancés de performance et de SEO qui peuvent être intégrés dans Nuxt.js.
2. Optimiser les APIs avec Apollo Client
Apollo Client est une bibliothèque pour gérer les requêtes GraphQL en JavaScript, offrant des fonctionnalités avancées d'optimisation et de mise en cache.
3. Utiliser l'API nuxt.config.js pour configurer la performance
La configuration dans nuxt.config.js offre de nombreuses options pour optimiser les performances, allant des minifications automatiques aux directives de cache HTTP.
Défi pratique : Créer un scraper en utilisant Nuxt.js
Créez un petit scraper qui récupère des données depuis une API publique et les affiche dans votre application Nuxt.js.
- Créez un module
scraper.jspour effectuer la requête. - Utilisez ce module dans une page ou une API route pour obtenir et afficher les données.
npm install axios cheerio
scraper.js :
const axios = require('axios');
const cheerio = require('cheerio');
async function scrapeData() {
const { data } = await axios.get('https://example.com/data');
const $ = cheerio.load(data);
const items = [];
$('item').each((i, el) => {
items.push({
title: $(el).find('title').text(),
description: $(el).find('description').text()
});
});
return items;
}
module.exports = scrapeData;
pages/index.vue :
<template>
<div>
<h1>Scraper Result</h1>
<ul>
<li v-for="item in items" :key="item.title">
item.title - item.description
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
items: []
};
},
async asyncData({ $axios }) {
const items = await this.$axios.$get('/api/scrape');
return { items };
}
};
</script>
server/api/scrape.js :
const scrapeData = require('../scraper');
export default function handler(req, res) {
scrapeData().then(items => {
res.status(200).json(items);
});
}
Avec ce projet fil rouge et ces concepts supplémentaires, vous devriez être bien préparé pour optimiser les performances de vos applications Nuxt.js.