Pekerja layanan yang lebih baru, secara default

tl;dr

Mulai Chrome 68, permintaan HTTP yang memeriksa update pada skrip pekerja layanan tidak akan lagi dipenuhi oleh cache HTTP secara default. Langkah ini mengatasi masalah umum developer, saat menyetel header Cache-Control yang tidak disengaja pada skrip pekerja layanan dapat menyebabkan update yang tertunda.

Jika sudah memilih untuk tidak menggunakan penyimpanan HTTP dalam cache untuk skrip /service-worker.js dengan menayangkannya menggunakan Cache-Control: max-age=0, Anda tidak akan melihat perubahan apa pun karena perilaku default yang baru.

Selain itu, mulai Chrome 78, perbandingan byte per byte akan diterapkan pada skrip yang dimuat dalam 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() dari JavaScript secara eksplisit, atau saat pekerja layanan "diaktifkan" melalui peristiwa push atau sync, browser secara paralel akan meminta resource JavaScript yang awalnya diteruskan ke panggilan navigator.serviceWorker.register() untuk mencari update pada skrip pekerja layanan.

Untuk tujuan artikel ini, anggap 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 (sebagaimana sebagian besar pengambilan). Artinya, jika skrip awalnya dikirim dengan Cache-Control: max-age=600, update dalam 600 detik berikutnya (10 menit) tidak akan masuk ke jaringan, sehingga pengguna mungkin tidak akan menerima versi pekerja layanan terbaru. Namun, jika max-age lebih besar dari 86400 (24 jam), nilainya akan diperlakukan seolah-olah 86400, agar pengguna tidak terjebak dengan versi tertentu selamanya.

Mulai 68, cache HTTP akan diabaikan ketika meminta update ke 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 setelan 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. Kode ini menggunakan salah satu dari tiga nilai: 'imports', 'all', atau 'none'.

Nilai ini akan menentukan apakah dan bagaimana cache HTTP standar browser berfungsi saat membuat permintaan HTTP untuk memeriksa resource pekerja layanan yang diperbarui.

  • Jika ditetapkan ke 'imports', cache HTTP tidak akan diperhitungkan saat memeriksa update pada skrip /service-worker.js, tetapi akan dimintai pendapatnya saat mengambil setiap skrip yang diimpor (path/to/import.js, dalam contoh kami). Ini adalah setelan default, dan cocok dengan perilaku yang mulai di Chrome 68.

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

  • Jika ditetapkan ke 'none', cache HTTP tidak akan digunakan saat membuat permintaan untuk /service-worker.js level teratas atau skrip yang diimpor, seperti path/to/import.js fiktif.

Misalnya, kode berikut akan mendaftarkan pekerja layanan, dan memastikan bahwa cache HTTP tidak pernah diminta saat memeriksa update 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 terlebih dahulu dengan cache HTTP, atau melalui jaringan, bergantung pada konfigurasi updateViaCache). Setelah pengambilan awal tersebut, data akan disimpan secara internal oleh browser dan tidak akan diambil ulang.

Satu-satunya cara untuk memaksa pekerja layanan yang sudah diinstal 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 (mis. importScripts('https://example.com/index.abcd1234.js')). Efek samping dari mengubah URL yang diimpor adalah konten skrip pekerja layanan tingkat atas berubah, yang kemudian akan memicu alur update.

Mulai Chrome 78, setiap kali pemeriksaan update dilakukan untuk file pekerja layanan level atas, 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 disetel ke 'all' atau 'imports' (yang merupakan nilai default), atau pemeriksaan mungkin langsung menuju jaringan jika updateViaCache disetel ke 'none'.

Jika pemeriksaan update pada skrip yang diimpor menghasilkan perbedaan byte demi byte dibandingkan dengan yang sebelumnya disimpan oleh pekerja layanan, hal tersebut akan memicu alur update pekerja layanan penuh, meskipun jika file pekerja layanan tingkat atas 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 memilih tidak menggunakan cache HTTP untuk skrip /service-worker.js dengan menayangkannya bersama Cache-Control: max-age=0 (atau nilai yang serupa), Anda tidak akan melihat perubahan apa pun karena perilaku default baru.

Jika Anda menayangkan skrip /service-worker.js dengan cache HTTP yang diaktifkan, baik secara sengaja atau karena hanya merupakan default untuk lingkungan hosting, Anda mungkin mulai melihat peningkatan permintaan HTTP tambahan untuk /service-worker.js yang dibuat terhadap server—permintaan ini 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 banyak 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 akan mengabaikannya.

Developer dapat menggunakan peluang ini untuk memutuskan apakah mereka ingin secara eksplisit mengecualikan skrip yang diimpor dari cache HTTP sekarang, dan menambahkan updateViaCache: 'none' ke pendaftaran pekerja layanan mereka jika sesuai.

Menyajikan skrip yang diimpor

Mulai Chrome 78, developer mungkin melihat lebih banyak permintaan HTTP masuk untuk resource yang dimuat melalui importScripts(), karena sekarang mereka 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 dari 'imports'.

Atau, jika Anda ingin skrip yang diimpor diperiksa untuk mengetahui pembaruan yang sering, pastikan untuk menayangkannya dengan Cache-Control: max-age=0, atau bahwa Anda menggunakan updateViaCache: 'none'.

Bacaan lebih lanjut

"Siklus Proses Pekerja Layanan" dan "Praktik terbaik caching & getcha usia maksimal", keduanya oleh Jake Archibald, merupakan bacaan yang direkomendasikan untuk semua developer yang men-deploy apa pun ke web.