Twoja pamięć podręczna ❤️

Użytkownicy wczytujący Twoją witrynę po raz drugi będą korzystać z pamięci podręcznej HTTP, więc upewnij się, że działa ona prawidłowo.

Ten post jest uzupełnieniem filmu Love your cache, który był częścią rozszerzonego materiału na Chrome Dev Summit 2020. Obejrzyj ten film:

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. Standardy dotyczące pamięci podręcznej w internecie pochodzą jednak z 1999 r. i są dość ogólnie zdefiniowane – ustalenie, czy plik, np. CSS lub obraz, może zostać pobrany ponownie z sieci, czy z pamięci podręcznej, nie jest dokładną nauką.

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

Gdy witryna wczytuje się po raz 2, masz 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 punkt 1, pobierając z sieci jak najmniej danych.

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).

Przy planowaniu pamięci podręcznej możesz też brać pod uwagę inne ustawienia. Być może zdecydujesz się na przechowywanie w pamięci podręcznej przeglądarki użytkownika przez dłuższy czas, aby nie wysyłać żadnych żądań sieciowych. Możesz też stworzyć skrypt service worker, który będzie obsługiwać witrynę całkowicie offline, zanim sprawdzi, 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 deweloperzy stron internetowych jesteśmy przyzwyczajeni do idei „nieaktualnego pamięci podręcznej”. Jednak prawie instynktownie znamy dostępne narzędzia, które mogą pomóc w rozwiązaniu tego problemu: „twarde odświeżenie”, otwarcie okna incognito lub użycie kombinacji narzędzi dewelopera przeglądarki w celu wyczyszczenia danych witryny.

Zwykli użytkownicy internetu nie mają tego luksusu. Chociaż naszym głównym celem jest zapewnienie użytkownikom świetnej zabawy podczas drugiego ładowania, ważne jest też, aby nie mogli się nudzić ani utknąć. (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
Zasoby wygenerowane w różnych momentach (w kolorze szarym) będą przechowywane w pamięci podręcznej przez różny czas, dlatego podczas 2 załadowania może zostać wyświetlona kombinacja zasobów z pamięci podręcznej i nowych zasobów

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, pozostanie w pamięci podręcznej przeglądarki przez około 3 dni.

W przeszłości była to chęć okazania użytkownikom dobrej woli, ale ze względu na ścisłą integrację współczesnych witryn internetowych to 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 jest brak buforowania 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ć u 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"
    }
  }
]

Nadal uważam, że to rozsądne ustawienie domyślne, ale to tylko ustawienie domyślne. Czytaj dalej, aby dowiedzieć się, jak wprowadzić zmiany w ustawieniach domyślnych.

Adresy URL z odciskiem cyfrowym

Dodanie do nazwy zasobów, obrazów itp. hashów zawartości plików wyświetlanych w Twojej witrynie zapewni, że te pliki będą zawsze zawierały unikalną zawartość. W efekcie będą one mieć nazwy np. sitecode.af12de.js. Gdy serwer odpowiada na żądania dotyczące tych plików, możesz bezpiecznie zlecić przeglądarkom końcowego użytkownika, aby przechowywały je w pamięci podręcznej przez długi czas. Aby to zrobić, skonfiguruj 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”.

Nie generuj tych haszy ręcznie – to zbyt dużo pracy. W tym celu możesz użyć narzędzi takich jak Webpack, Rollup itp. Więcej informacji znajdziesz w raporcie dotyczącym narzędzi.

Pamiętaj, że adresy URL z odciskami palców mogą być przydatne nie tylko w przypadku kodu JavaScript. W ten sposób można też nazywać zasoby takie jak ikony, pliki CSS i inne niezmienne pliki danych. (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 podchodzi do buforowania, 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 przeznaczonych dla użytkowników. Nie możemy też zmienić nazwy pliku index.html na index.abcd12.html – to niemożliwe. Nie możesz też wymagać od użytkowników, aby za każdym razem, gdy wczytują Twoją witrynę, przechodzili do nowego adresu URL. Tych „przyjaznych” adresów URL nie można w ten sposób zmienić i zapisać 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 ich adresów URL przez jakiś czas może na Ciebie wpłynąć. Spójrzmy na stronę 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 być niewidoczny, ponieważ nadal mają w pamięci podręcznej oryginalny obraz /images/foo.jpeg, gdy powracają do Twojej witryny.

Jeśli zachowasz ostrożność, nie powinno to mieć wpływu na Twoje konto. 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.

Większość przewodników dotyczących pamięci podręcznej zawiera informacje o tym rodzaju ustawieniach – czy chcesz przechowywać dane w pamięci podręcznej przez godzinę, 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 1 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;

    • Użytkownicy prawdopodobnie nie będą czytać danego artykułu więcej niż kilka razy, więc nie przechowuj zdjęć ani obrazów nagłówka w pamięci podręcznej na zawsze, ponieważ zajmie to zbyt dużo miejsca na dane.
  • Zasób, który reprezentuje coś, co 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 załaduj obraz stanu kompilacji do pamięci podręcznej, dopóki stan nie ulegnie zmianie.

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ć lepszych strategii buforowania, gdy ich potrzebujesz. Dziękujemy za uwagę!

Zobacz też

Ogólny przewodnik dotyczący pamięci podręcznej HTTP znajdziesz w artykule Zapobieganie zbędnym żądaniom sieciowym dzięki pamięci podręcznej HTTP.