Twoja pamięć podręczna ❤️

Użytkownicy, którzy spróbują załadować Twoją witrynę po raz drugi, będą korzystać z pamięci podręcznej HTTP, więc dopilnuj, by działała prawidłowo.

Ten post jest uzupełnieniem filmu Pokochaj pamięć podręczną, który jest częścią Extended Content at Chrome Dev Summit 2020. Zachęcamy do obejrzenia filmu:

Gdy użytkownicy wczytują Twoją witrynę po raz drugi, ich przeglądarka będzie używać zasobów z pamięci podręcznej HTTP, aby przyspieszyć wczytywanie. Jednak standardy buforowania w internecie sięgają 1999 roku i są dość ogólnikowo zdefiniowane. Określanie, czy plik, np. CSS lub obraz, może zostać ponownie pobrany z sieci, a czy z pamięci podręcznej, jest stosunkowo mało precyzyjne.

W tym poście omówię sensowne, nowoczesne domyślne ustawienie pamięci podręcznej, które w ogóle nie używa pamięci podręcznej. To tylko domyślne ustawienie, które oczywiście ma więcej niuansów niż samo „wyłączenie”. Czytaj dalej.

Cele

Przy drugim wczytaniu witryny pojawiają się 2 cele:

  1. Zadbaj o to, aby użytkownicy mieli dostęp do najnowszej wersji aplikacji. Jeśli wprowadzisz jakieś zmiany, powinny one szybko zostać odzwierciedlone.
  2. Wykonaj czynność 1, pobierając jak najmniejsze dane z sieci.

Ogólnie rzecz biorąc, chcesz wysyłać do klientów tylko najmniejsze zmiany, gdy ponownie wczytują Twoją witrynę. Ustrukturyzowanie witryny w sposób zapewniający najbardziej wydajną dystrybucję każdej zmiany jest trudne (więcej informacji na ten temat znajdziesz poniżej i w filmie).

Pamiętaj jednak, że w przypadku buforowania dostępne są też inne opcje – być może zdecydujesz się pozostawić witrynę w pamięci podręcznej HTTP przeglądarki użytkownika na dłuższy czas, aby jej obsługa nie wymagała żadnych żądań sieciowych. Możesz też utworzyć skrypt service worker, który będzie wyświetlać witrynę całkowicie w trybie offline, zanim sprawdzisz, czy jest aktualna. Jest to opcja ekstremalna, która jest odpowiednia i używana w przypadku wielu aplikacji offline, ale internet nie musi być ograniczony tylko do pamięci podręcznej ani nawet do sieci.

Tło

Jako programiści stron internetowych jesteśmy przyzwyczajeni do koncepcji „nieaktualnej pamięci podręcznej”. Jednak prawie instynktownie znamy dostępne narzędzia, które mogą rozwiązać ten problem: „twarde odświeżenie”, otwarcie okna incognito lub użycie kombinacji narzędzi programistycznych przeglądarki w celu wyczyszczenia danych witryny.

Stali użytkownicy w internecie nie mają tego samego luksusu. Chociaż naszym głównym celem jest zapewnienie użytkownikom świetnej zabawy podczas korzystania z drugiego poziomu ładowania, ważne jest też, aby nie tracili czasu ani nie utknęli. (Jeśli chcesz dowiedzieć się, jak prawie udało nam się zablokować stronę web.dev/live, obejrzyj ten film)

Oto kilka informacji ogólnych: bardzo częstą przyczyną „nieaktualnej pamięci podręcznej” jest domyślne używanie pamięci podręcznej z 1999 r. Używa nagłówka Last-Modified:

Diagram pokazujący, jak długo różne zasoby są przechowywane w pamięci podręcznej przez przeglądarkę użytkownika
Komponenty wygenerowane w różnych momentach (w kolorze szarym) są przechowywane w pamięci podręcznej przez różne czasy, więc przy drugim wczytaniu może zostać uwzględniona kombinacja nowych zasobów z pamięci podręcznej i nowych.

Każdy wczytywany plik jest przechowywany przez dodatkowe 10% jego aktualnego okresu ważności, jak widzi go Twoja przeglądarka. Jeśli na przykład index.html zostało utworzone miesiąc temu, będzie przechowywane w pamięci podręcznej przeglądarki przez około 3 dni.

