Les développeurs d'applications de photos d'événements disposent désormais d'une liste de contrôle concrète pour maintenir les téléchargements via navigateur actifs dans des lieux bondés. Un utilisateur peut passer du Wi-Fi au réseau cellulaire alors que des dizaines d'appareils se disputent le même point d'accès. Le guide montre comment empêcher une photo de disparaître après une notification « upload complete », même si l'invité verrouille son téléphone ou si le réseau subit une micro-coupure.

Pourquoi les téléchargements ordinaires échouent lors des mariages et des festivals

Dans un bureau, un ordinateur portable est connecté à une liaison Ethernet stable et un utilisateur unique clique sur « envoyer ». Lors d'une réception de mariage ou d'un festival de musique, la même action peut déclencher une cascade de problèmes : l'invité se déplace de la salle de cérémonie vers le parking, le routeur sature sous le poids de centaines de téléphones, ou le téléphone perd le Wi-Fi et bascule sur le réseau cellulaire. Le navigateur peut avoir transmis chaque octet au serveur, mais le serveur n'a pas encore validé le fichier dans le stockage. Si l'interface utilisateur déclare le succès dès que la barre de progression atteint 100 %, l'invité peut supprimer la photo, laissant l'organisateur avec un fichier manquant.

Le coût caché du simple « téléchargez »

Une approche naïve traite le téléchargement comme un unique POST HTTP. Cela fonctionne lorsque la connexion est stable, mais sur un réseau encombré, chaque interruption oblige à recommencer l'envoi de tout le fichier. Les utilisateurs s'impatientent et les pics de bande passante surviennent lorsque des dizaines de téléphones tentent de recommencer simultanément. Diviser le fichier en morceaux (chunks) et suivre chaque partie ajoute de la complexité, mais le résultat est un transfert prévisible, à faible surcharge, qui survit aux changements de réseau.

Créer un système de téléchargement par morceaux avec reprise

Voici une recette pratique, étape par étape.

1. Générer un ID de téléchargement avant que les données ne quittent le navigateur

Créez un identifiant unique universel (UUID) localement et envoyez-le au serveur lors de la première requête. Le serveur enregistre une session sous cet ID. Si le navigateur tente ultérieurement une nouvelle tentative en raison d'un délai d'attente (timeout), il inclut le même UUID, permettant au serveur de reconnaître la session et d'éviter un doublon. Cela rend le flux de travail idempotent — répéter la même requête n'a aucun effet indésirable.

2. Diviser le fichier en morceaux de 5 à 10 Mo

La taille des morceaux est un compromis. Des morceaux de petite taille (moins de 1 Mo) augmentent le nombre de requêtes HTTP et la surcharge d'en-tête associée. Des morceaux très volumineux rendent toute interruption coûteuse car le client doit renvoyer une grande partie. Pour des photos typiques et de courtes vidéos, 5 à 10 Mo offrent un bon équilibre : chaque requête se termine assez rapidement pour que l'interface reste réactive, tout en maintenant un nombre de requêtes gérable.

3. Limiter le nombre de téléchargements parallèles

Les navigateurs mobiles peuvent ouvrir de nombreuses connexions, mais sur un réseau Wi-Fi encombré, chaque flux supplémentaire entre en compétition pour une bande passante limitée. Deux flux stables valent mieux que huit flux concurrents. Utilisez l'API navigator.connection pour détecter les conditions de faible bande passante et réduire automatiquement la concurrence.

4. Persister l'état du téléchargement dans IndexedDB

Stockez l'ID de téléchargement, la liste des morceaux déjà envoyés et tout décalage (offset) confirmé par le serveur dans l'IndexedDB du navigateur. Si la page est rechargée ou si l'utilisateur ferme l'onglet, le client peut récupérer l'état lors du prochain chargement. Lorsque l'utilisateur rouvre la page, demandez-lui de sélectionner le même fichier ; les métadonnées stockées permettent au téléchargement de reprendre à partir du dernier morceau confirmé au lieu de tout recommencer.

5. Détecter les changements de réseau réels, pas seulement navigator.onLine

Le flag navigator.onLine indique souvent « en ligne » même lorsque la connexion est inutilisable. Au lieu de cela, définissez un délai d'attente de requête court (par exemple, 5 secondes) pour chaque morceau. Si un timeout survient, considérez que le réseau est hors service. Lorsque la connectivité revient, interrogez le serveur pour obtenir la liste des morceaux qu'il possède déjà, puis continuez à télécharger uniquement les parties manquantes. Cela évite d'envoyer des données en double après une brève interruption.

6. Appliquer un backoff exponentiel avec jitter pour les tentatives de reconnexion

Lorsque les appareils de nombreux invités détectent le retour du réseau, ils pourraient tous lancer des tentatives de reconnexion au même moment, submergeant le serveur. Le backoff exponentiel fait attendre chaque tentative plus longtemps que la précédente, tandis que le jitter ajoute un petit décalage aléatoire. Cette combinaison répartit le trafic de reconnexion sur quelques secondes, évitant ainsi un pic soudain.

7. Afficher un retour d'information multicouche et accessible

Une barre de statut à trois niveaux communique l'état réel du fichier :

  • Received – le serveur a stocké chaque morceau et a marqué le fichier comme terminé.
  • Preparing – le serveur génère des miniatures ou transcode une vidéo.
  • Available – l'organisateur peut visualiser ou télécharger le fichier.

Évitez de vous appuyer uniquement sur la couleur ; associez des icônes à un texte court afin que les utilisateurs de lecteurs d'écran puissent également comprendre la progression.

Que peut-il encore mal se passer ?

Même un téléchargement avec reprise bien conçu peut se heurter à quelques cas limites.

Ce qu'il faut surveiller ensuite

La plateforme web évolue.

À retenir

Un téléchargement fractionné avec reprise, qui suit chaque segment, stocke l'état localement et réessaie intelligemment, transforme un réseau d'événements instable en un canal fiable pour les photos des invités. Appliquez la liste de contrôle ci-dessus.