tl;dr
Od wersji Chrome 68 żądania HTTP, które sprawdzają dostępność aktualizacji skryptu service worker, nie będą
być wypełniane przez pamięć podręczną HTTP.
domyślnie. Problem dotyczy najczęstszego problemu programistów,
w którym ustawienie niezamierzonego nagłówka Cache-Control
w skrypcie service worker może prowadzić
do opóźnionych aktualizacji.
Jeśli skrypt /service-worker.js
ma już wyłączone buforowanie HTTP przez udostępnienie go
z Cache-Control: max-age=0
, nie powinny się pojawić żadne zmiany ze względu na nową domyślną wartość
zachowanie użytkownika.
Dodatkowo od wersji Chrome 78 funkcja porównywania bajtów
zastosowano do skryptów wczytywanych w mechanizmie Service Worker przez
importScripts()
Wszelkie zmiany wprowadzone w importowanym skrypcie spowodują uruchomienie polecenia
proces aktualizacji mechanizmów Service Worker,
tak samo jak zmiana
skryptu service worker.
Tło
Za każdym razem, gdy przechodzisz do nowej strony, która znajduje się w zakresie skryptu service worker, jawnie wywołaj registration.update()
JavaScript lub gdy skrypt service worker jest „wybudzony” za pomocą zdarzenia push
lub sync
, przeglądarka
równolegle wyśle żądanie zasobu JavaScript, który został pierwotnie przekazany do
navigator.serviceWorker.register()
w celu uzyskania aktualizacji skryptu service worker.
Na potrzeby tego artykułu załóżmy, że jego adres URL to /service-worker.js
i że
zawiera jedno wywołanie do importScripts()
,
który wczytuje dodatkowy kod uruchamiany w skrypcie service worker:
// Inside our /service-worker.js file:
importScripts('path/to/import.js');
// Other top-level code goes here.
Co się zmienia?
Przed wersją Chrome 68 żądanie aktualizacji przeglądarki /service-worker.js
było wysyłane z użyciem pamięci podręcznej HTTP
(tak jak w przypadku większości pobrań). Oznaczało to, że jeśli skrypt został pierwotnie wysłany za pomocą funkcji Cache-Control:
max-age=600
, aktualizacje w ciągu kolejnych 600 sekund (10 minut) nie trafiają do sieci, więc
użytkownik może nie otrzymać najnowszej wersji skryptu service worker. Jeśli jednak max-age
byłby
wartość większą niż 86 400 (24 godziny) jest traktowana tak, jakby była to 86 400, aby uniknąć zablokowania użytkownika.
z określoną wersją na zawsze.
Od wersji 68 pamięć podręczna HTTP będzie ignorowana przy żądaniach aktualizacji skryptu service worker
skryptu, tak więc istniejące aplikacje internetowe mogą odnotować wzrost częstotliwości wysyłania żądań
skrypt service worker. Żądania wysyłane do importScripts
będą nadal przesyłane przez pamięć podręczną HTTP. To jest
Jest dostępna nowa opcja rejestracji (updateViaCache
), która zapewnia kontrolę nad
tego działania.
updateViaCache
Deweloperzy mogą teraz przekazywać podczas wywoływania funkcji navigator.serviceWorker.register()
nową opcję: parametr updateViaCache
.
Przyjmuje jedną z trzech wartości: 'imports'
, 'all'
lub 'none'
.
Wartości określają, czy i w jaki sposób standardowa pamięć podręczna HTTP przeglądarki nie jest uwzględniana przy wysyłaniu żądania HTTP sprawdzającego dostępność zaktualizowanych zasobów skryptu service worker.
Gdy ustawisz wartość
'imports'
, pamięć podręczna HTTP nie będzie nigdy brana pod uwagę podczas sprawdzania dostępności aktualizacji/service-worker.js
, ale będzie używany przy pobieraniu wszelkich zaimportowanych skryptów (w tym przykładziepath/to/import.js
). Jest to ustawienie domyślne, które pasuje do w Chrome 68.Gdy zasada ma wartość
'all'
, pamięć podręczna HTTP jest brana pod uwagę przy wysyłaniu żądań skrypt/service-worker.js
najwyższego poziomu, a także wszystkie skrypty zaimportowane wewnątrz usługi instancji roboczej, np.path/to/import.js
. Ta opcja odpowiada poprzedniemu działaniu Chrome, przed wersją Chrome 68.Gdy ustawisz wartość
'none'
, pamięć podręczna HTTP nie będzie brana pod uwagę przy wysyłaniu żądań/service-worker.js
najwyższego poziomu lub dla dowolnych zaimportowanych skryptów, takich jak hipotetyczna wartośćpath/to/import.js
Na przykład poniższy kod zarejestruje skrypt service worker i zapewni, że pamięć podręczna HTTP jest
nigdy nie były konsultowane podczas sprawdzania aktualizacji skryptu /service-worker.js
ani żadnych
skrypty, do których odwołuje się importScripts()
w /service-worker.js
:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js', {
updateViaCache: 'none',
// Optionally, set 'scope' here, if needed.
});
}
Sprawdza, czy są dostępne aktualizacje zaimportowanych skryptów
Przed wersją Chrome 78 każdy skrypt skryptu service worker wczytywany przez
importScripts()
zostaną pobrane tylko raz (najpierw sprawdzając w pamięci podręcznej HTTP lub przez
w zależności od konfiguracji updateViaCache
). Po tej dacie
jest zapisywany wewnętrznie przez przeglądarkę i nigdy nie jest pobierany ponownie.
Jedyny sposób wymuszenia pobrania zmian przez już zainstalowany mechanizm Service Worker
zaimportowany skrypt miał na celu zmianę adresu URL skryptu, zazwyczaj przez dodanie parametru
wartość semver (np.
importScripts('https://example.com/v1.1.0/index.js')
) lub przez załączenie skrótu
treść (np. importScripts('https://example.com/index.abcd1234.js')
). O
efektem ubocznym zmiany zaimportowanego adresu URL jest to, że skrypt service worker najwyższego poziomu
zmiany treści skryptu, co z kolei powoduje uruchomienie
proces aktualizacji mechanizmu Service Worker.
Od Chrome 78 przy każdym sprawdzaniu dostępności aktualizacji
Skrypt service worker będzie przeprowadzany w tym samym czasie, co pozwoli określić, czy
lub nie zmieniono zawartości żadnego z zaimportowanych skryptów. W zależności od
Użyto Cache-Control
nagłówków; weryfikacja zaimportowanego skryptu może zostać wykonana przez
pamięci podręcznej HTTP, jeśli pole updateViaCache
ma wartość 'all'
lub 'imports'
(czyli
domyślnej wartości), lub wyniki mogą być kierowane bezpośrednio do sieci, jeśli
updateViaCache
ma wartość 'none'
.
Jeśli sprawdzenie aktualizacji zaimportowanego skryptu powoduje wystąpienie różnicy między bajtami w porównaniu z wcześniej zapisanym przez skrypt service worker, wyzwalać proces aktualizacji pełnego skryptu service worker, nawet jeśli usługa najwyższego poziomu pliku instancji roboczej pozostaje bez zmian.
Działanie Chrome 78 odpowiada temu, co implemented w przeglądarce Firefox. kilka lat temu, w Firefoksie w wersji 56. Safari implementuje już to działanie jako cóż.
Co muszą zrobić deweloperzy?
Jeśli dzięki udostępnieniu skryptu /service-worker.js
zrezygnowałeś(-aś) z buforowania protokołu HTTP
z Cache-Control: max-age=0
(lub podobną wartością), nie powinny się pojawić żadne zmiany ze względu na
na nowe domyślne zachowanie.
Jeśli udostępniasz skrypt /service-worker.js
z włączonym buforowaniem HTTP, albo celowo,
lub dlatego, że jest to domyślne dla Twojego środowiska hostingu,
możesz zauważyć wzrost liczby dodatkowych żądań HTTP dotyczących adresu /service-worker.js
wysyłanych do
Twojego serwera – są to żądania, które wcześniej były realizowane przez pamięć podręczną HTTP. Jeśli chcesz
Pozwól, aby wartość nagłówka Cache-Control
wpływała na aktualność
/service-worker.js
, musisz samodzielnie skonfigurować ustawienie updateViaCache: 'all'
, gdy:
podczas rejestrowania skryptu service worker.
Biorąc pod uwagę, że w przypadku starszych wersji przeglądarek może być spora grupa użytkowników, nadal dobrym pomysłem jest
kontynuuj konfigurowanie nagłówka HTTP Cache-Control: max-age=0
w skryptach skryptu service worker, nawet jeśli
nowsze przeglądarki mogą je ignorować.
Deweloperzy mogą wykorzystać tę możliwość, by zdecydować, czy chcą wyraźnie zdecydować, że dane zaimportowane zostaną zaimportowane.
skrypty z buforowania HTTP i dodanie updateViaCache: 'none'
do skryptu service worker
w stosownym przypadku.
Udostępnianie zaimportowanych skryptów
Począwszy od Chrome 78 deweloperzy mogą zauważyć więcej przychodzących żądań HTTP dla
zasoby wczytywane przez importScripts()
, ponieważ zostaną sprawdzone pod kątem
aktualizacje.
Jeśli chcesz uniknąć tego dodatkowego ruchu HTTP, ustaw
Cache-Control
w przypadku skryptów zawierających semver lub hasze w
ich adresy URL i korzystać z domyślnego zachowania updateViaCache
, czyli 'imports'
.
Jeśli chcesz, aby zaimportowane skrypty były często sprawdzane
, a następnie upewnij się, że obsługujesz je za pomocą funkcji Cache-Control: max-age=0
,
lub korzystasz z usługi updateViaCache: 'none'
.
Więcej informacji
„The Service Worker Lifecycle” oraz "Sprawdzone metody dotyczące buforowania max-age gotchas", przez Jake'a Archibalda, są polecane wszystkim programistom, którzy wdrażają coś w internecie.