Bangun PWA Dengan Webpack Dan Workbox

Diterbitkan: 2022-03-10
Ringkasan cepat Tutorial ini akan membantu Anda mengubah aplikasi yang tidak berfungsi offline menjadi PWA yang berfungsi offline dan menampilkan ikon pembaruan yang tersedia. Anda akan mempelajari cara melakukan precache aset dengan workbox, menangani caching dinamis, serta menangani pembaruan pada PWA Anda. Ikuti dan lihat bagaimana Anda juga dapat menerapkan teknik ini di situs web Anda.

Progressive 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:

  1. Tersedia antarmuka baris perintah yang memungkinkan Anda mengintegrasikan kotak kerja ke dalam aplikasi apa pun yang Anda miliki;
  2. Modul Node.js tersedia yang memungkinkan Anda mengintegrasikan kotak kerja ke alat pembuatan Node apa pun seperti gulp atau grunt;
  3. 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.

Lebih banyak setelah melompat! Lanjutkan membaca di bawah ini

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:

Tangkapan layar aplikasi mata uang yang kami buat di artikel ini.
'Mata Uang' adalah PWA yang mencantumkan biaya konversi mata uang terhadap mata uang Euro (€). (Pratinjau besar)

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:

Shell Aplikasi Kotak Masuk Google
Google Inbox App Shell: Beberapa milidetik sebelum email dimuat ke dalam shell aplikasi. (Pratinjau besar)
Shell Aplikasi asli Twitter
Aplikasi asli Twitter di Android: App shell menampilkan navbar, tab, dan loader. (Pratinjau besar)

Dan berikut adalah contoh shell aplikasi dari PWA:

App Shell dari PWA Twitter
Cangkang aplikasi PWA Twitter (Pratinjau besar)
App Shell dari PWA Flipkart
Cangkang aplikasi PWA Flipkart (Pratinjau besar)

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:

Mata Uang PWA App Shell dengan navbar & loader
Shell Aplikasi yang kami buat dalam artikel ini. (Pratinjau besar)

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.

Halaman kesalahan offline browser
Permintaan ke beranda gagal jadi kami jelas melihat ini sebagai hasilnya. (Pratinjau besar)

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:

Animasi permintaan jaringan dari browser klien ke internet.
Permintaan jaringan beralih dari browser ke Internet dan kembali. (Ikon dari flaticon.com) (Pratinjau besar)

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.

Animasi permintaan jaringan yang dicegat oleh pekerja layanan.
Permintaan jaringan dicegat oleh pekerja layanan. (Ikon dari flaticon.com) (Pratinjau besar)

Ini bermanfaat karena kami sekarang dapat merutekan ulang permintaan yang gagal ini ke cache (dengan asumsi kami memiliki konten dalam cache).

Animasi permintaan jaringan yang diterima oleh pekerja layanan dan dialihkan ke cache.
Permintaan jaringan dialihkan ke cache ketika sudah ada di cache. (Ikon dari flaticon.com) (Pratinjau besar)

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.

Cuplikan layar tab Jaringan DevTools saat pekerja layanan diinstal.
Permintaan yang ditandai dengan ikon ️ adalah permintaan yang diprakarsai oleh pekerja layanan. (Pratinjau besar)

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!

Cuplikan layar tab Jaringan Alat Dev yang menunjukkan panggilan API gagal.
Panggilan API gagal saat kita offline. (Pratinjau besar)

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:

  1. CacheFirst
  2. 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.

Siklus hidup service worker: Diurai, Diinstal/Menunggu, Diaktifkan & Redundan
Siklus hidup pekerja layanan yang disederhanakan (Pratinjau besar)

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 ID pembaruan aplikasi dan dengarkan acara workbox-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