Pobieranie zasobów przez sieć jest powolne i kosztowne:
- Duże odpowiedzi wymagają wielu transferów w obie strony między przeglądarką a serwerem.
- Strona nie załaduje się, dopóki wszystkie jej krytyczne zasoby nie zostaną w pełni pobrane.
- Jeśli użytkownik Twojej witryny ma abonament na mobilną transmisję danych z ograniczoną ilością danych, każde niepotrzebne żądanie sieciowe jest jego stratą pieniędzy.
Jak uniknąć zbędnych żądań sieciowych? Pamięć podręczna HTTP przeglądarki to pierwsza linia obrony. Nie musi to być najbardziej efektywne i elastyczne rozwiązanie, a Ty masz ograniczoną kontrolę nad okresem przechowywania odpowiedzi w pamięci podręcznej, ale jest skuteczne, obsługiwane we wszystkich przeglądarkach i nie wymaga dużo pracy.
Ten przewodnik zawiera podstawowe informacje o efektywnej implementacji buforowania HTTP.
Zgodność z przeglądarką
Pamięć podręczna HTTP to ogólna nazwa zbioru interfejsów API platformy internetowej obsługiwanych we wszystkich przeglądarkach:
Cache-Control
ETag
Last-Modified
Jak działa pamięć podręczna HTTP
Wszystkie żądania HTTP wysyłane przez przeglądarkę są najpierw kierowane do pamięci podręcznej przeglądarki w celu sprawdzenia, czy w pamięci podręcznej znajduje się prawidłowa odpowiedź, która może zostać wykorzystana do realizacji żądania. W przypadku dopasowania odpowiedź jest odczytywana z pamięci podręcznej, co eliminuje zarówno opóźnienia w sieci, jak i koszty przesyłania danych.
Działanie pamięci podręcznej HTTP zależy od kombinacji nagłówków żądań i nagłówków odpowiedzi. Idealnie zachowasz kontrolę zarówno nad kodem aplikacji internetowej, który określa nagłówki żądań, jak i konfiguracją serwera WWW, która określa nagłówki odpowiedzi.
Dokładniejsze omówienie znajdziesz w artykule Buforowanie HTTP w MDN.
Nagłówki żądań: pozostaw wartości domyślne (zwykle)
W żądaniach wychodzących z aplikacji internetowej należy pamiętać kilka ważnych nagłówków, ale gdy wysyła żądania, przeglądarka prawie zawsze konfiguruje je w Twoim imieniu. Nagłówki żądań, które wpływają na sprawdzanie aktualności, np. If-None-Match
i If-Modified-Since
, są wyświetlane zgodnie z interpretacją bieżących wartości w pamięci podręcznej HTTP.
To dobra wiadomość: możesz nadal umieszczać w kodzie HTML tagi takie jak <img src="my-image.png">
, a przeglądarka będzie automatycznie i bez dodatkowych działań korzystać z pamięci podręcznej HTTP.
Nagłówki odpowiedzi: skonfiguruj serwer WWW
Najważniejszy element konfiguracji buforowania HTTP to nagłówki, które serwer WWW dodaje do każdej odpowiedzi wychodzącej. Te nagłówki wpływają na skuteczne zachowanie buforowania:
Cache-Control
- Serwer może zwrócić dyrektywę
Cache-Control
, aby określić, jak i na jak długo przeglądarka i inne pośrednie pamięci podręczne mają buforować pojedynczą odpowiedź. ETag
.- Gdy przeglądarka znajdzie wygasłą odpowiedź w pamięci podręcznej, może wysłać do serwera mały token (zwykle jest to skrót zawartości pliku), aby sprawdzić, czy plik się zmienił. Jeśli serwer zwróci ten sam token, plik jest taki sam i nie trzeba go ponownie pobierać.
Last-Modified
- Nagłówek służy do tego samego celu co tag
ETag
, ale do określenia, czy zasób się zmienił, zamiast strategiiETag
opartej na treści korzysta ze strategii opartej na czasie.
Niektóre serwery WWW mają wbudowaną obsługę domyślnych ustawień tych nagłówków. Inne całkowicie pomijają nagłówki, chyba że je jednoznacznie skonfigurujesz. Szczegóły dotyczące konfigurowania nagłówków znacznie się różnią w zależności od używanego serwera WWW. Szczegółowe informacje znajdziesz w dokumentacji serwera.
Aby zaoszczędzić Ci trochę czasu, przygotowaliśmy te instrukcje konfigurowania kilku popularnych serwerów WWW:
Pominięcie nagłówka odpowiedzi Cache-Control
nie wyłącza buforowania HTTP.
Zamiast tego przeglądarki skutecznie odgadują, jaki typ zapisywania w pamięci podręcznej jest najlepszy w przypadku danego typu treści.
Prawdopodobnie zależy Ci na większej kontroli, dlatego musisz poświęcić czas na skonfigurowanie nagłówków odpowiedzi.
Których wartości nagłówków odpowiedzi użyjesz?
Podczas konfigurowania nagłówków odpowiedzi serwera WWW musisz wziąć pod uwagę 2 ważne scenariusze.
Długotrwałe buforowanie adresów URL obsługujących wersje
Załóżmy, że serwer instruuje przeglądarki, aby buforowały plik CSS w pamięci podręcznej na rok (Cache-Control: max-age=31536000
), ale projektant właśnie wprowadził aktualizację awaryjnej, którą musisz natychmiast wdrożyć. Jak powiadamiać przeglądarki o konieczności zaktualizowania „nieaktualnej” kopii pliku w pamięci podręcznej?
Nie możesz, przynajmniej nie, nie możesz zmienić adresu URL zasobu.
Po tym, jak przeglądarka zapisze odpowiedź w pamięci podręcznej, wersja z pamięci podręcznej jest używana, dopóki nie przestanie być aktualna, zgodnie z metodą max-age
lub expires
, albo do momentu jej usunięcia z pamięci podręcznej z innego powodu, na przykład z innego powodu, na przykład przez użytkownika. W efekcie różni użytkownicy mogą wczytywać różne wersje pliku podczas tworzenia strony: użytkownicy, którzy właśnie pobrali zasób, korzystają z nowej wersji, ale użytkownicy, którzy zapisali w pamięci podręcznej wcześniejszą (ale nadal ważną) kopię, korzystają ze starszej (ale nadal prawidłowej) wersji.
Aby uzyskać zarówno zapisywanie w pamięci podręcznej po stronie klienta, jak i szybkie aktualizacje, możesz zmienić adres URL zasobu i wymusić pobranie nowej odpowiedzi po każdej zmianie treści. Zwykle robi się to, umieszczając odcisk cyfrowy pliku lub numer wersji w jego nazwie, np. style.x234dff.css
.
Odpowiadając na prośby o adresy URL, które zawierają „odcisk palca” lub informacje o wersji, dodaj do swoich odpowiedzi atrybut Cache-Control: max-age=31536000
.
Ustawienie tej wartości informuje przeglądarkę, że gdy będzie musiała wczytać ten sam adres URL w ciągu następnego roku (31 536 000 sekund, maksymalna obsługiwana wartość), może od razu użyć wartości z pamięci podręcznej HTTP bez konieczności wysyłania żądań sieciowych do serwera WWW. To świetnie, ponieważ od razu udało Ci się zwiększyć niezawodność i szybkość, które wynikają z unikania sieci.
Narzędzia do tworzenia, takie jak Webpack, mogą zautomatyzować proces przypisywania odcisków cyfrowych odcisków cyfrowych do adresów URL zasobów.
Ponowna weryfikacja serwera w przypadku adresów URL bez wersji
Nie wszystkie wczytane przez Ciebie adresy URL mają różne wersje. Być może nie można dodawać kroku kompilacji przed wdrożeniem aplikacji internetowej, więc nie można dodawać haszów do adresów URL zasobów. A każda aplikacja internetowa potrzebuje plików HTML, które prawie nigdy nie zawierają informacji o wersji. Nikt nie zechce skorzystać z Twojej aplikacji internetowej, jeśli będzie chciał pamiętać, że odwiedzany URL to https://example.com/index.34def12.html
. Co więc możesz zrobić z tymi adresami URL?
Samo buforowanie HTTP nie jest wystarczające, aby całkowicie ominąć sieć. (Nie martw się – wkrótce dowiesz się więcej o skryptach service worker, które zapewniają dodatkową pomoc). Możesz jednak wykonać kilka czynności, aby żądania sieciowe były jak najszybsze i efektywne.
Te wartości Cache-Control
pomogą Ci precyzyjnie określić, gdzie i w jaki sposób przechowywane są niewersowane adresy URL:
no-cache
informuje przeglądarkę, że przed użyciem wersji adresu URL przechowywanej w pamięci podręcznej musi ona za każdym razem przeprowadzić ponowną weryfikację na serwerze.no-store
informuje przeglądarkę i inne pośrednie pamięci podręczne (np. sieci CDN), aby nigdy nie przechowywać żadnej wersji pliku.private
: przeglądarki mogą buforować plik, ale pośrednie pamięci podręczne nie.public
: odpowiedź może być przechowywana w każdej pamięci podręcznej.
Zobacz Załącznik: schemat blokowy Cache-Control
, aby zwizualizować proces wybierania wartości Cache-Control
do użycia. Cache-Control
może też akceptować listę dyrektyw rozdzielonych przecinkami. Zobacz Załącznik: Cache-Control
przykłady.
Pomóc może ustawienie ETag
lub Last-Modified
.
Jak wspomnieliśmy w nagłówkach odpowiedzi, funkcje ETag
i Last-Modified
służą do tego samego celu: określenie, czy przeglądarka musi ponownie pobrać wygasły plik z pamięci podręcznej. Zalecamy użycie ETag
, ponieważ jest on dokładniejszy.
Załóżmy, że od rozpoczęcia pobierania minęło 120 sekund, a przeglądarka zainicjowała nowe żądanie dotyczące tego samego zasobu. Najpierw przeglądarka sprawdza pamięć podręczną HTTP i znajduje poprzednią odpowiedź.
Przeglądarka nie może użyć poprzedniej odpowiedzi, ponieważ wygasła. W tym momencie przeglądarka może wysłać nowe żądanie i pobrać nową pełną odpowiedź. Jest to jednak nieefektywne, ponieważ jeśli zasób się nie zmienił, nie ma powodu, aby ponownie pobierać informacje, które już znajdują się w pamięci podręcznej.
Ten problem ma rozwiązywać tokeny weryfikacyjne ETag
. Serwer generuje i zwraca dowolny token, który jest zwykle hasz lub inny odcisk cyfrowy zawartości pliku.
Przeglądarka nie musi wiedzieć, jak jest generowany odcisk palca. Wystarczy, że wyśle ją do serwera w następnym żądaniu. Jeśli odcisk cyfrowy jest taki sam, oznacza to, że zasób nie uległ zmianie, a przeglądarka może pominąć pobieranie.
Ustawienie ETag
lub Last-Modified
znacznie usprawnia żądanie ponownej weryfikacji, ponieważ zezwala na uruchamianie nagłówków żądań If-Modified-Since
lub If-None-Match
wymienionych w nagłówkach żądań.
Gdy poprawnie skonfigurowany serwer WWW wykryje nagłówki żądań przychodzących, może sprawdzić, czy wersja zasobu, którą przeglądarka już znajduje w pamięci podręcznej HTTP, jest zgodna z najnowszą wersją na serwerze WWW. Jeśli do siebie pasują, serwer może odpowiedzieć, wysyłając odpowiedź HTTP 304 Not Modified
, co jest odpowiednikiem polecenia „Hej, nadal korzystaj z tego, co już masz!”. Podczas wysyłania odpowiedzi tego typu można przesłać bardzo mało danych, więc zwykle jest to znacznie szybsze niż wysyłanie kopii rzeczywistego żądanego zasobu.
Podsumowanie
Pamięć podręczna HTTP to skuteczny sposób na przyspieszenie wczytywania, ponieważ ogranicza liczbę zbędnych żądań sieciowych. Jest obsługiwana we wszystkich przeglądarkach i nie wymaga dużo pracy.
Warto zacząć od tych konfiguracji Cache-Control
:
Cache-Control: no-cache
dla zasobów, które powinny zostać ponownie zweryfikowane na serwerze przed każdym użyciem.Cache-Control: no-store
– zasoby, które nie powinny być przechowywane w pamięci podręcznej.Cache-Control: max-age=31536000
dla zasobów z obsługą wersji.
Nagłówek ETag
lub Last-Modified
może pomóc w efektywniejszym potwierdzaniu wygasłych zasobów pamięci podręcznej.
Więcej informacji
Jeśli chcesz dowiedzieć się więcej niż tylko podstawowe informacje o korzystaniu z nagłówka Cache-Control
, przeczytaj przewodnik Jake Archibalda na temat sprawdzonych metod dotyczących buforowania i maksymalnych wymagań dotyczących wieku.
Wskazówki dotyczące optymalizacji wykorzystania pamięci podręcznej przez powracających użytkowników znajdziesz w artykule Uwielbiaj pamięć podręczną.
Załącznik: więcej wskazówek
Jeśli masz więcej czasu, poniżej znajdziesz dodatkowe sposoby optymalizacji wykorzystania pamięci podręcznej HTTP:
- Używaj spójnych adresów URL. Jeśli udostępniasz te same treści pod różnymi adresami URL, przeglądarka wielokrotnie je pobiera i przechowuje.
- Ogranicz liczbę rezygnacji. Jeśli część zasobu (np. plik CSS) jest często aktualizowana, a reszta pliku nie (tak jak w przypadku kodu biblioteki), rozważ podzielenie często aktualizowanego kodu na oddzielny plik i zastosowanie krótkotrwałej strategii buforowania w przypadku często aktualizowanego kodu oraz strategii o długim czasie przechowywania w przypadku kodu, który rzadko się zmienia.
- Jeśli zasada
Cache-Control
akceptuje pewien poziom nieaktualności, rozważ zastosowanie nowej dyrektywystale-while-revalidate
.
Dodatek: schemat blokowy typu Cache-Control
Dodatek: Cache-Control
przykładów
Wartość: Cache-Control |
Wyjaśnienie |
---|---|
max-age=86400 |
Odpowiedź może być przechowywana w pamięci podręcznej przeglądarek i pośrednich pamięci podręcznych przez maksymalnie 1 dzień (60 sekund x 60 minut x 24 godziny). |
private, max-age=600 |
Odpowiedź może być przechowywana w pamięci podręcznej przeglądarki, ale nie w pamięci podręcznej pośredniej, przez maksymalnie 10 minut (60 sekund x 10 minut). |
public, max-age=31536000 |
Odpowiedź można przechowywać w dowolnej pamięci podręcznej przez rok. |
no-store |
Odpowiedź nie może być przechowywana w pamięci podręcznej i musi być pobierana w całości przy każdym żądaniu. |