Migration Next.js vers TanStack Start & Convex : Performance et DX Améliorés
Découvrez la migration d'une application de génération de miniatures YouTube de Next.js vers la stack NowStack (TanStack Start + Convex), améliorant la performance, la synchronisation des données et l'expérience développeur grâce à l'IA.
Introduction
Cette documentation explore la migration d'une application de génération de miniatures YouTube, Subfast, de sa stack Next.js + Prisma + PostgreSQL vers la nouvelle stack NowStack (TanStack Start + Convex). L'objectif principal est de démontrer les améliorations significatives en termes de performance, de synchronisation des données et d'expérience développeur.
Précis de configuration
| Élément | Version / Lien |
|---|---|
| Langage / Runtime | JavaScript / TypeScript, Node.js |
| Librairie principale (ancienne) | Next.js, Prisma |
| Librairie principale (nouvelle) | TanStack Start, Convex |
| APIs requises | Stripe (paiements), OpenAI / Gemini (génération d'images) |
| Clés / credentials nécessaires | Clés API pour OpenAI / Gemini, Clés Stripe |
Guide étape par étape
Étape 1 — Comprendre l'ancienne architecture (Next.js + Qstash + PostgreSQL)
L'ancienne version de l'application utilisait Next.js pour le frontend et le backend, avec Prisma comme ORM pour interagir avec une base de données PostgreSQL. Pour les tâches longues comme la génération d'images, Qstash était employé comme système de file d'attente de jobs. Le problème principal était la synchronisation des données et le coût du pré-chargement.
// Exemple simplifié de génération d'image avec Next.js et Qstash
// (Le code exact n'est pas fourni dans la vidéo, ceci est une illustration conceptuelle)
// Dans un Server Action Next.js
async function generateThumbnail(prompt: string) {
// Création d'un job Qstash pour la génération d'image en arrière-plan
const qstashJob = await qstashClient.enqueue({
url: 'https://api.example.com/generate-image-webhook',
body: { prompt },
});
// Retourne immédiatement à l'utilisateur, le client devra 'poller' pour le résultat
return { jobId: qstashJob.id, status: 'pending' };
}
// Côté client (React Component)
// Le client doit régulièrement interroger la base de données pour vérifier le statut du job
// et récupérer l'image générée une fois prête.
// Ce 'polling' est coûteux et crée un délai perçu par l'utilisateur.
Étape 2 — Migrer vers la nouvelle architecture (TanStack Start + Convex)
La nouvelle stack, NowStack, est centrée sur TanStack Start pour le frontend et Convex pour le backend et la base de données. Convex gère les bases de données, les jobs en arrière-plan et la synchronisation en temps réel, simplifiant considérablement la gestion de l'état et des données.
// Exemple simplifié de génération d'image avec TanStack Start et Convex
// (Le code exact n'est pas fourni dans la vidéo, ceci est une illustration conceptuelle)
// Dans une fonction Convex (backend)
// Cette fonction est appelée depuis le frontend et exécute un job en arrière-plan.
// Convex gère automatiquement la mise à jour de la base de données et la synchronisation en temps réel.
export const generateThumbnail = mutation({
args: { prompt: v.string() },
handler: async (ctx, { prompt }) => {
// Création d'un job en arrière-plan pour la génération d'image
const jobId = await ctx.scheduler.run({
func: api.ai.generateImage,
args: { prompt },
// [Note de l'éditeur : options de planification ou de retry à vérifier dans la documentation officielle de Convex]
});
// Met à jour la base de données avec le statut 'pending' et l'ID du job
// Convex synchronise cette mise à jour en temps réel avec le frontend
await ctx.db.insert("thumbnails", { jobId, status: "pending", imageUrl: null });
return { jobId };
},
});
// Dans une fonction Convex (job en arrière-plan)
export const generateImage = internalAction({
args: { prompt: v.string() },
handler: async (ctx, { prompt }) => {
// Logique de génération d'image via une API externe (ex: OpenAI)
const imageUrl = await callExternalAIGeneration(prompt);
// Met à jour la base de données avec l'URL de l'image générée et le statut 'completed'
// Convex synchronise cette mise à jour en temps réel avec le frontend
await ctx.db.patch(thumbnailId, { status: "completed", imageUrl });
},
});
// Côté client (TanStack Start / React Component)
// Le frontend s'abonne aux données Convex et reçoit les mises à jour en temps réel.
// Pas besoin de 'polling' manuel.
function ThumbnailDisplay({ thumbnailId }) {
const thumbnail = useQuery(api.thumbnails.get, { id: thumbnailId });
if (!thumbnail) return <div>Loading...</div>;
if (thumbnail.status === 'pending') return <div>Generating thumbnail...</div>;
return <img src={thumbnail.imageUrl} alt="Generated Thumbnail" />;
}
Tableaux comparatifs



| Caractéristique | Ancienne Stack (Next.js + Prisma + PostgreSQL) | Nouvelle Stack (TanStack Start + Convex) |
|---|---|---|
| Architecture | Client-side (avec pré-chargement) et Server-side (avec Qstash pour les jobs) | Full-stack (frontend et backend) avec synchronisation en temps réel |
| Synchronisation des données | Nécessite du 'polling' côté client pour les mises à jour asynchrones, gestion manuelle du cache | Synchronisation automatique et en temps réel via Convex, pas de 'polling' nécessaire |
| Gestion des jobs | Qstash pour les tâches de fond, nécessite une intégration séparée | Jobs intégrés directement dans Convex, gestion simplifiée |
| Coût | Le pré-chargement et le 'polling' peuvent entraîner des coûts élevés en requêtes | Optimisé pour le coût grâce à la synchronisation en temps réel et la gestion efficace des jobs |
| Expérience Développeur (DX) | Plus complexe à maintenir, gestion manuelle de la synchronisation et du cache, débogage des logs | Simplifiée, moins de code à écrire pour la synchronisation, l'IA peut aider au débogage et à la correction des bugs |
| Performance perçue | Délais de chargement et d'affichage dus au 'polling' et au pré-chargement | Affichage instantané des données et des générations grâce à la synchronisation en temps réel |
⚠️ Erreurs fréquentes et pièges
- Désynchronisation des données : Avec l'ancienne stack, il était fréquent que les données affichées côté client ne soient pas à jour avec la base de données, nécessitant des invalidations de cache manuelles ou du 'polling' coûteux. Solution avec Convex : Convex assure une synchronisation automatique et en temps réel, éliminant ce problème structurel.
- Coûts de pré-chargement excessifs : Le pré-chargement de pages entières avec Next.js peut entraîner des requêtes inutiles et des coûts accrus, surtout pour des applications dynamiques. Solution avec Convex : Convex charge les données à la demande et les synchronise en temps réel, réduisant les requêtes inutiles.
- Complexité du débogage en production : Lire les logs, identifier la logique défaillante et déboguer les problèmes en production était une tâche ardue avec l'ancienne stack. Solution avec l'IA : L'intégration d'outils d'IA permet de corriger automatiquement les bugs en production en analysant les logs, le code et en déployant des correctifs.
- Gestion des jobs asynchrones : L'utilisation de systèmes de jobs externes comme Qstash ajoute une couche de complexité pour gérer les workflows et les retries. Solution avec Convex : Convex intègre nativement la gestion des jobs en arrière-plan, simplifiant le code et la maintenance.
Glossaire
Pré-chargement (Prefetching) : Technique où les ressources (pages, données) sont chargées en arrière-plan avant que l'utilisateur ne les demande explicitement, dans le but d'accélérer la navigation.
Polling : Méthode où un client interroge régulièrement un serveur pour vérifier si de nouvelles données sont disponibles ou si un état a changé.
Server-Side Rendering (SSR) : Technique de rendu où les pages web sont générées sur le serveur avant d'être envoyées au navigateur, améliorant le temps de chargement initial et le SEO.
Points clés à retenir
- La migration vers TanStack Start et Convex a permis une amélioration drastique de l'expérience utilisateur et développeur pour l'application Subfast.
- Convex offre une synchronisation des données en temps réel, éliminant le besoin de 'polling' et de gestion manuelle du cache.
- L'architecture de Convex simplifie la gestion des jobs en arrière-plan et la base de données, réduisant la complexité du code.
- L'intégration de l'IA dans le processus de développement et de débogage est un atout majeur pour corriger rapidement les bugs en production.
- La stack NowStack est conçue pour être économique, avec un coût de 0€ jusqu'à ce que l'application génère des revenus.
Ressources
- NowStack (site mentionné dans la vidéo)
- Thumbfa.st (application migrée)
- Convex (documentation officielle)
- TanStack Start (documentation officielle)