Strony statyczne działają, podczas gdy są publikowane ponownie
Ponowna publikacja strony statycznej w Mythex kiedyś najpierw usuwała żywe pliki, a dopiero potem wysyłała nowy build, więc przez cały czas wysyłania część odwiedzających dostawała stronę 404 albo stronę, której skrypty były niedostępne. Nieudane wysłanie mogło zostawić stronę pustą albo na wpół nową. Teraz nowy build nadpisuje stary, strony idą na końcu, a pozostałości są usuwane kilka minut później. Druga poprawka sprawia, że ponowna publikacja pojawia się w ciągu kilku sekund zamiast minuty — albo, w przypadku plików takich jak logo, nawet do doby.
Jak serwowana jest strona statyczna
Strona statyczna to taka, która składa się wyłącznie z plików: stron HTML, JavaScriptu, CSS, obrazów. Gdy publikujesz ją w Mythex, budujemy ją, wysyłamy wynik do magazynu obiektów w folderze Twojej strony i serwujemy przez sieć brzegową — serwery blisko odwiedzających, które pobierają pliki z magazynu i trzymają ich kopie przez jakiś czas. (Jeśli to dla Ciebie nowość, nasz przewodnik czym jest CDN wyjaśnia tę ideę.)
Z dwoma rzeczami było coś nie tak: z kolejnością, w jakiej ponowna publikacja zmieniała pliki, i z tym, jak długo trzymano stare kopie.
Problem 1: wysyłanie opróżniało stronę najpierw
Ponowna publikacja usuwała wszystko w folderze strony, a dopiero potem wysyłała nowy build. Przez cały czas wysyłania — 12 sekund dla strony z 250 plikami w naszym lokalnym teście — odwiedzający, którego żądanie nie było już w pamięci podręcznej na brzegu, dostawał 404 albo stronę HTML, której skrypty zwracały 404.
Nieudane wysłanie było gorsze. Folder był już pusty, a na jednej z dwóch ścieżek wysyłania nowy index.html mógł trafić na miejsce, zanim nie powiódł się plik. Publikacja zgłoszona jako nieudana mogła zostawić na żywo na wpół nową stronę.
Rozwiązanie: nadpisz, strony na końcu, czyszczenie później
- Nie usuwaj najpierw. Nowy build wysyłamy na stary.
- Zasoby przed stronami. Strona wymienia skrypty i style, których potrzebuje, więc strony idą na końcu. Dopóki nowe strony nie trafią na miejsce, odwiedzający dostaje starą stronę, która wymienia stare zasoby, a te są wciąż na miejscu. Gdy strony trafią, nowe zasoby, które wymieniają, są już na swoim miejscu.
- Pozostałości usuń później. Przed wysłaniem spisujemy, z czego składa się strona. Trzy minuty po udanym wysłaniu usuwamy wszystko z tej listy, czego nowy build nie nadpisał. Trzy minuty to więcej niż 60 sekund, przez które strona może być trzymana w pamięci podręcznej na brzegu i w przeglądarce, więc odwiedzający z jeszcze starą stroną znajdzie zasoby, które ona wymienia.
- W razie wątpliwości niczego nie usuwaj. Jeśli spis przed wysłaniem się nie uda, nic nie jest czyszczone. Pozostałe pliki są nieszkodliwe, a następna publikacja je usunie. Usuwanie bez wiedzy, co tam było, to sposób, w jaki strona kończy pusta.
Nieudane wysłanie zostawia teraz poprzednią stronę dokładnie taką, jaka była.
Przetestowaliśmy to od początku do końca lokalnie, używając prawdziwego skryptu wysyłania, prawdziwej trasy wysyłania i serwowania z magazynu, oraz odwiedzających trafiających na zimną pamięć podręczną brzegu. Przy starym kodzie 55 z 91 wizyt było zepsutych podczas ponownej publikacji, a 61 z 92 podczas nieudanej. Przy nowym kodzie było 0 zepsutych wśród około 3500 wizyt obejmujących obie ścieżki wysyłania, nieudaną próbę i publikację po niej — a dokładnie te pozostałości, które miały zostać usunięte, zostały usunięte.
Problem 2: ponowna publikacja za długo się pokazywała
Nawet gdy wysyłanie przebiegało dobrze, zmiany pojawiały się powoli. Brzeg trzymał kopię strony przez 60 sekund, a każdego innego pliku przez dobę, i tak też mówił przeglądarkom. Pliki o stałej nazwie — logo.png, czcionka, cokolwiek z folderu public/ — mogły pokazywać starą wersję przez dobę po ponownej publikacji.
Rozwiązanie: kopie plików pod numerem builda
Gdy brzeg pyta nasze API, gdzie mieszka strona, odpowiedź zawiera teraz znacznik builda, który zmienia się przy każdej publikacji. Brzeg zapisuje swoje kopie pod tym znacznikiem. Publikacja staje się więc zupełnie nowym zestawem kluczy pamięci podręcznej, gdy tylko minie 30-sekundowe wyszukiwanie na brzegu. Stare kopie po prostu nigdy nie są już znajdowane, więc brzeg może trzymać kopie przez dobę, nigdy nie serwując jednej, która przekroczyła publikację, która ją zastąpiła.
Przeglądarki dostają dwie różne reguły:
- Zhaszowane wyjście builda — pliki takie jak
assets/index-CzLcxDO8.js, których nazwa zmienia się, gdy zmienia się treść — są przechowywane przez rok i oznaczone jako niezmienne. Pod tą nazwą nigdy nie mogą być nieaktualne. - Wszystko inne — strony i pliki o stałej nazwie, jak logo — jest oznaczone jako
no-cache, czyli „sprawdź przed użyciem”. Jeśli nic się nie zmieniło, odpowiedzią jest mały304 Not Modifiedbez treści, odkąd respektujemy sprawdzenie przeglądarkiIf-None-Match.
Rozróżnienie tych dwóch wymaga uwagi: plik skopiowany z public/assets/ zachowuje własną nazwę, a cachowanie assets/logo.png na rok przypięłoby stare logo na rok. Dlatego plik liczy się jako zhaszowany tylko wtedy, gdy jest w folderze wyjściowym builda i jego nazwa ma segment wyglądający na hasz, a nie zwykłe słowo.
Lokalnie nowa strona i logo były widoczne 6 sekund po tym, jak publikacja weszła na żywo. Wcześniej było to 60 sekund dla strony i doba dla logo.
Dwie mniejsze poprawki po drodze
- Puste strony z żądań HEAD. Żądanie
HEADpyta o nagłówki strony bez jej treści. Zapisywaliśmy w pamięci podręcznej te puste odpowiedzi, więc kolejny odwiedzający tej strony dostawał pustą stronę. OdpowiedziHEADnie są już cachowane. - Prawdziwa strona dla „nic tu nie ma”. Adres bez aplikacji dostawał kiedyś zwykły tekst „Ta opublikowana aplikacja jest offline lub link nie został znaleziony” z kodem błędu 502. Teraz dostaje porządną stronę „Tu nie ma aplikacji” ze statusem 404 i drogą powrotu do Mythex dla właściciela. Nieznane własne domeny dostają tę samą stronę.
Co z tego wynieśliśmy
- Kolejność jest częścią poprawności. Te same pliki wysłane w innej kolejności to różnica między zepsutą a działającą stroną.
- Usuwaj późno i tylko to, co znasz. Czyszczenie spisem zrobionym przed wysłaniem jest bezpieczne; opróżnianie folderu i liczenie na to, że wysyłanie się skończy, nie jest.
- Cachuj według wersji, a nie według czasu. Czasy wygaśnięcia to zgadywanie, kiedy treść się zmienia. Klucz, który zmienia się wraz z buildem, to fakt.
Powiązane: twoja opublikowana aplikacja pozostaje dostępna podczas ponownej publikacji. Więcej o publikacji znajdziesz w dokumentacji.