Entwickler von Event-Foto-Apps haben nun eine konkrete Checkliste, um Browser-Uploads in überfüllten Veranstaltungsorten stabil zu halten. Ein einzelner Nutzer wechselt möglicherweise zwischen WLAN und Mobilfunk, während Dutzende von Geräten um denselben Hotspot konkurrieren. Der Leitfaden zeigt, wie man verhindert, dass ein Foto nach einer „Upload abgeschlossen“-Toast-Benachrichtigung verschwindet, selbst wenn der Gast das Telefon sperrt oder das Netzwerk kurzzeitig schwankt.
Warum gewöhnliche Uploads bei Hochzeiten und Festivals scheitern
In einem Büro sitzt ein Laptop an einer stabilen Ethernet-Verbindung und ein einzelner Nutzer klickt auf „Senden“. Bei einer Hochzeitsfeier oder einem Musikfestival kann dieselbe Aktion eine Kaskade von Problemen auslösen: Der Gast geht von der Zeremonienhalle zum Parkplatz, der Router bricht unter hunderten Telefonen zusammen oder das Telefon verliert das WLAN und wechselt in den Mobilfunk. Der Browser hat möglicherweise bereits jedes Byte an den Server gestreamt, aber der Server hat die Datei noch nicht dauerhaft im Speicher abgelegt. Wenn die Benutzeroberfläche den Erfolg in dem Moment meldet, in dem der Fortschrittsbalken 100 % erreicht, löscht der Gast das Foto möglicherweise, was den Organisator mit einer fehlenden Datei zurücklässt.
Die versteckten Kosten von „einfach hochladen“
Ein naiver Ansatz behandelt den Upload als einen einzigen HTTP-POST. Das funktioniert, wenn die Verbindung stabil ist, aber in einem überlasteten Netzwerk zwingt jede Unterbrechung dazu, die gesamte Datei von vorne zu beginnen. Nutzer werden frustriert und die Bandbreite schlägt aus, wenn Dutzende von Telefonen gleichzeitig einen erneuten Versuch starten. Das Aufteilen der Datei in Chunks und das Verfolgen jedes einzelnen Teils erhöht die Komplexität, aber der Gewinn ist ein vorhersagbarer Transfer mit geringem Overhead, der Netzwerkwechsel übersteht.
Aufbau eines fortsetzbaren, chunkbasierten Upload-Systems
Nachfolgend finden Sie ein praktisches Schritt-für-Schritt-Rezept.
1. Generieren Sie eine Upload-ID, bevor Daten den Browser verlassen
Erstellen Sie lokal eine universell eindeutige Kennung (UUID) und senden Sie diese als erste Anfrage an den Server. Der Server registriert eine Sitzung unter dieser ID. Wenn der Browser später aufgrund eines Timeouts einen erneuten Versuch unternimmt, enthält er dieselbe UUID, sodass der Server die Sitzung erkennt und einen doppelten Eintrag vermeidet. Dies macht den Workflow idempotent – das wiederholte Senden derselben Anfrage hat keine negativen Auswirkungen.
2. Die Datei in 5–10 MB große Chunks aufteilen
Die Chunk-Größe ist ein Kompromiss. Kleine Chunks (unter 1 MB) erhöhen die Anzahl der HTTP-Anfragen und den damit verbundenen Header-Overhead. Sehr große Chunks machen jede Unterbrechung kostspielig, da der Client ein großes Stück erneut senden muss. Für typische Fotos und kurze Videos bietet eine Größe von 5–10 MB ein ausgewogenes Verhältnis: Jede Anfrage wird schnell genug abgeschlossen, um die Benutzeroberfläche reaktionsfähig zu halten, während die Anzahl der Anfragen überschaubar bleibt.
3. Die Anzahl der parallelen Uploads begrenzen
Mobile Browser können viele Verbindungen öffnen, aber in einem überlasteten WLAN konkurriert jeder zusätzliche Stream um die begrenzte Bandbreite. Zwei stabile Streams sind besser als acht konkurrierende. Nutzen Sie die navigator.connection API, um Bedingungen mit geringer Bandbreite zu erkennen und die Parallelität automatisch zu reduzieren.
4. Den Upload-Status in IndexedDB speichern
Speichern Sie die Upload-ID, die Liste der bereits gesendeten Chunks und alle vom Server bestätigten Offsets in der IndexedDB des Browsers. Wenn die Seite neu geladen wird oder der Nutzer den Tab schließt, kann der Client den Status beim nächsten Laden wiederherstellen. Wenn der Nutzer die Seite erneut öffnet, fordern Sie ihn auf, dieselbe Datei auszuwählen; die gespeicherten Metadaten ermöglichen es, den Upload ab dem letzten bestätigten Chunk fortzusetzen, anstatt von vorne zu beginnen.
5. Echte Netzwerkänderungen erkennen, nicht nur navigator.onLine
Das Flag navigator.onLine meldet oft „online“, selbst wenn die Verbindung unbrauchbar ist. Setzen Sie stattdessen ein kurzes Request-Timeout (z. B. 5 Sekunden) für jeden Chunk. Wenn ein Timeout auftritt, behandeln Sie das Netzwerk als offline. Wenn die Verbindung wiederhergestellt ist, fragen Sie den Server nach der Liste der Chunks, die er bereits besitzt, und setzen Sie den Upload dann nur für die fehlenden Teile fort. Dies verhindert das Senden redundanter Daten nach einer kurzen Unterbrechung.
6. Exponential Backoff mit Jitter für Wiederholungsversuche anwenden
Wenn die Geräte vieler Gäste bemerken, dass das Netzwerk wieder verfügbar ist, könnten sie alle im selben Moment einen erneuten Versuch starten und den Server überlasten. Exponential Backoff sorgt dafür, dass jeder Wiederholungsversuch länger wartet als der vorherige, während Jitter einen zufälligen kleinen Versatz hinzufügt. Die Kombination verteilt den Retry-Verkehr über einige Sekunden und verhindert so eine plötzliche Lastspitze.
7. Mehrschichtiges, barrierefreies Feedback anzeigen
Ein dreistufiger Statusbalken kommuniziert den tatsächlichen Zustand der Datei:
- Empfangen – der Server hat jeden Chunk gespeichert und die Datei als vollständig markiert.
- Vorbereitung – der Server erstellt Vorschaubilder oder transkodiert ein Video.
- Verfügbar – der Organisator kann die Datei ansehen oder herunterladen.
Verlassen Sie sich nicht allein auf Farben; kombinieren Sie Icons mit kurzem Text, damit auch Screenreader-Nutzer den Fortschritt verstehen.
Was kann trotzdem noch schiefgehen?
Selbst ein gut entwickelter, fortsetzbarer Upload kann bei einigen Edge Cases scheitern.
Worauf Sie als Nächstes achten sollten
Die Web-Plattform entwickelt sich ständig weiter.
Fazit
Ein fortsetzbarer, in Chunks unterteilter Upload, der jedes Teil verfolgt, den Status lokal speichert und intelligente Wiederholungsversuche unternimmt, verwandelt ein unzuverlässiges Event-Netzwerk in einen verlässlichen Kanal für Gästefotos. Implementieren Sie die oben genannte Checkliste.
