Bangun PWA Dengan Webpack Dan Workbox
Diterbitkan: 2022-03-10Progressive Web App (PWA) adalah situs yang menggunakan teknologi modern untuk memberikan pengalaman seperti aplikasi di web. Ini adalah istilah umum untuk teknologi baru seperti 'manifes aplikasi web', 'pekerja layanan', dan banyak lagi. Ketika digabungkan bersama, teknologi ini memungkinkan Anda memberikan pengalaman pengguna yang cepat dan menarik dengan situs web Anda.
Artikel ini adalah tutorial langkah demi langkah untuk menambahkan pekerja layanan ke situs web satu halaman yang sudah ada. Pekerja layanan akan memungkinkan Anda membuat situs web Anda bekerja secara offline sambil juga memberi tahu pengguna tentang pembaruan ke situs Anda. Harap dicatat bahwa ini didasarkan pada proyek kecil yang dibundel dengan Webpack, jadi kami akan menggunakan plugin Workbox Webpack (Workbox v4).
Menggunakan alat untuk menghasilkan pekerja layanan Anda adalah pendekatan yang disarankan karena memungkinkan Anda mengelola cache secara efisien. Kami akan menggunakan Workbox — satu set pustaka yang memudahkan pembuatan kode service worker Anda — untuk menghasilkan service worker kami dalam tutorial ini.
Bergantung pada proyek Anda, Anda dapat menggunakan Workbox dalam tiga cara berbeda:
- Tersedia antarmuka baris perintah yang memungkinkan Anda mengintegrasikan kotak kerja ke dalam aplikasi apa pun yang Anda miliki;
- Modul Node.js tersedia yang memungkinkan Anda mengintegrasikan kotak kerja ke alat pembuatan Node apa pun seperti gulp atau grunt;
- Tersedia plugin webpack yang memungkinkan Anda berintegrasi dengan mudah dengan proyek yang dibuat dengan Webpack.
Webpack adalah bundler modul. Untuk menyederhanakan, Anda dapat menganggapnya sebagai alat yang mengelola dependensi JavaScript Anda. Ini memungkinkan Anda untuk mengimpor kode JavaScript dari perpustakaan dan menggabungkan JavaScript Anda menjadi satu atau banyak file.
Untuk memulai, klon repositori berikut di komputer Anda:
git clone [email protected]:jadjoubran/workbox-tutorial-v4.git cd workbox-tutorial-v4 npm install npm run dev
Selanjutnya, navigasikan ke https://localhost:8080/
. Anda seharusnya dapat melihat aplikasi mata uang yang akan kami gunakan selama tutorial ini:
Mulai Dengan Shell Aplikasi
Shell aplikasi (atau 'app shell') adalah pola yang terinspirasi dari Native Apps. Ini akan membantu memberikan aplikasi Anda tampilan yang lebih asli. Ini hanya menyediakan aplikasi dengan tata letak dan struktur tanpa data apa pun — layar transisi yang bertujuan untuk meningkatkan pengalaman memuat aplikasi web Anda.
Berikut adalah beberapa contoh shell aplikasi dari aplikasi asli:
Dan berikut adalah contoh shell aplikasi dari PWA:
Pengguna menyukai pengalaman memuat shell aplikasi karena mereka tidak menyukai layar kosong. Layar kosong membuat pengguna merasa bahwa situs web tidak memuat. Itu membuat mereka merasa seolah-olah situs web itu macet.
Cangkang aplikasi berusaha melukis struktur navigasi aplikasi sesegera mungkin, seperti bilah navigasi, bilah tab, serta pemuat yang menandakan bahwa konten yang Anda minta sedang dimuat.
Jadi Bagaimana Anda Membangun Shell Aplikasi?
Pola shell aplikasi memprioritaskan pemuatan HTML, CSS, dan JavaScript yang akan dirender terlebih dahulu. Ini berarti bahwa kita perlu memberikan sumber daya tersebut prioritas penuh, maka Anda harus menyelaraskan aset tersebut. Jadi untuk membangun shell aplikasi, Anda hanya perlu memasukkan HTML, CSS, dan JavaScript yang bertanggung jawab untuk shell aplikasi. Tentu saja, Anda tidak boleh meng-inline semuanya melainkan tetap dalam batas sekitar 30 hingga 40KB total.
Anda dapat melihat shell aplikasi sebaris di index.html . Anda dapat memeriksa kode sumber dengan memeriksa file index.html , dan Anda dapat mempratinjaunya di browser dengan menghapus elemen <main>
di alat dev:
Apakah Ini Bekerja Offline?
Mari kita simulasikan offline! Buka DevTools, navigasikan ke tab jaringan dan centang kotak 'Offline'. Saat Anda memuat ulang halaman, Anda akan melihat bahwa kami akan mendapatkan halaman offline browser.
Itu karena permintaan awal ke /
(yang akan memuat file index.html ) akan gagal karena Internet sedang offline. Satu-satunya cara bagi kami untuk pulih dari kegagalan permintaan itu adalah dengan memiliki pekerja layanan.
Mari kita visualisasikan permintaan tanpa pekerja layanan:
Pekerja layanan adalah proxy jaringan yang dapat diprogram, yang berarti ia berada di antara halaman web Anda dan Internet. Ini memungkinkan Anda mengontrol permintaan jaringan yang masuk dan keluar.
Ini bermanfaat karena kami sekarang dapat merutekan ulang permintaan yang gagal ini ke cache (dengan asumsi kami memiliki konten dalam cache).
Service worker juga merupakan tipe Web Worker, artinya ia berjalan secara terpisah dari halaman utama Anda dan tidak memiliki akses ke objek window
atau document
.
Precache Shell Aplikasi
Untuk membuat aplikasi kita bekerja secara offline, kita akan mulai dengan melakukan precache shell aplikasi.
Jadi mari kita mulai dengan menginstal plugin Webpack Workbox:
npm install --save-dev workbox-webpack-plugin
Kemudian kita akan membuka file index.js dan mendaftarkan service worker:
if ("serviceWorker" in navigator){ window.addEventListener("load", () => { navigator.serviceWorker.register("/sw.js"); }) }
Selanjutnya, buka file webpack.config.js dan mari kita konfigurasikan plugin webpack Workbox:
//add at the top const WorkboxWebpackPlugin = require("workbox-webpack-plugin"); //add inside the plugins array: plugins: [ … , new WorkboxWebpackPlugin.InjectManifest({ swSrc: "./src/src-sw.js", swDest: "sw.js" }) ]
Ini akan menginstruksikan Workbox untuk menggunakan file ./src/src-sw.js kami sebagai basis. File yang dihasilkan akan disebut sw.js dan akan berada di folder dist
.
Kemudian buat file ./src/src-sw.js di tingkat root dan tulis yang berikut di dalamnya:
workbox.precaching.precacheAndRoute(self.__precacheManifest);
Catatan : Variabel self.__precacheManifest
akan diimpor dari file yang akan dihasilkan secara dinamis oleh workbox.
Sekarang Anda siap untuk membangun kode Anda dengan npm run build
dan Workbox akan menghasilkan dua file di dalam folder dist
:
- precache-manifest.66cf63077c7e4a70ba741ee9e6a8da29.js
- sw.js
sw.js mengimpor kotak kerja dari CDN serta manifes pra-cache.[chunkhash].js .
//precache-manifest.[chunkhash].js file self.__precacheManifest = (self.__precacheManifest || []).concat([ "revision": "ba8f7488757693a5a5b1e712ac29cc28", "url": "index.html" }, "url": "main.49467c51ac5e0cb2b58e.js" ]);
Manifes precache mencantumkan nama file yang diproses oleh webpack dan yang berakhir di folder dist
Anda. Kami akan menggunakan file-file ini untuk melakukan precache di browser. Ini berarti bahwa ketika situs web Anda memuat pertama kali dan mendaftarkan pekerja layanan, aset tersebut akan disimpan dalam cache sehingga dapat digunakan di lain waktu.
Anda juga dapat melihat bahwa beberapa entri memiliki 'revisi' sedangkan yang lain tidak. Itu karena revisi terkadang dapat disimpulkan dari chunkhash dari nama file. Sebagai contoh, mari kita lihat lebih dekat nama file main.49467c51ac5e0cb2b58e.js . Ini memiliki revisi dalam nama file, yang merupakan chunkhash 49467c51ac5e0cb2b58e .
Ini memungkinkan Workbox untuk memahami kapan file Anda berubah sehingga hanya membersihkan atau memperbarui file yang diubah, daripada membuang semua cache setiap kali Anda memublikasikan versi baru pekerja layanan Anda.
Pertama kali Anda memuat halaman, pekerja layanan akan menginstal. Anda dapat melihatnya di DevTools. Pertama, file sw.js diminta yang kemudian meminta semua file lainnya. Mereka ditandai dengan jelas dengan ikon roda gigi.
Jadi Workbox akan menginisialisasi dan akan melakukan precache semua file yang ada di manifes precache. Penting untuk memeriksa ulang bahwa Anda tidak memiliki file yang tidak perlu dalam file manifes pra-cache seperti file .map atau file yang bukan bagian dari shell aplikasi.
Di tab jaringan, kita dapat melihat permintaan yang datang dari pekerja layanan. Dan sekarang jika Anda mencoba offline, shell aplikasi sudah di-cache sehingga berfungsi bahkan jika kita offline!
Rute Dinamis Cache
Apakah Anda memperhatikan bahwa ketika kami offline, shell aplikasi berfungsi tetapi tidak data kami? Itu karena panggilan API ini bukan bagian dari shell aplikasi yang sudah di-cache . Saat tidak ada koneksi Internet, permintaan ini akan gagal dan pengguna tidak akan dapat melihat informasi mata uang.
Namun, permintaan ini tidak dapat di-cache karena nilainya berasal dari API. Selain itu, ketika Anda mulai memiliki banyak halaman, Anda tidak ingin men-cache semua permintaan API sekaligus. Sebagai gantinya, Anda ingin menyimpannya di cache ketika pengguna mengunjungi halaman itu.
Kami menyebutnya 'data dinamis'. Mereka sering menyertakan panggilan API serta gambar dan aset lain yang diminta saat pengguna melakukan tindakan tertentu di situs web Anda (misalnya saat mereka menjelajah ke halaman baru).
Anda dapat menyimpannya dalam cache menggunakan modul perutean Workbox. Berikut caranya:
//add in src/src-sw.js workbox.routing.registerRoute( /https:\/\/api\.exchangeratesapi\.io\/latest/, new workbox.strategies.NetworkFirst({ cacheName: "currencies", plugins: [ new workbox.expiration.Plugin({ maxAgeSeconds: 10 * 60 // 10 minutes }) ] }) );
Ini akan menyiapkan caching dinamis untuk URL permintaan apa pun yang cocok dengan URL https://api.exchangeratesapi.io/latest
.
Strategi caching yang kami gunakan di sini disebut NetworkFirst
; ada dua yang lain yang sering digunakan:
-
CacheFirst
-
StaleWhileRevalidate
CacheFirst
akan mencarinya di cache terlebih dahulu. Jika tidak ditemukan, maka akan mendapatkannya dari jaringan. StaleWhileRevalidate
akan masuk ke jaringan dan cache secara bersamaan. Kembalikan respons cache ke halaman (sementara di latar belakang) itu akan menggunakan respons jaringan baru untuk memperbarui cache saat digunakan berikutnya.
Untuk kasus penggunaan kami, kami harus menggunakan NetworkFirst
karena kami berurusan dengan nilai tukar mata uang yang sangat sering berubah. Namun, ketika pengguna offline, kami setidaknya dapat menunjukkan kepada mereka tarif seperti 10 menit yang lalu — itulah mengapa kami menggunakan plugin kedaluwarsa dengan maxAgeSeconds
disetel ke 10 * 60
detik.
Kelola Pembaruan Aplikasi
Setiap kali pengguna memuat halaman Anda, browser akan menjalankan kode navigator.serviceWorker.register
meskipun service worker sudah diinstal dan dijalankan. Ini memungkinkan browser untuk mendeteksi jika ada versi baru dari service worker. Ketika browser melihat bahwa file tidak berubah, itu hanya melewatkan panggilan pendaftaran. Setelah file itu berubah, browser memahami bahwa ada versi baru dari service worker, sehingga ia menginstal service worker baru secara paralel dengan service worker yang sedang berjalan .
Namun, itu berhenti pada fase installed/waiting
karena hanya satu pekerja layanan yang dapat diaktifkan pada saat yang sama.
Hanya ketika semua jendela browser yang dikontrol oleh service worker sebelumnya ditutup, maka service worker baru menjadi aman untuk diaktifkan.
Anda juga dapat mengontrolnya secara manual dengan memanggil skipWaiting()
(atau self.skipWaiting()
karena self
adalah konteks eksekusi global dalam service worker). Namun, sebagian besar waktu Anda hanya boleh melakukannya setelah menanyakan kepada pengguna apakah mereka ingin mendapatkan pembaruan terbaru.
Untungnya, workbox-window
membantu kami mencapai ini. Ini adalah perpustakaan jendela baru yang diperkenalkan di Workbox v4 yang bertujuan untuk menyederhanakan tugas-tugas umum di sisi jendela.
Mari kita mulai dengan menginstalnya dengan yang berikut ini:
npm install workbox-window
Selanjutnya, impor Workbox
di bagian atas file index.js :
import { Workbox } from "workbox-window";
Kemudian kami akan mengganti kode registrasi kami dengan di bawah ini:
if ("serviceWorker" in navigator) { window.addEventListener("load", () => { const wb = new Workbox("/sw.js"); wb.register(); }); }
Kami kemudian akan menemukan tombol perbarui yang memiliki IDworkbox-waiting
kotak kerja:
//add before the wb.register() const updateButton = document.querySelector("#app-update"); // Fires when the registered service worker has installed but is waiting to activate. wb.addEventListener("waiting", event => { updateButton.classList.add("show"); updateButton.addEventListener("click", () => { // Set up a listener that will reload the page as soon as the previously waiting service worker has taken control. wb.addEventListener("controlling", event => { window.location.reload(); }); // Send a message telling the service worker to skip waiting. // This will trigger the `controlling` event handler above. wb.messageSW({ type: "SKIP_WAITING" }); }); });
Kode ini akan menampilkan tombol update saat ada update baru (jadi saat service worker dalam keadaan menunggu) dan akan mengirimkan pesan SKIP_WAITING
ke service worker.
Kita perlu memperbarui file service worker dan menangani event SKIP_WAITING
sehingga memanggil skipWaiting
:
//add in src-sw.js addEventListener("message", event => { if (event.data && event.data.type === "SKIP_WAITING") { skipWaiting(); });
Sekarang jalankan npm run dev
lalu muat ulang halaman. Masuk ke kode Anda dan perbarui judul navbar menjadi "Navbar v2". Muat ulang halaman lagi, dan Anda seharusnya dapat melihat ikon pembaruan.
Membungkus
Situs web kami sekarang berfungsi offline dan dapat memberi tahu pengguna tentang pembaruan baru. Harap diingat, bahwa faktor terpenting saat membangun PWA adalah pengalaman pengguna. Selalu fokus untuk membangun pengalaman yang mudah digunakan oleh pengguna Anda. Kami, sebagai pengembang, cenderung terlalu tertarik dengan teknologi dan sering kali melupakan pengguna kami.
Jika Anda ingin mengambil langkah lebih jauh, Anda dapat menambahkan manifes aplikasi web yang memungkinkan pengguna Anda menambahkan situs ke layar beranda mereka. Dan jika Anda ingin tahu lebih banyak tentang Workbox, Anda dapat menemukan dokumentasi resmi di situs web Workbox.
Bacaan Lebih Lanjut tentang SmashingMag:
- Bisakah Anda Menghasilkan Lebih Banyak Uang Dengan Aplikasi Seluler Atau PWA?
- Panduan Lengkap Untuk Aplikasi Web Progresif
- Asli Dan PWA: Pilihan, Bukan Penantang!
- Membangun PWA Menggunakan Angular 6