tl;dr
Mulai Chrome 68, permintaan HTTP yang memeriksa update pada skrip pekerja layanan tidak akan
lagi dipenuhi oleh cache HTTP
secara default. Hal ini mengatasi titik masalah umum developer,
yang menetapkan header Cache-Control
yang tidak disengaja pada skrip pekerja layanan dapat menyebabkan
update tertunda.
Jika Anda telah memilih untuk tidak menggunakan cache HTTP untuk skrip /service-worker.js
dengan menayangkannya
dengan Cache-Control: max-age=0
, Anda tidak akan melihat perubahan apa pun karena perilaku default
baru.
Selain itu, mulai Chrome 78, perbandingan byte demi byte akan
diterapkan ke skrip yang dimuat di pekerja layanan melalui
importScripts()
.
Setiap perubahan yang dilakukan pada skrip yang diimpor akan memicu
alur update pekerja layanan,
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 "diaktifkan" melalui peristiwa push
atau sync
, browser akan secara paralel meminta resource JavaScript yang awalnya diteruskan ke panggilan navigator.serviceWorker.register()
, untuk mencari update pada skrip pekerja layanan.
Untuk tujuan artikel ini, asumsikan 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 dilakukan melalui cache HTTP
(seperti sebagian besar pengambilan). Artinya, jika skrip awalnya dikirim dengan Cache-Control:
max-age=600
, update dalam 600 detik (10 menit) berikutnya tidak akan dikirim ke jaringan, sehingga pengguna mungkin tidak menerima versi terbaru pekerja layanan. Namun, jika max-age
lebih besar dari 86400 (24 jam), max-age
akan diperlakukan seolah-olah 86400, agar pengguna tidak terjebak
dengan versi tertentu selamanya.
Mulai versi 68, cache HTTP akan diabaikan saat meminta update ke skrip pekerja layanan, sehingga aplikasi web yang ada mungkin akan mengalami peningkatan frekuensi permintaan untuk skrip pekerja layanannya. Permintaan untuk importScripts
akan tetap melalui cache HTTP. Namun, ini
hanya default—opsi pendaftaran baru, updateViaCache
tersedia yang menawarkan kontrol atas
perilaku ini.
updateViaCache
Developer kini dapat meneruskan opsi baru saat memanggil navigator.serviceWorker.register()
: parameter updateViaCache
.
Metode ini memerlukan salah satu dari tiga nilai: 'imports'
, 'all'
, atau 'none'
.
Nilai ini menentukan apakah dan bagaimana cache HTTP standar browser digunakan saat membuat permintaan HTTP untuk memeriksa resource pekerja layanan yang diperbarui.
Jika ditetapkan ke
'imports'
, cache HTTP tidak akan pernah dikonsultasikan saat memeriksa update pada skrip/service-worker.js
, tetapi akan dikonsultasikan saat mengambil skrip yang diimpor (path/to/import.js
, dalam contoh kami). Ini adalah setelan default, dan cocok dengan perilaku yang dimulai di Chrome 68.Jika ditetapkan ke
'all'
, cache HTTP akan dikonsultasikan saat membuat permintaan untuk skrip/service-worker.js
level 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 dikonsultasikan saat membuat permintaan untuk/service-worker.js
tingkat atas atau untuk skrip yang diimpor, sepertipath/to/import.js
hipotetik.
Misalnya, kode berikut akan mendaftarkan pekerja layanan, dan memastikan bahwa cache HTTP
tidak pernah dikonsultasikan 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.
});
}
Memeriksa update pada skrip yang diimpor
Sebelum Chrome 78, skrip pekerja layanan apa pun yang dimuat melalui
importScripts()
hanya akan diambil satu kali (pertama-tama memeriksa cache HTTP, atau melalui
jaringan, bergantung pada konfigurasi updateViaCache
). Setelah pengambilan awal, data tersebut akan disimpan secara internal oleh browser, dan tidak akan diambil lagi.
Satu-satunya cara untuk memaksa pekerja layanan yang telah diinstal untuk 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 konten skrip pekerja layanan
tingkat teratas berubah, yang pada akhirnya memicu
alur update pekerja layanan.
Mulai Chrome 78, setiap kali pemeriksaan update dilakukan untuk file pekerja layanan
level 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 dapat dipenuhi oleh
cache HTTP jika updateViaCache
ditetapkan ke 'all'
atau 'imports'
(yang merupakan
nilai default), atau pemeriksaan dapat langsung dilakukan terhadap jaringan jika
updateViaCache
ditetapkan ke 'none'
.
Jika pemeriksaan update untuk skrip yang diimpor menghasilkan perbedaan byte-per-byte dibandingkan dengan yang sebelumnya disimpan oleh pekerja layanan, hal ini pada gilirannya akan memicu alur update pekerja layanan lengkap, meskipun file pekerja layanan tingkat atas tetap sama.
Perilaku Chrome 78 cocok dengan yang diterapkan Firefox beberapa tahun yang lalu, di Firefox 56. Safari juga sudah menerapkan perilaku ini.
Apa yang harus dilakukan developer?
Jika Anda telah memilih untuk tidak menggunakan cache HTTP untuk skrip /service-worker.js
secara efektif dengan menayangkannya
dengan 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 mengaktifkan cache HTTP, baik secara sengaja
maupun karena itu adalah default untuk lingkungan hosting Anda,
Anda mungkin mulai melihat peningkatan permintaan HTTP tambahan untuk /service-worker.js
yang dibuat terhadap
server Anda—ini adalah permintaan yang sebelumnya dipenuhi oleh cache HTTP. Jika ingin
terus mengizinkan nilai header Cache-Control
memengaruhi keaktualan
/service-worker.js
, Anda harus mulai menetapkan updateViaCache: 'all'
secara eksplisit saat
mendaftarkan pekerja layanan.
Mengingat mungkin ada pengguna longtail di versi browser lama, sebaiknya terus tetapkan header HTTP Cache-Control: max-age=0
pada skrip pekerja layanan, meskipun browser yang lebih baru mungkin mengabaikannya.
Developer dapat menggunakan peluang ini untuk memutuskan apakah mereka ingin secara eksplisit memilih skrip
yang diimpor dari penyimpanan dalam cache HTTP sekarang, dan menambahkan updateViaCache: 'none'
ke pendaftaran pekerja layanan
jika sesuai.
Menayangkan skrip yang diimpor
Mulai Chrome 78, developer mungkin melihat lebih banyak permintaan HTTP masuk untuk
resource yang dimuat melalui importScripts()
, karena resource tersebut 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 mengandalkan perilaku updateViaCache
default dari 'imports'
.
Atau, jika Anda ingin skrip yang diimpor diperiksa untuk update
yang sering, pastikan Anda menayangkannya dengan Cache-Control: max-age=0
,
atau menggunakan updateViaCache: 'none'
.
Bacaan lebih lanjut
"Siklus Proses Pekerja Layanan" dan "Praktik terbaik penyimpanan dalam cache & masalah max-age", keduanya oleh Jake Archibald, adalah bacaan yang direkomendasikan untuk semua developer yang men-deploy apa pun ke web.