Codelab ini merupakan bagian dari kursus pelatihan Mengembangkan Progressive Web App yang dikembangkan oleh tim Pelatihan Google Developers. Anda akan mendapatkan manfaat maksimal dari kursus ini jika Anda mengerjakan codelab secara berurutan.
Untuk detail selengkapnya tentang kursus ini, lihat Ringkasan Progressive Web Apps Progressive.
Pengantar
Lab ini memandu Anda dalam membuat pekerja layanan sederhana dan menjelaskan siklus proses pekerja layanan.
Yang akan Anda pelajari
- Membuat skrip pekerja layanan dasar, menginstalnya, dan melakukan proses debug sederhana
Yang perlu Anda ketahui
- JavaScript dan HTML Dasar
- Konsep dan sintaksis dasar ES2015 Promises
- Cara mengaktifkan konsol developer
Yang Anda perlukan sebelum memulai
- Komputer dengan akses terminal/shell
- Koneksi ke internet
- Browser yang mendukung pekerja layanan
- Editor teks
Download atau clone repositori pwa-training-labs dari github dan instal versi LTS Node.js, jika diperlukan.
Buka direktori service-worker-lab/app/
dan mulai server pengembangan lokal:
cd service-worker-lab/app npm install node server.js
Anda dapat menghentikan server kapan saja dengan Ctrl-c
.
Buka browser, lalu buka localhost:8081/
.
Catatan: Batalkan pendaftaran pekerja layanan dan hapus semua cache pekerja layanan untuk localhost sehingga tidak mengganggu lab. Di Chrome DevTools, Anda dapat melakukannya dengan mengklik Hapus data situs dari bagian Hapus penyimpanan di tab Aplikasi.
Buka folder service-worker-lab/app/
di editor teks pilihan Anda. Folder app/
adalah tempat Anda akan membuat lab.
Folder ini berisi:
below/another.html
,js/another.js
,js/other.js
, danother.html
adalah resource contoh yang kami gunakan untuk bereksperimen dengan cakupan pekerja layanan- Folder
styles/
berisi stylesheet bertingkat untuk lab ini test/
folder berisi file untuk menguji progres Andaindex.html
adalah halaman HTML utama untuk situs/aplikasi contoh kamiservice-worker.js
adalah file JavaScript yang digunakan untuk membuat pekerja layananpackage.json
danpackage-lock.json
melacak paket node yang digunakan dalam project iniserver.js
adalah server ekspres sederhana yang digunakan untuk menghosting aplikasi
Buka service-worker.js
di editor teks Anda. Perhatikan bahwa file tersebut kosong. Kita belum menambahkan kode apa pun untuk dijalankan dalam pekerja layanan.
Buka index.html
di editor teks Anda.
Di dalam tag <script>
, tambahkan kode berikut untuk mendaftarkan pekerja layanan:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('service-worker.js')
.then(registration => {
console.log('Service Worker is registered', registration);
})
.catch(err => {
console.error('Registration failed:', err);
});
});
}
Simpan skrip dan muat ulang halaman. Konsol akan menampilkan pesan yang menunjukkan bahwa pekerja layanan telah terdaftar. Di Chrome, Anda dapat memeriksa apakah pekerja layanan terdaftar dengan membuka DevTools (Control + Shift + I di Windows dan Linux, atau ⌘ + alt + I di Mac), mengklik tab Application, dan mengklik opsi Service Workers. Anda akan melihat sesuatu yang mirip dengan hal berikut:
Opsional: Buka situs di browser yang tidak didukung dan pastikan bahwa pemeriksaan dukungan berfungsi dengan baik.
Penjelasan
Kode di atas mendaftarkan file service-worker.js
sebagai pekerja layanan. Pengujian ini pertama-tama memeriksa apakah browser mendukung pekerja layanan. Hal ini harus dilakukan setiap kali Anda mendaftarkan pekerja layanan karena beberapa browser mungkin tidak mendukung pekerja layanan. Kode kemudian mendaftarkan pekerja layanan menggunakan metode register
dari ServiceWorkerContainer
API, yang terdapat dalam antarmuka Navigator
jendela.
navigator.serviceWorker.register(...)
menampilkan promise yang di-resolve dengan objek registration
setelah pekerja layanan berhasil didaftarkan. Jika pendaftaran gagal, promise akan menolak.
Perubahan status pekerja layanan memicu peristiwa di pekerja layanan.
Menambahkan pemroses peristiwa
Buka service-worker.js
di editor teks Anda.
Tambahkan pemroses peristiwa berikut ke pekerja layanan:
self.addEventListener('install', event => {
console.log('Service worker installing...');
// Add a call to skipWaiting here
});
self.addEventListener('activate', event => {
console.log('Service worker activating...');
});
Simpan file tersebut.
Batalkan pendaftaran pekerja layanan secara manual dan muat ulang halaman untuk menginstal dan mengaktifkan pekerja layanan yang diperbarui. Log konsol harus menunjukkan bahwa pekerja layanan baru telah terdaftar, diinstal, dan diaktifkan.
Catatan: Log pendaftaran mungkin tidak berurutan dengan log lainnya (penginstalan dan aktivasi). Pekerja layanan berjalan bersamaan dengan halaman, sehingga kami tidak dapat menjamin urutan log (log pendaftaran berasal dari halaman, sementara log penginstalan dan aktivasi berasal dari pekerja layanan). Namun, peristiwa penginstalan, aktivasi, dan pekerja layanan lainnya terjadi dalam urutan yang ditentukan di dalam pekerja layanan, dan harus selalu muncul dalam urutan yang diharapkan.
Penjelasan
Pekerja layanan memunculkan peristiwa install
di akhir pendaftaran. Pada kode di atas, pesan dicatat di dalam pemroses peristiwa install
, tetapi dalam aplikasi sebenarnya, ini adalah tempat yang baik untuk menyimpan aset statis ke dalam cache.
Ketika pekerja layanan didaftarkan, browser mendeteksi apakah pekerja layanan tersebut baru (baik karena pekerja layanan berbeda dari pekerja layanan yang diinstal sebelumnya atau karena tidak ada pekerja layanan terdaftar untuk situs ini). Jika pekerja layanan masih baru (seperti dalam kasus ini), browser akan menginstalnya.
Pekerja layanan memunculkan peristiwa activate
saat mengambil alih halaman. Kode di atas mencatat pesan di sini, tetapi peristiwa ini sering digunakan untuk memperbarui cache.
Hanya satu pekerja layanan yang dapat aktif dalam satu waktu untuk cakupan tertentu (lihat Menjelajahi cakupan pekerja layanan), sehingga pekerja layanan yang baru diinstal tidak diaktifkan hingga pekerja layanan yang ada tidak lagi digunakan. Oleh karena itu, semua halaman yang dikontrol oleh pekerja layanan harus ditutup sebelum pekerja layanan baru dapat mengambil alih. Karena kita membatalkan pendaftaran pekerja layanan yang ada, pekerja layanan baru akan segera diaktifkan.
Catatan: Hanya memuat ulang halaman tidak cukup untuk mentransfer kontrol ke pekerja layanan baru, karena halaman baru akan diminta sebelum halaman saat ini dihapus muatannya, dan tidak akan ada waktu saat pekerja layanan lama tidak digunakan.
Catatan: Anda juga dapat mengaktifkan pekerja layanan baru secara manual menggunakan beberapa browser&alat developer dan secara terprogram dengan skipWaiting()
, yang dibahas pada bagian 3.4.
Mengupdate pekerja layanan
Tambahkan komentar berikut di mana saja di service-worker.js
:
// I'm a new service worker
Simpan file, lalu muat ulang halaman. Lihat log di konsol; perhatikan bahwa pekerja layanan baru menginstal tetapi tidak aktif. Di Chrome, Anda dapat melihat pekerja layanan yang menunggu di tab Aplikasi pada DevTools.
Tutup semua halaman yang terkait dengan pekerja layanan. Lalu, buka kembali localhost:8081/
. Log konsol harus menunjukkan bahwa pekerja layanan baru kini telah diaktifkan.
Catatan: Jika Anda mendapatkan hasil yang tidak diharapkan, pastikan cache HTTP dinonaktifkan di alat developer.
Penjelasan
Browser mendeteksi perbedaan byte antara file pekerja layanan baru dan yang sudah ada (karena komentar yang ditambahkan), sehingga pekerja layanan baru akan diinstal. Karena hanya satu pekerja layanan yang dapat aktif pada satu waktu (untuk cakupan tertentu), meskipun pekerja layanan baru diinstal, pekerja layanan tersebut tidak akan diaktifkan hingga pekerja layanan yang ada tidak lagi digunakan. Dengan menutup semua halaman di bawah kontrol pekerja layanan lama, kita dapat mengaktifkan pekerja layanan baru.
Melewati tahap menunggu
Pekerja layanan baru dapat segera diaktifkan, meskipun ada pekerja layanan yang ada, dengan melewati fase menunggu.
Di service-worker.js
, tambahkan panggilan ke skipWaiting
di pemroses peristiwa install
:
self.skipWaiting();
Simpan file, lalu muat ulang halaman. Perhatikan bahwa pekerja layanan baru akan menginstal dan mengaktifkan segera, meskipun pekerja layanan sebelumnya memegang kendali.
Penjelasan
Metode skipWaiting()
memungkinkan pekerja layanan diaktifkan segera setelah selesai diinstal. Pemroses peristiwa penginstalan adalah tempat yang umum untuk melakukan panggilan skipWaiting()
, tetapi dapat dipanggil di mana saja selama atau sebelum fase menunggu. Lihat dokumentasi ini untuk informasi selengkapnya tentang waktu dan cara menggunakan skipWaiting()
. Untuk bagian selanjutnya di lab, sekarang kita dapat menguji kode pekerja layanan baru tanpa membatalkan pendaftaran pekerja layanan secara manual.
Untuk informasi selengkapnya
Pekerja layanan dapat bertindak sebagai proxy di antara aplikasi web Anda dan jaringan.
Mari tambahkan pemroses pengambilan untuk menangkap permintaan dari domain kita.
Tambahkan kode berikut ke service-worker.js
:
self.addEventListener('fetch', event => {
console.log('Fetching:', event.request.url);
});
Simpan skrip dan muat ulang halaman untuk menginstal dan mengaktifkan pekerja layanan yang telah diperbarui.
Periksa konsol dan amati bahwa tidak ada peristiwa pengambilan yang dicatat. Muat ulang halaman dan periksa konsol lagi. Anda akan melihat peristiwa pengambilan kali ini untuk halaman dan asetnya (seperti CSS).
Klik link ke Halaman lainnya, Halaman lain, dan Kembali.
Anda akan melihat peristiwa pengambilan di konsol untuk setiap halaman dan asetnya. Apakah semua log masuk akal?
Catatan: Jika Anda mengunjungi halaman dan tidak menonaktifkan cache HTTP, aset CSS dan JavaScript dapat disimpan dalam cache secara lokal. Jika hal ini terjadi, Anda tidak akan melihat peristiwa pengambilan untuk resource ini.
Penjelasan
Pekerja layanan menerima peristiwa pengambilan untuk setiap permintaan HTTP yang dibuat oleh browser yang berada dalam cakupannya. Objek fetch event berisi permintaan. Mendeteksi peristiwa pengambilan di pekerja layanan mirip dengan memproses peristiwa klik di DOM. Dalam kode kita, saat peristiwa pengambilan terjadi, kita mencatat URL yang diminta ke konsol (dalam praktiknya kita juga bisa membuat dan mengembalikan respons khusus kita sendiri dengan resource arbitrer).
Mengapa tidak ada log aktivitas pengambilan pada pembaruan pertama? Secara default, mengambil peristiwa dari halaman tidak akan melalui pekerja layanan kecuali jika permintaan halaman itu sendiri melalui pekerja layanan. Hal ini akan memastikan konsistensi di situs; jika halaman dimuat tanpa pekerja layanan, sub-resource-nya juga akan dimuat.
Untuk informasi selengkapnya
Kode solusi
Untuk mendapatkan salinan kode yang berfungsi, buka folder 04-intercepting-network-requests/
.
Pekerja layanan memiliki cakupan. Cakupan pekerja layanan menentukan dari jalur mana pekerja layanan menangkap permintaan.
Menemukan cakupan
Perbarui kode pendaftaran di index.html
dengan:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('service-worker.js')
.then(registration => {
console.log('SW registered with scope:', registration.scope);
})
.catch(err => {
console.error('Registration failed:', err);
});
});
}
Muat ulang browser. Perhatikan bahwa konsol menampilkan cakupan pekerja layanan (dalam hal ini http://localhost:8081/
).
Penjelasan
Promise yang ditampilkan oleh register()
ditetapkan ke objek pendaftaran, yang berisi cakupan pekerja layanan.
Cakupan default adalah jalur ke file pekerja layanan, dan diperluas ke semua direktori bawah. Jadi, pekerja layanan di direktori utama aplikasi mengontrol permintaan dari semua file di aplikasi.
Memindahkan pekerja layanan
Pindahkan service-worker.js
ke direktori below/
dan perbarui URL pekerja layanan di kode pendaftaran di index.html
.
Batalkan pendaftaran pekerja layanan saat ini di browser dan muat ulang halaman.
Konsol menunjukkan bahwa cakupan pekerja layanan sekarang adalah http://localhost:8081/below/
. Di Chrome, Anda juga dapat melihat cakupan pekerja layanan di tab aplikasi DevTools:
Kembali ke halaman utama, klik Halaman lainnya, Halaman lain, dan Kembali. Permintaan pengambilan mana yang dicatat dalam log? Mana yang bukan?
Penjelasan
Cakupan default pekerja layanan adalah jalur ke file pekerja layanan. Karena file pekerja layanan kini berada di below/
, itulah cakupannya. Konsol kini hanya mencatat peristiwa pengambilan ke dalam log untuk another.html
, another.css
, dan another.js
, karena ini adalah satu-satunya resource dalam cakupan pekerja layanan.
Menetapkan cakupan arbitrer
Pindahkan pekerja layanan kembali ke direktori utama project (app/
) dan perbarui URL pekerja layanan dalam kode pendaftaran di index.html
.
Gunakan referensi pada MDN untuk menetapkan cakupan pekerja layanan ke direktori below/
menggunakan parameter opsional di register()
.
Batalkan pendaftaran pekerja layanan dan muat ulang halaman. Klik Halaman lainnya, Halaman lain, dan Kembali.
Sekali lagi, konsol menunjukkan bahwa cakupan pekerja layanan sekarang adalah http://localhost:8081/below/
, dan log mengambil peristiwa hanya untuk another.html
, another.css
, dan another.js
.
Penjelasan
Anda dapat menetapkan cakupan arbitrer dengan meneruskan parameter tambahan saat mendaftar, misalnya:
navigator.serviceWorker.register('/service-worker.js', {
scope: '/kitten/'
});
Pada contoh di atas, cakupan pekerja layanan ditetapkan ke /kitten/
. Pekerja layanan menangkap permintaan dari halaman dalam /kitten/
dan /kitten/lower/
, tetapi tidak dari halaman seperti /kitten
atau /
.
Catatan: Anda tidak dapat menetapkan cakupan arbitrer yang berada di atas lokasi sebenarnya pekerja layanan. Namun, jika pekerja server aktif pada klien yang dilayani dengan header Service-Worker-Allowed
, Anda dapat menentukan cakupan maksimal untuk pekerja layanan tersebut di atas lokasi pekerja layanan.
Untuk informasi selengkapnya
Kode solusi
Untuk mendapatkan salinan kode yang berfungsi, buka folder solution/
.
Anda sekarang telah menyiapkan serta menjalankan pekerja layanan sederhana serta memahami siklus proses pekerja layanan.
Untuk informasi selengkapnya
Untuk melihat semua codelab dalam kursus pelatihan PWA, lihat Codelab selamat datang untuk kursus/