W przeszłości była to chęć okazania dobrej woli, ale biorąc pod uwagę ścisłą integrację współczesnych witryn, takie domyślne zachowanie może spowodować, że użytkownik będzie miał pliki przeznaczone do różnych wersji Twojej witryny (np. plik JS z wersji z wtorku i plik CSS z wersji z piątku), ponieważ te pliki nie zostały zaktualizowane dokładnie w tym samym czasie.

dobrze oświetlona ścieżka;

Obecnie domyślnym ustawieniem pamięci podręcznej jest brak korzystania z niej i używanie CDN do dostarczania treści użytkownikom. Za każdym razem, gdy użytkownik wczyta Twoją witrynę, będzie ona sprawdzać, czy jest aktualna. Żądanie to będzie miało niską latencję, ponieważ będzie dostarczane przez sieć CDN zlokalizowaną geograficznie blisko każdego użytkownika.

Możesz skonfigurować hosta internetowego, aby odpowiadał na żądania internetowe za pomocą tego nagłówka:

Cache-Control: max-age=0,must-revalidate,public

Oznacza to, że plik jest ważny przez nieokreślony czas i należy go zweryfikować w sieci, zanim będzie można go ponownie użyć (w przeciwnym razie jest on tylko „zalecany”).

Ten proces weryfikacji jest stosunkowo tani pod względem przesyłanych bajtów – jeśli duży plik obrazu się nie zmienił, przeglądarka otrzyma małą odpowiedź 304, ale kosztem opóźnienia, ponieważ użytkownik musi się jeszcze połączyć z siecią, aby się tego dowiedzieć. To jest główny minus tej metody. Może ono działać bardzo dobrze w przypadku osób korzystających z szybkich połączeń w krajach rozwiniętych, w których wybrany przez Ciebie CDN ma świetne pokrycie, ale nie będzie działać dobrze w przypadku osób korzystających z wolniejszych połączeń komórkowych lub z niedostatecznej infrastruktury.

Niezależnie od tego, jest to nowoczesne podejście, które jest domyślnie używane w popularnej sieci CDN Netlify, ale można je skonfigurować w prawie każdej sieci CDN. W przypadku Hostingu Firebase możesz umieścić ten nagłówek w sekcji hostingu w pliku firebase.json:

