Pekerja layanan yang lebih baru, secara default

tl;dr

Mulai Chrome 68, permintaan HTTP yang memeriksa update skrip pekerja layanan tidak akan lagi akan dipenuhi oleh cache HTTP secara {i>default<i}. Cara ini dapat mengatasi masalah umum yang dialami developer, yang menyebabkan header Cache-Control yang tidak disengaja pada skrip pekerja layanan dapat menyebabkan pembaruan yang tertunda.

Jika Anda telah memilih untuk tidak mengaktifkan penyimpanan cache HTTP untuk skrip /service-worker.js dengan menayangkannya dengan Cache-Control: max-age=0, Anda tidak akan melihat perubahan apa pun karena perilaku model.

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

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, browser akan, secara paralel, meminta resource JavaScript yang awalnya diteruskan ke navigator.serviceWorker.register(), untuk mencari pembaruan 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). Ini berarti jika skrip awalnya dikirim dengan Cache-Control: max-age=600, pembaruan dalam 600 detik berikutnya (10 menit) tidak akan sampai ke jaringan, sehingga pengguna mungkin tidak menerima versi pekerja layanan terbaru. Namun, jika max-age adalah lebih besar dari 86400 (24 jam), akan diperlakukan seolah-olah 86400, untuk menghindari pengguna terjebak dengan versi tertentu selamanya.

Mulai versi 68, cache HTTP akan diabaikan saat meminta update untuk pekerja layanan , jadi aplikasi web yang ada mungkin melihat peningkatan frekuensi permintaan untuk skrip pekerja layanan. Permintaan untuk importScripts akan tetap melalui cache HTTP. Tapi ini adalah hanya sebagai default—opsi pendaftaran baru, updateViaCache tersedia yang menawarkan kontrol 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 sumber daya pekerja layanan yang telah diperbarui.

  • Jika ditetapkan ke 'imports', cache HTTP tidak akan dimintai masukan saat memeriksa update pada /service-worker.js skrip, tetapi akan diminta bantuannya saat mengambil skrip yang diimpor (path/to/import.js, dalam contoh kita). Ini adalah defaultnya, dan sesuai dengan perilaku yang dimulai di Chrome 68.

  • Jika disetel ke 'all', cache HTTP akan diminta masukannya saat membuat permintaan untuk skrip /service-worker.js tingkat teratas, serta skrip apa pun yang diimpor di dalam layanan pekerja, seperti path/to/import.js. Opsi ini sesuai dengan perilaku sebelumnya di Chrome, sebelum Chrome 68.

  • Jika disetel ke 'none', cache HTTP tidak akan diperiksa saat membuat permintaan untuk /service-worker.js tingkat teratas atau untuk skrip yang diimpor, seperti contoh path/to/import.js.

Misalnya, kode berikut akan mendaftarkan pekerja layanan, dan memastikan bahwa cache HTTP tidak pernah berkonsultasi saat memeriksa pembaruan pada skrip /service-worker.js, atau untuk skrip 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, skrip pekerja layanan apa pun yang dimuat melalui importScripts() akan diambil sekali saja (memeriksa cache HTTP terlebih dahulu, atau melalui jaringan, bergantung pada konfigurasi updateViaCache). Setelah nilai awal tersebut , data akan disimpan secara internal oleh browser dan tidak pernah diambil kembali.

Satu-satunya cara untuk memaksa pekerja layanan yang sudah terinstal untuk mengambil perubahan pada skrip yang diimpor adalah mengubah URL skrip, biasanya dengan menambahkan nilai seemver (mis. importScripts('https://example.com/v1.1.0/index.js')) atau dengan menyertakan hash dari kontennya (misalnya, importScripts('https://example.com/index.abcd1234.js')). J efek samping perubahan URL yang diimpor adalah pekerja layanan tingkat teratas konten skrip berubah, yang pada gilirannya akan memicu alur update pekerja layanan.

Mulai Chrome 78, setiap kali pemeriksaan update dilakukan untuk file pekerja layanan, pemeriksaan akan dilakukan pada saat yang sama untuk menentukan apakah atau tidak ada perubahan apa pun pada konten skrip yang diimpor. Bergantung pada Cache-Control header digunakan, pemeriksaan skrip yang diimpor ini mungkin dipenuhi oleh cache HTTP jika updateViaCache disetel ke 'all' atau 'imports' (yang nilai {i>default<i}), atau pemeriksaan mungkin langsung melawan jaringan jika updateViaCache disetel ke 'none'.

Jika pemeriksaan update untuk skrip yang diimpor menghasilkan perbedaan byte-untuk-byte dibandingkan dengan apa yang sebelumnya disimpan oleh pekerja layanan, yang pada gilirannya memicu alur update pekerja layanan penuh, meskipun layanan level teratas dan file worker akan tetap sama.

Perilaku Chrome 78 cocok dengan yang implemented Firefox beberapa tahun yang lalu, di Firefox 56. Safari sudah menerapkan perilaku ini sebagai ya.

Apa yang harus dilakukan developer?

Jika Anda secara efektif menonaktifkan penyimpanan cache HTTP untuk skrip /service-worker.js 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 cache HTTP diaktifkan, baik secara sengaja atau karena merupakan default untuk lingkungan hosting Anda, Anda mungkin mulai melihat peningkatan permintaan HTTP tambahan untuk /service-worker.js yang dilakukan terhadap server Anda—ini adalah permintaan yang biasanya dipenuhi oleh cache HTTP. Jika Anda ingin terus mengizinkan nilai header Cache-Control memengaruhi keaktualan file /service-worker.js, Anda harus mulai menyetel updateViaCache: 'all' secara eksplisit saat mendaftarkan pekerja layanan Anda.

Mengingat mungkin ada banyak pengguna di versi browser lama, tidak ada salahnya untuk lanjutkan menyetel header HTTP Cache-Control: max-age=0 pada skrip pekerja layanan, meskipun {i>browser<i} yang lebih baru mungkin mengabaikannya.

Developer dapat menggunakan peluang ini untuk memutuskan apakah mereka ingin secara eksplisit memilih opsi impor skrip dari cache HTTP sekarang, dan menambahkan updateViaCache: 'none' ke pekerja layanannya jika diperlukan.

Menyajikan skrip yang diimpor

Mulai Chrome 78, developer mungkin melihat lebih banyak permintaan HTTP masuk untuk resource dimuat melalui importScripts(), karena kini akan diperiksa pembaruan.

Jika Anda ingin menghindari traffic HTTP tambahan ini, Cache-Control header 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 sering diperiksa update, lalu pastikan Anda menayangkan Cache-Control: max-age=0, atau Anda menggunakan updateViaCache: 'none'.

Bacaan lebih lanjut

"Siklus Proses Service Worker" dan "Praktik terbaik penyimpanan dalam cache & mendapat getcha usia maksimum", keduanya oleh Jake Archibald, direkomendasikan untuk dibaca bagi semua developer yang men-deploy apa pun ke web.