Checkpoint: Résolution du problème de latence d'affichage avec double requestAnimationFrame : cette technique garantit que le navigateur peint l'animation à l'écran avant de bloquer sur le fetch. Le premier requestAnimationFrame permet à React de mettre à jour l'état, le second force le navigateur à afficher visuellement l'animation avant de démarrer l'upload. Déployé sur le VPS de production.

This commit is contained in:
Manus
2026-01-30 09:37:18 -05:00
parent 1bbbe842b5
commit e68949baeb
2 changed files with 44 additions and 41 deletions

View File

@@ -196,53 +196,54 @@ function UploadAttestationDialog({
return;
}
// Forcer le rendu synchrone de l'interface AVANT de démarrer l'upload
flushSync(() => {
setUploading(true);
setUploadProgress(0);
});
// Afficher immédiatement l'état de chargement
setUploading(true);
setUploadProgress(0);
// Démarrer l'upload de manière asynchrone
(async () => {
try {
const formData = new FormData();
formData.append('file', file);
// Utiliser requestAnimationFrame pour garantir que le navigateur
// affiche l'animation AVANT de bloquer sur le fetch
requestAnimationFrame(() => {
requestAnimationFrame(async () => {
try {
const formData = new FormData();
formData.append('file', file);
const progressInterval = setInterval(() => {
setUploadProgress(prev => {
if (prev >= 90) return prev;
return prev + 10;
});
}, 200);
const progressInterval = setInterval(() => {
setUploadProgress(prev => {
if (prev >= 90) return prev;
return prev + 10;
});
}, 200);
const response = await fetch('/api/upload-file', {
method: 'POST',
body: formData,
});
const response = await fetch('/api/upload-file', {
method: 'POST',
body: formData,
});
clearInterval(progressInterval);
setUploadProgress(100);
clearInterval(progressInterval);
setUploadProgress(100);
if (!response.ok) {
throw new Error('Erreur lors de l\'upload');
}
if (!response.ok) {
throw new Error('Erreur lors de l\'upload');
}
const data = await response.json();
setFileData({
nomFichier: file.name,
urlFichier: data.url,
s3Key: data.key,
typeFichier: file.type,
tailleFichier: file.size,
});
toast.success('Fichier uploadé avec succès');
} catch (error) {
toast.error('Erreur lors de l\'upload du fichier');
setUploadProgress(0);
} finally {
setUploading(false);
}
})(); // Fermer et exécuter la fonction async
const data = await response.json();
setFileData({
nomFichier: file.name,
urlFichier: data.url,
s3Key: data.key,
typeFichier: file.type,
tailleFichier: file.size,
});
toast.success('Fichier uploadé avec succès');
} catch (error) {
toast.error('Erreur lors de l\'upload du fichier');
setUploadProgress(0);
} finally {
setUploading(false);
}
}); // Fermer requestAnimationFrame interne
}); // Fermer requestAnimationFrame externe
}}
/>
</label>

View File

@@ -1476,3 +1476,5 @@
- [x] Corriger la latence d'affichage du message d'upload (forcer le rendu avant traitement)
- [x] Restructurer le flux d'upload avec useEffect pour affichage immédiat
- [x] Corriger la latence avec requestAnimationFrame pour affichage avant fetch bloquant