tl;dr
Mulai Chrome 68, permintaan HTTP yang memeriksa update pada skrip pekerja layanan tidak akan lagi dipenuhi oleh cache HTTP secara default. Tindakan ini mengatasi titik masalah developer yang umum,
saat menetapkan header Cache-Control
yang tidak disengaja pada skrip pekerja layanan dapat menyebabkan
update tertunda.
Jika sudah menonaktifkan penyimpanan cache HTTP untuk skrip /service-worker.js
dengan menayangkannya
bersama Cache-Control: max-age=0
, Anda tidak akan melihat perubahan apa pun karena perilaku default
baru.
Selain itu, mulai Chrome 78, perbandingan byte-untuk-byte akan
diterapkan ke skrip yang dimuat di pekerja layanan melalui
importScripts()
.
Setiap perubahan yang dibuat pada skrip yang diimpor akan memicu alur update pekerja layanan, sama seperti perubahan pada pekerja layanan tingkat teratas.
Latar belakang
Setiap kali Anda membuka halaman baru yang berada dalam cakupan pekerja layanan, panggil registration.update()
secara eksplisit dari JavaScript, atau saat pekerja layanan "dibangunkan" melalui peristiwa push
atau sync
, secara paralel browser akan meminta resource JavaScript yang awalnya diteruskan ke panggilan navigator.serviceWorker.register()
, untuk mencari pembaruan pada skrip pekerja layanan.
Untuk tujuan artikel ini, anggap saja URL-nya adalah /service-worker.js
dan
berisi satu panggilan ke importScripts()
,
yang memuat kode tambahan yang dijalankan di dalam pekerja layanan:
// Inside our /service-worker.js file:
importScripts('path/to/import.js');
// Other top-level code goes here.
Apa yang berubah?
Sebelum Chrome 68, permintaan update untuk /service-worker.js
akan dibuat melalui cache HTTP
(seperti kebanyakan pengambilan). Artinya, jika skrip awalnya dikirim dengan Cache-Control:
max-age=600
, update dalam 600 detik berikutnya (10 menit) tidak akan sampai ke jaringan, sehingga pengguna mungkin tidak menerima versi terbaru pekerja layanan. Namun, jika max-age
lebih besar dari 86400 (24 jam), nilainya akan diperlakukan seolah-olah adalah 86400, untuk mencegah pengguna terjebak dengan versi tertentu selamanya.
Mulai versi 68, cache HTTP akan diabaikan saat meminta update untuk skrip pekerja layanan, sehingga aplikasi web yang ada mungkin mengalami peningkatan frekuensi permintaan untuk skrip pekerja layanannya. Permintaan untuk importScripts
akan tetap melalui cache HTTP. Namun, ini
hanyalah opsi default—tersedia opsi pendaftaran baru updateViaCache
yang menawarkan kontrol atas
perilaku ini.
updateViaCache
Developer kini dapat meneruskan opsi baru saat memanggil navigator.serviceWorker.register()
: parameter updateViaCache
.
Fungsi ini menggunakan salah satu dari tiga nilai: 'imports'
, 'all'
, atau 'none'
.
Nilai ini menentukan apakah dan bagaimana cache HTTP standar browser berperan saat membuat permintaan HTTP untuk memeriksa resource pekerja layanan terbaru.
Jika ditetapkan ke
'imports'
, cache HTTP tidak akan dimintai masukannya saat memeriksa update pada skrip/service-worker.js
, tetapi akan diminta bantuan saat mengambil skrip yang diimpor (dalam contoh kita adalahpath/to/import.js
). Ini adalah setelan default, dan cocok dengan perilaku yang dimulai di Chrome 68.Jika ditetapkan ke
'all'
, cache HTTP akan diperiksa saat membuat permintaan untuk skrip/service-worker.js
tingkat teratas, serta skrip apa pun yang diimpor di dalam pekerja layanan, sepertipath/to/import.js
. Opsi ini sesuai dengan perilaku sebelumnya di Chrome, sebelum Chrome 68.Jika ditetapkan ke
'none'
, cache HTTP tidak akan diperhatikan saat membuat permintaan untuk/service-worker.js
tingkat teratas atau untuk skrip yang diimpor, seperti hipotesispath/to/import.js
.
Misalnya, kode berikut akan mendaftarkan pekerja layanan, dan memastikan bahwa cache HTTP tidak pernah diperiksa saat memeriksa update pada skrip /service-worker.js
, atau untuk skrip apa pun yang direferensikan melalui importScripts()
di dalam /service-worker.js
:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js', {
updateViaCache: 'none',
// Optionally, set 'scope' here, if needed.
});
}
Pemeriksaan update pada skrip yang diimpor
Sebelum Chrome 78, semua skrip pekerja layanan yang dimuat melalui
importScripts()
hanya akan diambil satu kali (memeriksa cache HTTP terlebih dahulu, atau melalui
jaringan, bergantung pada konfigurasi updateViaCache
). Setelah diambil
awal tersebut, data akan disimpan secara internal oleh browser, dan tidak pernah diambil kembali.
Satu-satunya cara untuk memaksa pekerja layanan yang sudah diinstal agar mengambil perubahan pada skrip yang diimpor adalah dengan mengubah URL skrip, biasanya dengan menambahkan nilai semver (misalnya importScripts('https://example.com/v1.1.0/index.js')
) atau dengan menyertakan hash konten (misalnya, importScripts('https://example.com/index.abcd1234.js')
). Efek samping dari mengubah URL yang diimpor adalah perubahan konten skrip pekerja layanan tingkat atas.
Mulai Chrome 78, setiap kali pemeriksaan update dilakukan untuk file
pekerja layanan tingkat teratas, pemeriksaan akan dilakukan secara bersamaan untuk menentukan apakah
konten skrip yang diimpor telah berubah atau tidak. Bergantung pada
header Cache-Control
yang digunakan, pemeriksaan skrip yang diimpor ini mungkin dipenuhi oleh
cache HTTP jika updateViaCache
ditetapkan ke 'all'
atau 'imports'
(yang merupakan
nilai default), atau pemeriksaan mungkin langsung ke jaringan jika
updateViaCache
ditetapkan ke 'none'
.
Jika pemeriksaan update untuk skrip yang diimpor menghasilkan perbedaan byte-untuk-byte dibandingkan dengan apa yang sebelumnya disimpan oleh pekerja layanan, hal tersebut pada gilirannya akan memicu alur update pekerja layanan penuh, meskipun jika file pekerja layanan tingkat teratas tetap sama.
Perilaku Chrome 78 sesuai dengan yang diterapkan Firefox beberapa tahun lalu, di Firefox 56. Safari juga sudah menerapkan perilaku ini.
Apa yang harus dilakukan developer?
Jika Anda secara efektif menonaktifkan penyimpanan cache HTTP untuk skrip /service-worker.js
dengan menayangkannya menggunakan Cache-Control: max-age=0
(atau nilai serupa), Anda tidak akan melihat perubahan apa pun karena perilaku default baru.
Jika Anda menayangkan skrip /service-worker.js
dengan cache HTTP diaktifkan, baik secara sengaja maupun karena itu hanya setelan default untuk lingkungan hosting Anda, Anda mungkin akan mulai melihat peningkatan permintaan HTTP tambahan untuk /service-worker.js
yang dibuat terhadap server Anda. Permintaan ini adalah permintaan yang biasanya dipenuhi oleh cache HTTP. Jika ingin terus mengizinkan nilai header Cache-Control
memengaruhi keaktualan /service-worker.js
, Anda harus mulai menyetel updateViaCache: 'all'
secara eksplisit saat mendaftarkan pekerja layanan.
Mengingat mungkin ada longtail pengguna di versi browser lama, sebaiknya
terus setel header HTTP Cache-Control: max-age=0
pada skrip pekerja layanan, meskipun
browser yang lebih baru mungkin mengabaikannya.
Developer dapat menggunakan kesempatan ini untuk memutuskan apakah mereka ingin secara eksplisit mengecualikan skrip yang diimpor
dari cache HTTP sekarang, dan menambahkan updateViaCache: 'none'
ke pendaftaran pekerja
layanan jika sesuai.
Menyajikan skrip yang diimpor
Mulai Chrome 78, developer mungkin melihat lebih banyak permintaan HTTP yang masuk untuk
resource yang dimuat melalui importScripts()
, karena developer kini akan diperiksa untuk
update.
Jika Anda ingin menghindari traffic HTTP tambahan ini, tetapkan header
Cache-Control
yang berumur panjang saat menayangkan skrip yang menyertakan semver atau hash di
URL-nya, dan andalkan perilaku updateViaCache
default 'imports'
.
Atau, jika Anda ingin skrip yang diimpor diperiksa untuk sering update, pastikan Anda menayangkannya dengan Cache-Control: max-age=0
, atau menggunakan updateViaCache: 'none'
.
Bacaan lebih lanjut
"The Service Worker Lifecycle" dan "Caching best practice & max-age gotchas", keduanya oleh Jake Archibald, direkomendasikan sebagai bacaan bagi semua developer yang men-deploy apa pun ke web.