Siapa pun yang telah menggunakan pekerja layanan
dapat memberi tahu Anda bahwa pekerja layanan bersifat asinkron. Fungsi ini bergantung secara eksklusif
pada antarmuka berbasis peristiwa, seperti
FetchEvent
,
dan menggunakan promise untuk
memberi sinyal saat operasi asinkron selesai.
Asinkronitas sama pentingnya, meskipun kurang terlihat oleh developer, dalam hal respons yang diberikan oleh pengendali peristiwa pengambilan pekerja layanan. Respons streaming adalah standar emas di sini: respons ini memungkinkan halaman yang membuat permintaan asli untuk mulai menggunakan respons segera setelah bagian data pertama tersedia, dan berpotensi menggunakan parser yang dioptimalkan untuk streaming guna menampilkan konten secara bertahap.
Saat menulis pengendali peristiwa fetch
Anda sendiri, biasanya Anda hanya meneruskan metode
respondWith()
Response
(atau promise untuk Response
) yang Anda dapatkan melalui
fetch()
atau caches.match()
,
dan selesai. Kabar baiknya adalah Response
yang dibuat oleh kedua
metode tersebut sudah dapat di-streaming. Kabar buruknya adalah Response
yang "dibuat secara manual"
tidak dapat di-streaming, setidaknya hingga saat ini. Di sinilah
Streams API berperan.
Streaming?
Aliran data adalah sumber data yang dapat
dibuat dan dimanipulasi secara bertahap,
dan menyediakan antarmuka untuk membaca atau menulis potongan data asinkron,
hanya sebagian yang mungkin tersedia dalam memori pada waktu tertentu. Untuk saat ini,
kita tertarik dengan 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 mendapatkan respons streaming
segera setelah event.respondWith()
dipanggil, dan akan terus membaca dari
streaming tersebut selama pekerja layanan terus enqueue()
ing data tambahan. Respons yang mengalir dari service worker ke halaman benar-benar
asinkron, dan kita memiliki kontrol penuh atas pengisian streaming.
Penggunaan di dunia nyata
Anda mungkin telah melihat bahwa contoh sebelumnya memiliki beberapa komentar
/* your data here */
placeholder, dan tidak memiliki detail implementasi yang sebenarnya.
Jadi, seperti apa contohnya di dunia nyata?
Jake Archibald (tidak mengherankan!) memiliki
contoh bagus
penggunaan streaming untuk menggabungkan respons HTML dari beberapa cuplikan HTML
yang di-cache, bersama dengan data "live" yang di-streaming melalui fetch()
—dalam hal ini, konten
untuk blog-nya
Keuntungan menggunakan respons streaming, seperti yang dijelaskan Jake, adalah browser dapat mengurai dan merender HTML saat di-streaming, termasuk bit awal yang dimuat dengan cepat dari cache, tanpa harus menunggu penarikan seluruh konten blog selesai. Hal ini memanfaatkan sepenuhnya kemampuan rendering HTML progresif browser. Resource lain yang juga dapat dirender secara progresif, seperti beberapa format gambar dan video, juga dapat memperoleh manfaat dari pendekatan ini.
Streaming? Atau shell aplikasi?
Praktik terbaik yang ada terkait penggunaan pekerja layanan untuk mendukung aplikasi web Anda berfokus pada model Shell Aplikasi + konten dinamis. Pendekatan tersebut mengandalkan penyimpanan dalam cache "shell" aplikasi web Anda secara agresif—HTML, JavaScript, dan CSS minimal yang diperlukan untuk menampilkan struktur dan tata letak—lalu memuat konten dinamis yang diperlukan untuk setiap halaman tertentu melalui permintaan sisi klien.
Streaming menghadirkan alternatif untuk model App Shell, yaitu ada respons HTML yang lebih lengkap yang di-streaming ke browser saat pengguna membuka halaman baru. Respons yang di-streaming dapat menggunakan resource yang di-cache—sehingga dapat tetap memberikan bagian awal HTML dengan cepat, bahkan saat offline.—tetapi respons tersebut akhirnya terlihat lebih seperti isi respons tradisional yang dirender server. Misalnya, jika aplikasi web Anda didukung oleh sistem pengelolaan konten yang merender HTML server dengan menggabungkan template parsial, model tersebut akan diterjemahkan langsung ke dalam penggunaan respons streaming, dengan logika pembuatan template direplikasi di pekerja layanan, bukan server Anda. Seperti yang ditunjukkan dalam video berikut, untuk kasus penggunaan tersebut, keunggulan kecepatan yang ditawarkan respons streaming dapat sangat mencolok:
Salah satu keuntungan penting dari streaming seluruh respons HTML, yang menjelaskan mengapa ini adalah alternatif tercepat dalam video, adalah bahwa 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 biasa dilakukan dalam model App Shell) tidak dapat memanfaatkan pengoptimalan ini.
Jadi, jika Anda berada dalam tahap perencanaan penerapan pekerja layanan, model manakah yang harus Anda adopsi: respons streaming yang dirender secara progresif, atau shell ringan yang digabungkan dengan permintaan sisi klien untuk konten dinamis? Jawabannya adalah, tidak mengherankan, bahwa hal ini bergantung: pada apakah Anda memiliki implementasi yang ada yang mengandalkan CMS dan template parsial (keuntungan: streaming); pada apakah Anda mengharapkan payload HTML tunggal yang besar yang akan mendapatkan manfaat dari rendering progresif (keuntungan: streaming); pada apakah aplikasi web Anda paling baik dimodelkan sebagai aplikasi web satu halaman (keuntungan: App Shell); dan pada apakah Anda memerlukan model yang saat ini didukung di beberapa rilis stabil browser (keuntungan: App Shell).
Kami masih berada di tahap awal respons streaming yang didukung pekerja layanan, dan kami berharap dapat melihat berbagai model yang matang dan terutama melihat lebih banyak alat yang dikembangkan untuk mengotomatiskan kasus penggunaan umum.
Mempelajari streaming lebih dalam
Jika Anda membuat streaming yang dapat dibaca sendiri, memanggil
controller.enqueue()
secara sembarangan mungkin tidak memadai atau
efisien. Jake menjelaskan beberapa detail
tentang cara metode start()
, pull()
, dan cancel()
dapat digunakan secara bersamaan
untuk membuat aliran data yang disesuaikan dengan kasus penggunaan Anda.
Bagi Anda yang menginginkan detail lebih lanjut, spesifikasi Streaming dapat membantu Anda.
Kompatibilitas
Dukungan untuk membuat objek Response
di dalam pekerja layanan menggunakan
ReadableStream
sebagai 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 pada dukungan Streams API tanpa awalan di Edge, beserta dukungan pekerja layanan secara keseluruhan, dapat dilacak di halaman status Platform Microsoft.