Twórcy aplikacji do zdjęć z wydarzeń mają teraz konkretną listę kontrolną, jak utrzymać przesyłanie plików przez przeglądarkę w warunkach dużego zagęszczenia osób. Pojedynczy użytkownik może przełączać się między Wi-Fi a siecią komórkową, podczas gdy dziesiątki urządzeń walczą o ten sam hotspot. Przewodnik pokazuje, jak zapobiec zniknięciu zdjęcia po wyświetleniu powiadomienia „przesyłanie zakończone”, nawet jeśli gość zablokuje telefon lub nastąpi zakłócenie sieci.
Dlaczego zwykłe przesyłanie plików zawodzi na weselach i festiwalach
W biurze laptop jest podłączony do stabilnego łącza Ethernet, a pojedynczy użytkownik klika „wyślij”. Na przyjęciu weselnym lub festiwalu muzycznym ta sama czynność może wywołać lawinę problemów: gość idzie z sali obrzędowej na parking, router nie wyrabia pod naporem setek telefonów lub telefon traci połączenie z Wi-Fi i przełącza się na sieć komórkową. Przeglądarka mogła przesłać każdy bajt na serwer, ale serwer nie zapisał jeszcze pliku w pamięci masowej. Jeśli interfejs użytkownika (UI) ogłosi sukces w momencie, gdy pasek postępu osiągnie 100%, gość może usunąć zdjęcie, pozostawiając organizatora z brakującym plikiem.
Ukryty koszt podejścia „po prostu prześlij”
Naiwne podejście traktuje przesyłanie jako pojedyncze żądanie HTTP POST. Działa to, gdy połączenie jest stabilne, ale w zatłoczonej sieci każde przerwanie zmusza do ponownego przesyłania całego pliku. Użytkownicy czują frustrację, a pasmo jest gwałtownie obciążane, gdy dziesiątki telefonów próbują ponowić próbę w tym samym czasie. Dzielenie pliku na fragmenty (chunks) i śledzenie każdej części dodaje złożoności, ale nagrodą jest przewidywalny transfer o niskim narzucie, który przetrwa zmiany sieci.
Budowanie systemu przesyłania plików w kawałkach z możliwością wznawiania
Poniżej znajduje się praktyczny przepis krok po kroku.
1. Wygeneruj identyfikator przesyłania przed wysłaniem jakichkolwiek danych z przeglądarki
Utwórz lokalnie uniwersalny identyfikator (UUID) i wyślij go do serwera w pierwszym żądaniu. Serwer rejestruje sesję pod tym identyfikatorem. Jeśli przeglądarka później spróbuje ponownie z powodu przekroczenia czasu oczekiwania (timeout), dołączy ten sam UUID, co pozwoli serwerowi rozpoznać sesję i uniknąć duplikatu. Dzięki temu proces staje się idempotentny — powtórzenie tego samego żądania nie ma negatywnych skutków.
2. Podziel plik na fragmenty o rozmiarze 5–10 MB
Rozmiar fragmentu to kwestia kompromisu. Małe fragmenty (poniżej 1 MB) zwiększają liczbę żądań HTTP i powiązany z nimi narzut nagłówków. Bardzo duże fragmenty sprawiają, że każde przerwanie jest kosztowne, ponieważ klient musi ponownie wysłać dużą część. Dla typowych zdjęć i krótkich filmów 5–10 MB stanowi złoty środek: każde żądanie kończy się wystarczająco szybko, aby interfejs pozostał responsywny, a liczba żądań pozostaje pod kontrolą.
3. Ogranicz liczbę równoległych przesyłań
Przeglądarki mobilne mogą otwierać wiele połączeń, ale w zatłoczonej sieci Wi-Fi każdy dodatkowy strumień konkuruje o ograniczone pasmo. Dwa stabilne strumienie są lepsze niż osiem rywalizujących ze sobą. Użyj API navigator.connection, aby wykryć warunki niskiej przepustowości i automatycznie zmniejszyć współbieżność.
4. Przechowuj stan przesyłania w IndexedDB
Przechowuj identyfikator przesyłania, listę już wysłanych fragmentów oraz wszelkie przesunięcia (offsets) potwierdzone przez serwer w bazie IndexedDB przeglądarki. Jeśli strona zostanie przeładowana lub użytkownik zamknie kartę, klient może odzyskać stan przy następnym ładowaniu. Gdy użytkownik ponownie otworzy stronę, poproś go o wybranie tego samego pliku; zapisane metadane pozwolą wznowić przesyłanie od ostatniego potwierdzonego fragmentu zamiast zaczynać od nowa.
5. Wykrywaj rzeczywiste zmiany sieci, a nie tylko navigator.onLine
Flaga navigator.onLine często raportuje status „online”, nawet gdy połączenie jest bezużyteczne. Zamiast tego ustaw krótki limit czasu żądania (np. 5 sekund) dla każdego fragmentu. Jeśli wystąpi przekroczenie czasu, potraktuj sieć jako niedostępną. Gdy połączenie powróci, zapytaj serwer o listę fragmentów, które już posiada, a następnie kontynuuj przesyłanie tylko brakujących części. Pozwala to uniknąć wysyłania duplikujących się danych po krótkiej przerwie.
6. Zastosuj wykładniczy czas oczekiwania (exponential backoff) z jitterem przy ponawianiu prób
Gdy urządzenia wielu gości zauważą powrót sieci, wszystkie mogą jednocześnie wysłać ponowione żądania, przeciążając serwer. Wykładniczy czas oczekiwania sprawia, że każda kolejna próba następuje po dłuższym czasie niż poprzednia, a jitter dodaje mały, losowy przeskok czasowy. Połączenie to rozprasza ruch ponowionych prób na kilka sekund, zapobiegając nagłym skokom obciążenia.
7. Wyświetlaj wielowarstwowe, dostępne informacje zwrotne
Trójstopniowy pasek statusu komunikuje rzeczywisty stan pliku:
- Otrzymano – serwer zapisał wszystkie fragmenty i oznaczył plik jako kompletny.
- Przygotowywanie – serwer generuje miniatury lub transkoduje wideo.
- Dostępne – organizator może wyświetlić lub pobrać plik.
Nie polegaj wyłącznie na kolorze; łącz ikony z krótkim tekstem, aby użytkownicy czytników ekranu również mogli zrozumieć postęp.
Co wciąż może pójść nie tak?
Nawet dobrze zaprojektowane przesyłanie danych z możliwością wznawiania może napotkać kilka przypadków brzegowych.
Na co zwrócić uwagę w przyszłości
Platforma internetowa stale się rozwija.
Podsumowanie
Przesyłanie danych w kawałkach z możliwością wznawiania, które śledzi każdy fragment, przechowuje stan lokalnie i inteligentnie podejmuje próby ponowienia, zmienia niestabilną sieć wydarzeń w niezawodny kanał przesyłu zdjęć gości. Wdróż powyższą listę kontrolną.
