Siapa pun yang menggunakan pekerja layanan dapat mengetahui bahwa mereka berjalan secara asinkron. Library klien ini hanya mengandalkan antarmuka berbasis peristiwa, seperti FetchEvent
, dan menggunakan promise untuk memberikan sinyal saat operasi asinkron selesai.
Asinkronisasi juga sama pentingnya, meskipun kurang terlihat oleh developer, dalam hal respons yang diberikan oleh pengendali peristiwa pengambilan pekerja layanan. Respons streaming adalah standar terbaik di sini: memungkinkan halaman yang membuat permintaan asli mulai menangani respons segera setelah bagian data pertama tersedia, dan berpotensi menggunakan parser yang dioptimalkan untuk streaming agar secara bertahap menampilkan konten.
Saat menulis pengendali peristiwa fetch
Anda sendiri, biasanya Anda cukup meneruskan metode respondWith()
Response
(atau promise untuk Response
) yang Anda dapatkan melalui fetch()
atau caches.match()
, dan menghentikannya sehari. Kabar baiknya adalah Response
yang dibuat oleh kedua
metode tersebut sudah dapat di-streaming. Kabar buruknya adalah Response
yang "secara manual"
dibuat
tidak dapat di-streaming, setidaknya sampai sekarang. Di sinilah
Streams API akan masuk.
Streaming?
Aliran data adalah sumber data yang dapat
dibuat dan dimanipulasi secara bertahap,
dan menyediakan antarmuka untuk membaca atau menulis potongan data asinkron,
hanya subset yang mungkin tersedia dalam memori pada waktu tertentu. Untuk saat ini,
kita akan tertarik pada ReadableStream
,
yang dapat digunakan untuk membuat
objek Response
yang diteruskan ke fetchEvent.respondWith()
:
self.addEventListener('fetch', event => {
var stream = new ReadableStream({
start(controller) {
if (/* there's more data */) {
controller.enqueue(/* your data here */);
} else {
controller.close();
}
});
});
var response = new Response(stream, {
headers: {'content-type': /* your content-type here */}
});
event.respondWith(response);
});
Halaman yang permintaannya memicu peristiwa fetch
akan segera mendapatkan respons
streaming segera setelah event.respondWith()
dipanggil, dan akan terus membaca dari
aliran tersebut selama pekerja layanan terus melakukan enqueue()
data tambahan. Respons yang mengalir dari pekerja layanan ke halaman benar-benar
asinkron, dan kita memiliki kontrol penuh untuk mengisi aliran data.
Penggunaan di dunia nyata
Anda mungkin telah memperhatikan bahwa contoh sebelumnya memiliki beberapa komentar
/* your data here */
placeholder, dan ringan pada detail penerapan yang sebenarnya.
Jadi akan seperti apa contoh
dunia nyata terlihat?
Jake Archibald (tidak mengherankan!) memiliki
contoh bagus
tentang penggunaan streaming untuk merangkai respons HTML dari beberapa cuplikan
HTML yang di-cache, bersama dengan data "live" yang distreaming melalui fetch()
—dalam hal ini, konten
untuk blog-nya
Keuntungan menggunakan respons streaming, seperti yang dijelaskan Jake, adalah bahwa browser dapat mengurai dan merender HTML saat mengalir, termasuk bit awal yang dimuat dengan cepat dari cache, tanpa harus menunggu seluruh pengambilan konten blog selesai. Cara ini akan memanfaatkan sepenuhnya kemampuan rendering HTML progresif browser. Resource lain yang juga dapat dirender secara bertahap, seperti beberapa format gambar dan video, juga dapat memperoleh manfaat dari pendekatan ini.
Streaming? Atau app shell?
Praktik terbaik yang ada terkait penggunaan pekerja layanan untuk mendukung aplikasi web Anda berfokus pada model Shell Aplikasi + konten dinamis. Pendekatan tersebut bergantung pada penyimpanan cache "shell" aplikasi web Anda secara agresif—HTML, JavaScript, dan CSS minimal yang diperlukan untuk menampilkan struktur dan tata letak Anda—lalu memuat konten dinamis yang diperlukan untuk setiap halaman tertentu melalui permintaan sisi klien.
Aliran data membawa alternatif untuk model Shell Aplikasi, yaitu ada respons HTML yang lebih lengkap yang di-streaming ke browser saat pengguna membuka halaman baru. Respons yang di-streaming dapat memanfaatkan resource yang di-cache sehingga tetap dapat menyediakan potongan awal HTML dengan cepat, bahkan saat offline!—tetapi pada akhirnya terlihat lebih seperti isi respons tradisional yang dirender server. Misalnya, jika aplikasi web Anda didukung oleh sistem pengelolaan konten yang merender HTML oleh server dengan menggabungkan template parsial, model tersebut akan langsung diterjemahkan menjadi menggunakan respons streaming, dengan logika template yang direplikasi dalam pekerja layanan, bukan server Anda. Seperti yang ditunjukkan dalam video berikut, untuk kasus penggunaan tersebut, keunggulan kecepatan yang ditawarkan respons streaming dapat sangat mengejutkan:
Salah satu keuntungan penting streaming seluruh respons HTML, yang menjelaskan alasan ini menjadi alternatif tercepat dalam video, adalah HTML yang dirender selama permintaan navigasi awal dapat memanfaatkan sepenuhnya parser HTML streaming browser. Potongan HTML yang disisipkan ke dalam dokumen setelah halaman dimuat (seperti yang umum dalam model Shell Aplikasi) tidak dapat memanfaatkan pengoptimalan ini.
Jadi, jika Anda sedang dalam tahap perencanaan implementasi pekerja layanan, model mana yang harus Anda adopsi: respons yang di-streaming yang dirender secara bertahap, atau shell ringan yang digabungkan dengan permintaan sisi klien untuk konten dinamis? Jawabannya, tidak mengherankan, semuanya bergantung: pada apakah Anda sudah memiliki implementasi yang mengandalkan CMS dan template sebagian (kelebihan: stream); pada apakah Anda mengharapkan payload HTML tunggal berukuran besar yang akan mendapat manfaat dari rendering progresif (unggul: stream); pada apakah aplikasi web Anda paling baik dimodelkan sebagai aplikasi web satu halaman (keunggulan: App Shell saat ini); dan apakah Anda memerlukan model yang didukung di beberapa browser saat ini (keunggulan: App Shell).
Kami masih dalam tahap awal respons streaming yang didukung pekerja layanan, dan kami tidak sabar untuk melihat berbagai model matang, terutama untuk melihat lebih banyak alat yang dikembangkan untuk mengotomatiskan kasus penggunaan umum.
Mempelajari feed lebih dalam
Jika Anda membuat streaming yang dapat dibaca sendiri, memanggil
controller.enqueue()
secara acak mungkin tidak akan cukup atau
efisien. Jake menjelaskan beberapa detail
tentang cara metode start()
, pull()
, dan cancel()
dapat digunakan bersama
untuk membuat aliran data yang disesuaikan dengan kasus penggunaan Anda.
Jika Anda ingin mengetahui detail lebih lanjut, baca spesifikasi Streaming.
Kompatibilitas
Dukungan untuk membuat objek Response
di dalam pekerja layanan menggunakan
ReadableStream
seperti sumbernya ditambahkan di
Chrome 52.
Implementasi pekerja layanan Firefox belum mendukung respons yang didukung oleh ReadableStream
, tetapi ada bug pelacakan yang relevan untuk dukungan Streams API yang dapat Anda ikuti.
Progres untuk dukungan Streams API tanpa awalan di Edge, beserta dukungan pekerja layanan secara keseluruhan, dapat dilacak di Halaman status platform Microsoft.