"headers": [
  // Be sure to put this last, to not override other headers
  {
    "source": "**",
    "headers": [ {
      "key": "Cache-Control",
      "value": "max-age=0,must-revalidate,public"
    }
  }
]

Choć nadal polecam to ustawienie, to jest to rozsądne ustawienie domyślne. Czytaj dalej, aby dowiedzieć się, jak wprowadzić zmiany domyślne.

Adresy URL zawierające odciski cyfrowe

Dodanie do nazwy zasobów, obrazów itp. dostępnych w Twojej witrynie hasha zawartości pliku zapewni, że te pliki będą zawsze zawierały unikalną zawartość. W efekcie będą one mieć nazwy np. sitecode.af12de.js. Gdy Twój serwer odpowiada na żądania tych plików, możesz bezpiecznie poinstruować przeglądarki użytkowników, aby buforowały je przez dłuższy czas, konfigurując je za pomocą tego nagłówka:

Cache-Control: max-age=31536000,immutable

Ta wartość to rok w sekundach. Zgodnie ze specyfikacją oznacza to „na zawsze”.

Ważne, aby nie generować tych haszów ręcznie – to zbyt wiele pracy ręcznej. W tym celu możesz użyć narzędzi takich jak Webpack, Rollup itp. Więcej informacji na ten temat znajdziesz w raporcie dotyczącym narzędzi.

Pamiętaj, że w przypadku adresów URL z odciskami cyfrowymi nie tylko JavaScript może być korzystny – zasoby takie jak ikony, CSS i inne stałe pliki danych również mogą być nazywane w ten sposób. (Pamiętaj, aby obejrzeć film powyżej, aby dowiedzieć się więcej o podziale kodu, który pozwala zmniejszyć ilość kodu wysyłanego przy każdej zmianie w witrynie).

Niezależnie od tego, jak Twoja witryna radzi sobie z buforowaniem, tego typu pliki z odciskami palców są niezwykle cenne dla każdej witryny, którą tworzysz. Większość witryn nie jest aktualizowana przy każdej wersji.

Oczywiście nie możemy w ten sposób zmienić nazwy „przyjaznych” stron dla użytkowników: zmieniając nazwę pliku index.html na index.abcd12.html. Tych „przyjaznych” adresów URL nie można w ten sposób przemianować ani przechowywać w pamięci podręcznej, co prowadzi mnie do możliwego kompromisu.

Środek

W przypadku pamięci podręcznej jest oczywiście miejsce na kompromis. Przedstawiłem 2 skrajne opcje: nigdyzawsze. Będzie też kilka plików, które warto przechowywać w pamięci podręcznej przez jakiś czas, np. wspomniane powyżej „przyjazne” adresy URL.

Jeśli chcesz przechowywać w pamięci podręcznej te „przyjazne” adresy URL i ich kod HTML, warto sprawdzić, jakie zależności zawierają, jak mogą być przechowywane w pamięci podręcznej oraz jak przechowywanie w pamięci podręcznej ich adresów URL może na Ciebie wpłynąć. Przyjrzyjmy się stronie HTML, która zawiera taki obraz:

<img src="/images/foo.jpeg" loading="lazy" />

Jeśli zaktualizujesz lub zmienisz swoją witrynę, usuwając lub zmieniając ten obraz wczytywany opóźnienie, użytkownicy, którzy wyświetlają wersję HTML z pamięci podręcznej, mogą zobaczyć nieprawidłowy obraz lub obraz może w ogóle nie być widoczny, ponieważ nadal mają w pamięci podręcznej oryginalny obraz /images/foo.jpeg, gdy powracają do Twojej witryny.

Jeśli zachowasz ostrożność, te zmiany mogą nie mieć wpływu na Twoją pracę. Należy jednak pamiętać, że gdy Twoja witryna jest przechowywana w pamięci podręcznej przez użytkowników, nie istnieje już tylko na Twoich serwerach. Zamiast tego mogą one występować w elementach w pamięci podręcznej przeglądarek użytkowników.

Ogólnie większość poradników na temat buforowania mówi o tego rodzaju ustawieniach – czy chcesz przechowywać dane na godzinę czy kilka godzin itd. Aby skonfigurować ten rodzaj pamięci podręcznej, użyj nagłówka podobnego do tego (który przechowuje dane w pamięci podręcznej przez 3600 sekund, czyli przez godzinę):

Cache-Control: max-age=3600,immutable,public

Jeszcze jedna uwaga. Jeśli tworzysz treści aktualne, które zwykle są dostępne dla użytkowników tylko raz (np. artykuły informacyjne), nie powinny one być przechowywane w pamięci podręcznej. Użyj więc domyślnych ustawień. Często przeszacowujemy wartość buforowania w porównaniu z chęcią użytkownika, aby zawsze widzieć najnowsze i najlepsze treści, takie jak istotna aktualizacja wiadomości lub bieżącego wydarzenia.

Opcje inne niż HTML

Oprócz HTML, inne opcje plików z poziomu pośredniego to:

  • Ogólnie szukaj zasobów, które nie wpływają na inne

    • Na przykład: unikaj kodu CSS, ponieważ powoduje on zmiany w sposobie renderowania kodu HTML.
  • duże obrazy używane w ramach aktualnych artykułów;

    • Twoi użytkownicy zapewne nie będą odwiedzać pojedynczego artykułu więcej niż kilka razy, więc nie zapisuj w pamięci podręcznej zdjęć ani obrazów głównych
  • Zasób, który reprezentuje coś, co samo ma czas trwania

    • Dane JSON o pogodzie mogą być publikowane tylko co godzinę, więc możesz przechowywać w pamięci podręcznej poprzedni wynik przez godzinę – nie zmieni się on w Twoim oknie
    • Kompilacje projektu open source mogą być ograniczone pod względem szybkości, dlatego należy przechowywać w pamięci podręcznej obraz stanu kompilacji do momentu, gdy stan może się zmienić.

Podsumowanie

Gdy użytkownicy wczytują Twoją witrynę po raz drugi, oznacza to, że już Ci zaufali i chcą wrócić, aby skorzystać z Twojej oferty. Obecnie nie chodzi już tylko o skrócenie czasu wczytywania. Dostępnych jest wiele opcji, które pozwolą przeglądarce wykonywać tylko te czynności, które są niezbędne do zapewnienia szybkiego i aktualnego działania.

Buforowanie nie jest nową koncepcją w internecie, ale być może potrzebujesz sensownego domyślnego ustawienia. Zastanów się, czy nie warto użyć takiego ustawienia i włączyć lepsze strategie buforowania, gdy będziesz ich potrzebować. Dziękujemy za uwagę!

Zobacz też

Ogólny przewodnik po pamięci podręcznej HTTP znajdziesz w artykule Zapobiegaj niepotrzebnym żądaniom sieciowym dzięki pamięci podręcznej HTTP.