Kehendak soalan dan senario yang berkaitan
Aplikasi analitik asal sama (same-origin) mempunyai tiga keperluan bebas:
- Menghuraikan CSV 200 MiB yang dipilih pengguna secara setempat sementara input dan persembahan visual (rendering) kekal responsif.
- Berkongsi satu WebSocket dan keadaan langganan dalam ingatan (in-memory) merentasi tab selagi sekurang-kurangnya satu tab kekal dibuka.
- Membuka rangka aplikasi (app shell) dan laporan berjaya yang terakhir secara luar talian, memasukkan satu operasi simpan ke dalam baris gilir, dan mencuba semula selepas sambungan kembali pulih.
Pilih antara Dedicated Worker, SharedWorker, dan Service Worker bagi setiap keperluan. Terangkan pemilikan, jangka hayat, komunikasi, ketahanan data, pengendalian pembatalan dan kegagalan, sandaran pelayar (browser fallbacks), sempadan keselamatan, serta pengesahan.
Fail 200 MiB, satu WebSocket tunggal, dan penyimpanan luar talian hanyalah andaian temu duga, bukan sasaran produk sejagat. Soalan ini sesuai untuk peranan frontend kanan, platform Web, dan seni bina frontend. Kemahiran terasnya ialah pelaksanaan pelayar dan pemilihan platform Web, jadi kategorinya ialah frontend.
Perkara yang dinilai oleh penemu duga
Pertama, bolehkah calon memilih berdasarkan pihak yang memiliki tugas, tempoh hayatnya, dan halaman yang terkesan dan bukannya menggelar setiap bebenang latar belakang (background thread) sebagai Web Worker semata-mata? Jawapan yang kukuh mengagihkan pengiraan milik halaman kepada Dedicated Worker, keadaan berbilang halaman asal sama sementara kepada SharedWorker, serta proksi rangkaian berskop, caching, dan tugasan latar belakang berasaskan peristiwa kepada Service Worker.
Kedua, bolehkah calon membezakan konsep pembebenangan (threading) daripada ketahanan data (persistence)? Memindahkan kod keluar daripada bebenang utama tidak mengurangkan CPU, memori, atau I/O secara automatik. Memori SharedWorker bukan keadaan yang tahan lama. Pelayar boleh menghentikan Service Worker di antara peristiwa, jadi tugas yang menunggu perlu disimpan dalam storan tahan lama seperti IndexedDB.
Ketiga, bolehkah calon mengukur kos pemesejan? Pengklonan berstruktur (structured cloning) lazimnya menyalin data. Suatu ArrayBuffer boleh dipindahkan agar pemilikannya berpindah tanpa salinan bait demi bait yang lain, tetapi penimbal (buffer) penghantar akan terpisah (detached). Pengendalian CSV yang besar juga memerlukan pemecahan ketulan (chunking), penjejakan kemajuan, tekanan balik (backpressure), dan pembatalan.
Keempat, bolehkah calon menyediakan strategi sandaran yang betul? SharedWorker telah mencapai Baseline 2026 dalam versi pelayar semasa, tetapi peranti yang lebih lama dan sesetengah pelaksanaan mungkin tidak menyokongnya. Background Sync masih belum menjadi Baseline. Ketepatan fungsi tidak boleh bergantung pada satu API pilihan.
Kelima, bolehkah calon menguji kegagalan kitaran hayat? Satu klik lalu laluan lancar (happy path) tidak mencukupi. Muat semula, penutupan tab terakhir, kemas kini Service Worker, pemulaan semula luar talian, peristiwa penyelarasan pendua, pencemaran cache, dan sandaran pelayar lama semuanya penting.
Soalan untuk dijelaskan terlebih dahulu
- Adakah penghuraian CSV berlaku sekali-sekala atau berterusan? Kerja sekali sahaja boleh mencipta satu Dedicated Worker atas permintaan. Kerja serentak yang berterusan memerlukan kolam worker terikat (bounded worker pool) dan baris gilir dan bukannya satu bebenang baharu bagi setiap fail.
- Adakah keseluruhan input mesti berada dalam memori? Utamakan input penstriman atau berketul (chunked) jika penghurai menyokongnya. Jika keseluruhan
ArrayBuffermesti dipindahkan sekali gus, sediakan bajet memori berasingan untuk bait mentah, rentetan ternyahkod, nilai terhurai, dan indeks. - Adakah semua tab betul-betul berasal sama (same-origin)? SharedWorker memerlukan skema, hos, dan port yang sama. Subdomain, iframe pihak ketiga, atau port pembangunan yang berbeza akan mengubah reka bentuk komunikasi.
- Adakah satu WebSocket itu satu pengoptimuman atau kekangan ketepatan logik? Jika ia hanya untuk menjimatkan sambungan, sambungan bagi setiap tab adalah sandaran yang sah. Jika pelayan hanya membenarkan satu sesi, sandaran memerlukan BroadcastChannel, pemilihan ketua (leader election), pajakan (leases), dan pemulihan pemecahan otak (split-brain).
- Bolehkah penyimpanan luar talian dicuba semula secara automatik? Operasi yang sensitif atau bercanggah mungkin memerlukan pengesahan pengguna selepas halaman kembali dibuka. Percubaan semula automatik memerlukan kunci keidempotanan (idempotency key), keadaan tahan lama, dan penangguhan terikat (bounded backoff).
- Pelayar lama dan mod privasi yang manakah berada dalam skop? Jawapan itu menetapkan pengesanan ciri dan sempadan sandaran untuk SharedWorker, Background Sync, kuota storan, dan kelakuan Service Worker.
Rangka kerja jawapan 30 saat
"Saya akan membahagikan keperluan mengikut pemilikan dan jangka hayat. CSV 200 MiB adalah kerja berat CPU yang dimiliki oleh halaman semasa, jadi saya akan menggunakan Dedicated Worker, menghurai secara berketul, melaporkan kemajuan, memindahkan ArrayBuffer apabila pemilikan boleh dipindahkan, dan membatalkannya secara kooperatif atau menamatkan worker tersebut. Saya akan meletakkan satu WebSocket rentas tab asal sama dalam SharedWorker dan membiarkan setiap halaman melanggan melalui MessagePort, dengan pengesanan ciri dan sandaran kepada BroadcastChannel berserta pemilihan ketua atau, jika boleh diterima, satu sambungan bagi setiap tab. Saya akan menggunakan Service Worker untuk rangka luar talian, cache laporan, dan percubaan semula kemudian kerana ia boleh memintas permintaan berskop dan mengendalikan peristiwa latar belakang. Baris gilir diletakkan dalam IndexedDB bersama kunci keidempotanan. Tanpa Background Sync, halaman akan mengosongkannya semasa pemulaan, kembali ke latar hadapan, atau penyambungan semula. Saya akan menguji penutupan tab terakhir, pemulaan semula luar talian, penyelarasan pendua, dan kemas kini Service Worker."
Penerangan mendalam langkah demi langkah
Langkah 1: Pilih mengikut pemilikan, skop, dan jangka hayat
| Keperluan | Pilihan | Pemilik dan komunikasi | Sempadan kegagalan utama |
|---|---|---|---|
| Menghurai CSV besar untuk halaman semasa | Dedicated Worker | Halaman pencipta; postMessage | Penutupan halaman, pembatalan, puncak memori |
| Berkongsi sambungan merentasi tab asal sama | SharedWorker | Halaman asal sama; satu MessagePort bagi setiap halaman | Rujukan terakhir ditutup, pelayar lama tiada sokongan |
| Rangka luar talian, proksi rangkaian, penyelarasan kemudian | Service Worker | Skop asal dan laluan berdaftar; peristiwa dan mesej klien | Kemas kini menunggu, penamatan antara peristiwa, API pilihan tidak tersedia |
Tiada satu pun daripada ketiga-tiganya boleh memanipulasi DOM secara langsung. Dedicated Worker dan SharedWorker menjalankan kerja JavaScript yang diperlukan oleh halaman. Service Worker ialah proksi rangkaian berasaskan peristiwa yang didaftarkan terhadap asal dan laluan tertentu. Ia boleh mengendalikan fetch, caching, Push, dan penyelarasan latar belakang dalam pelayar yang menyokongnya, tetapi ia bukan tempat yang sesuai untuk penghuraian CSV yang mesti berjalan secara berterusan selama beberapa minit.
Langkah 2: Asingkan penghuraian CSV 200 MiB dalam Dedicated Worker
Cipta Dedicated Worker atas permintaan kerana tugas tersebut hanya memberi perkhidmatan kepada halaman semasa. Bebenang utama memiliki pemilihan fail, UI kemajuan, dan persembahan hasil. Worker memiliki penyahkodan, pengesahan token (tokenization), inferens jenis, dan pengagregatan. Ia tiada akses DOM, jadi ia mengembalikan hasil melalui mesej.
Lakaran antara muka ini mengetepikan jenis penghurai dan ralat. chunkBytes memberitahu worker untuk memproses secara dalaman dalam kelompok 4 MiB; ia tidak bermakna bebenang utama membuat satu salinan lain:
const parser = new Worker(
new URL("./csv-parser.worker.js", import.meta.url),
{ type: "module" },
);
const jobId = crypto.randomUUID();
const buffer = await file.arrayBuffer();
parser.postMessage(
{ type: "parse", jobId, buffer, chunkBytes: 4 * 1024 * 1024 },
[buffer],
);
parser.onmessage = ({ data }) => {
if (data.jobId !== jobId) return;
if (data.type === "progress") renderProgress(data.rows);
if (data.type === "done") renderReport(data.summary);
};
cancelButton.onclick = () => {
parser.postMessage({ type: "cancel", jobId });
};Pembatalan boleh berlaku secara kooperatif atau secara paksa. Gelung huraian menyemak bendera pembatalan pada sempadan ketulan, melepaskan objek sementara, dan melaporkan keadaan akhir. Jika worker tergantung atau penghurai tidak dapat memberi laluan (yield), terminate() akan menghentikannya, tetapi setiap tugas di dalam worker tersebut akan hilang. Oleh itu, pemproses berbilang fail jangka panjang memerlukan pengasingan tugas dan bukannya satu worker kongsi yang tidak dibezakan.
Langkah 3: Reka bentuk untuk penyalinan dan puncak memori
postMessage biasa menggunakan pengklonan berstruktur. Di bawah andaian mudah di mana ArrayBuffer 200 MiB wujud pada kedua-dua penghantar dan penerima, bait mentah sahaja menggunakan sekitar 400 MiB. Itu tidak termasuk stor sandaran File, rentetan ternyahkod, objek baris, indeks, dan ruang pembersihan memori (garbage collection headroom). Ini ialah penerbitan temu duga, bukan jaminan memori pelayar.
Meletakkan ArrayBuffer dalam senarai pemindahan (transfer list) memindahkan sumber memorinya kepada worker dan memisahkan penimbal penghantar, sekali gus mengelakkan salinan bait tersebut. Jangan pindahkannya jika halaman masih memerlukan data asal dan pemilikan belum direka bentuk. Laluan input besar yang lebih selamat membaca Blob.stream() atau hirisan (slices), menghantar ketulan kecil, dan menerima statistik secara berperingkat. Bebenang utama mengehadkan ketulan yang sedang diproses dan hanya menghantar ketulan seterusnya selepas menerima perakuan, yang mewujudkan tekanan balik.
Memori kongsi bukan jalan pintas lalai. SharedArrayBuffer memerlukan pengasingan rentas asal (cross-origin isolation) dan memperkenalkan atomik, perlumbaan data (data races), dan keselamatan pelaksanaan yang lebih ketat. Jangan tambah kerumitan itu sebelum pengukuran membuktikan bahawa mesej biasa dan objek boleh pindah menjadi punca kesesakan (bottleneck).
Langkah 4: Kekalkan sambungan berbilang tab asal sama dalam SharedWorker
SharedWorker menepati keperluan "mengekalkan satu tika kongsi selagi sekurang-kurangnya satu halaman asal sama kekal disambungkan." Setiap tab membuka worker bernama yang sama pada URL yang sama dan mendaftarkan langganan melalui MessagePort miliknya sendiri. Worker tersebut memiliki WebSocket, satu set port, dan pemetaan langganan dalam ingatan, kemudian menghalakan mesej pelayan ke port yang berkaitan.
const socketHub = new SharedWorker(
new URL("./socket-hub.shared-worker.js", import.meta.url),
{ type: "module", name: "analytics-socket-hub" },
);
socketHub.port.start();
socketHub.port.postMessage({ type: "subscribe", reportId });
socketHub.port.onmessage = ({ data }) => applyLiveUpdate(data);
window.addEventListener("pagehide", () => {
socketHub.port.postMessage({ type: "disconnect", reportId });
socketHub.port.close();
});Hanya konteks yang tepat-tepat asal sama boleh mengakses SharedWorker. Ia mungkin kekal hidup selagi halaman yang terbuka memegang rujukan; selepas rujukan terakhir ditutup, ia bukan perkhidmatan latar belakang kekal. Kehilangan sambungan, pelayar ditutup, atau kerosakan worker mungkin memadamkan peta langganan. Kekalkan kursor pelayan yang mesti bertahan, atau biarkan setiap halaman mengisytiharkan semula langganannya.
Langkah 5: Sediakan sandaran sebenar untuk SharedWorker
Kesan ciri SharedWorker. Tanpanya, tab boleh bertukar-tukar denyutan nadi (heartbeats) dan peristiwa melalui BroadcastChannel, manakala Web Locks atau pajakan storan yang mempunyai tempoh luput memilih satu ketua untuk memiliki WebSocket. Tab lain akan memilih pengganti selepas ketua ditutup. Pelayan menyahduplikasi mengikut sesi dan ID peristiwa, manakala klien menolak mesej daripada ketua lama menggunakan epok monotonik untuk mengehadkan kerosakan pemecahan otak.
Sandaran tersebut jauh lebih rumit daripada SharedWorker. Jika satu sambungan hanyalah pengoptimuman kos, sandaran betul yang paling mudah ialah satu WebSocket bagi setiap tab dengan keidempotanan bahagian pelayan dan had sambungan. Bina pemilihan, pembaharuan pajakan, pengesanan kegagalan, dan suntikan ralat (fault injection) hanya apabila kekangan pelayan yang ketat memerlukan satu sambungan tunggal.
Langkah 6: Gunakan Service Worker untuk kelakuan luar talian dan percubaan semula
Service Worker didaftarkan terhadap skop asal dan laluan serta boleh memintas permintaan daripada halaman terkawal. Rangka aplikasi sesuai untuk pra-cache berversi (versioned precaching) atau cache dahulu (cache-first). Laporan terkini lazimnya sesuai untuk rangkaian dahulu (network-first): kemas kini Cache Storage pada respons rangkaian yang berjaya dan kembalikan respons cache berjaya yang terakhir jika gagal. Letakkan baris gilir simpanan pengguna dalam IndexedDB, bukan Cache Storage atau pemboleh ubah global Service Worker.
Ini masih merupakan lakaran antara muka. Kod pengeluaran mesti membenarkan URL yang boleh dicache (allowlist), mengesahkan respons, membuat versi cache, dan menulis simpanan ke IndexedDB sebelum memaparkan "dimasukkan ke baris gilir":
navigator.serviceWorker.register("/sw.js", { scope: "/" });
// sw.js
self.addEventListener("install", (event) => {
event.waitUntil(cacheAppShell());
});
self.addEventListener("fetch", (event) => {
const url = new URL(event.request.url);
if (url.pathname.startsWith("/reports/")) {
event.respondWith(networkFirstReport(event.request));
}
});
self.addEventListener("sync", (event) => {
if (event.tag === "retry-report-saves") {
event.waitUntil(flushIndexedDbQueue());
}
});Background Sync hanya tersedia dalam sesetengah pelayar. Jika pendaftaran gagal atau API tiada, panggil pengosong baris gilir yang sama apabila halaman bermula, kembali ke latar hadapan, atau menerima peristiwa online. Peristiwa keterambungan (connectivity) ialah pencetus percubaan semula, bukan bukti kejayaan; hanya respons pelayan yang mengesahkan penyelesaian. Setiap simpanan menyimpan kunci keidempotanan, bilangan percubaan, dan masa percubaan seterusnya. Percanggahan memasuki status semakan dan bukannya menulis ganti secara berterusan.
Langkah 7: Kendalikan jangka hayat dan kemas kini Service Worker
Service Worker mengawal halaman hanya selepas muat turun, pemasangan, menunggu, dan pengaktifan. Selepas pendaftaran pertama, dokumen semasa biasanya memerlukan satu lagi navigasi sebelum ia dikawal. Versi baharu mungkin dipasang dan menunggu halaman yang menggunakan versi lama ditutup. skipWaiting() dan clients.claim() boleh mengambil kawalan dengan lebih cepat, tetapi halaman lama yang dipadankan dengan worker baharu boleh rosak apabila protokol berbeza. Buat versi skema mesej dan cache sewajarnya.
Pelayar boleh menamatkan worker antara peristiwa dan memulakannya semula untuk peristiwa seterusnya. event.waitUntil() memanjangkan jangka hayat yang dikaitkan dengan Promise peristiwa semasa; ia tidak mencipta proses mastautin (resident process). Kekalkan data baris gilir, bilangan percubaan, dan kunci keidempotanan. Pemprosesan penyelarasan mesti boleh disambung semula daripada mana-mana rekod dan menjalankan permintaan yang sama dua kali dengan selamat.
Service Worker memerlukan konteks selamat. HTTPS ialah keperluan persekitaran pengeluaran, manakala localhost ialah pengecualian pembangunan. Skop lalai dikekang oleh laluan skrip. Sahkan juga CSP worker-src, kandungan cache sensitif pengguna, pengasingan log keluar, serta tingkah laku CORS dan kelayakan untuk permintaan rentas asal.
Langkah 8: Sahkan dengan matriks kegagalan
Uji Dedicated Worker dengan fail 1 MiB dan 200 MiB, input yang rosak (malformed), dan pembatalan. Rekod tugas panjang bebenang utama, kelewatan input, daya pemprosesan huraian, puncak memori, dan masa pelepasan selepas pembatalan. Bandingkan varian klon berstruktur, boleh dipindahkan, dan berketul, kemudian pilih punca kesesakan yang diukur.
Uji SharedWorker dengan dua langganan serentak, penutupan halaman ketua, penutupan halaman terakhir, turun naik rangkaian, ralat worker, dan pelayar tanpa SharedWorker. Semakan penerimaan termasuk kiraan sambungan pelayan sebenar, tiada jurang mesej atau pendua yang tidak dijangka, kesinambungan kursor selepas sambung semula, dan sandaran yang mengekalkan ketepatan.
Uji Service Worker pada lawatan pertama, lawatan semula terkawal, muat semula luar talian, luputnya cache, kemas kini yang menunggu, penutupan paksa pelayar, pendua sync, kuota storan habis, dan ketiadaan Background Sync. Gunakan kunci keidempotanan pada titik akhir simpanan untuk membuktikan bahawa percubaan sekurang-kurangnya sekali (at-least-once) tidak mencipta penulisan pendua. Sahkan bahawa data peribadi yang dicache tidak boleh bercampur antara pengguna.
Contoh jawapan berkualiti tinggi
"Saya akan bermula dengan siapa yang memiliki tugas tersebut, tempoh hayatnya, dan sama ada ia memproksi rangkaian. CSV 200 MiB hanya memberi perkhidmatan kepada halaman semasa dan menggunakan banyak CPU, jadi saya akan menggunakan Dedicated Worker. Bebenang utama mengendalikan pemilihan fail dan UI; worker menghuraikan ketulan, melaporkan kemajuan, dan menyemak pembatalan antara ketulan. Pemesejan biasa menggunakan klon berstruktur. Jika penimbal 200 MiB lengkap wujud pada kedua-dua belah pihak, andaian temu duga meletakkan bait mentah sahaja menghampiri 400 MiB, jadi saya akan menanda aras ArrayBuffer boleh pindah yang memindahkan pemilikan atau menstrim ketulan dengan bilangan terikat yang sedang diproses.
Saya akan mengekalkan satu WebSocket rentas tab dalam SharedWorker. Setiap halaman mesti betul-betul asal sama dan mengisytiharkan semula langganan melalui MessagePort miliknya. Worker hanya menyimpan sambungan yang boleh dibina semula dan keadaan penghalaan. Ia bukan storan kekal; keadaan mungkin hilang selepas halaman terakhir ditutup, pelayar ditutup, atau worker ranap. Saya akan mengesan cirinya terlebih dahulu. Jika satu sambungan hanyalah pengoptimuman, sandarannya ialah satu sambungan bagi setiap tab. Jika ia adalah kekangan tegar, saya akan menggunakan BroadcastChannel berserta pemilihan berasaskan pajakan, dengan epok dan ID peristiwa untuk menangani pemecahan otak dan pendua.
Saya akan menggunakan Service Worker untuk rangka luar talian, laporan terkini, dan simpanan kemudian. Ia memintas permintaan dalam skop: pra-cache berversi untuk rangka aplikasi dan rangkaian dahulu dengan sandaran cache untuk laporan. Simpanan ditulis ke IndexedDB dengan kunci keidempotanan sebelum penyelarasan latar belakang didaftarkan. Tanpa Background Sync, pemulaan, kembali ke latar hadapan, atau penyambungan semula akan memanggil pengosong yang sama. Disebabkan Service Worker mungkin berhenti antara peristiwa, baris gilir tidak pernah diletakkan hanya dalam pemboleh ubah global; setiap pelaksanaan memulihkan keadaan tahan lama dan mengaitkan kerja semasa dengan waitUntil().
Akhir sekali, saya akan mengesahkan tugas panjang dan memori bebenang utama, kiraan sambungan WebSocket sebenar dan kelakuan sambung semula, pemulaan semula luar talian dan penyelarasan pendua, serta penungguan kemas kini Service Worker, sandaran pelayar lama, pengasingan cache bagi setiap pengguna, serta sempadan HTTPS dan CSP."
Kesilapan lazim
- Menggunakan Service Worker sebagai bebenang pengiraan jangka panjang → pelayar mungkin menamatkannya antara peristiwa atau semasa kerja yang panjang → gunakan Dedicated Worker untuk pengiraan halaman dan khaskan Service Worker untuk kerja rangkaian berasaskan peristiwa.
- Menghantar objek 200 MiB dengan
postMessagetanpa mengukur memori → klon berstruktur dan hasil yang dihuraikan mungkin wujud bersama pada kemuncak memori yang besar → bandingkan laluan boleh pindah, berketul, dan penstriman serta ukur puncaknya. - Menganggap sebarang worker menjamin aplikasi yang responsif → CPU, pembersihan memori (garbage collection), dan pensirilan masih memerlukan masa → ukur tugas panjang bebenang utama, daya pemprosesan, dan saiz kelompok mesej.
- Menganggap memori SharedWorker sebagai keadaan yang boleh dipercayai → ia mungkin hilang selepas rujukan terakhir ditutup atau pelayar keluar → simpan hanya keadaan masa jalan yang boleh dibina semula dan kekalkan kursor serta baris gilir penting secara tahan lama.
- Mengabaikan keperluan asal sama yang tepat → skema, hos, atau port yang berbeza tidak boleh berkongsinya → petakan sempadan asal sebelum memilih penyelarasan bahagian klien.
- Menyalin sistem pemilihan yang rumit setiap kali SharedWorker tidak tersedia → perniagaan mungkin memerlukan ketepatan logik, bukan tepat-tepat satu sambungan → tentukan sama ada kiraan sambungan ialah kekangan tegar dan jika tidak, beralihlah kepada sandaran bagi setiap tab.
- Menyimpan baris gilir luar talian dalam pemboleh ubah global Service Worker → pemulaan semula worker akan menghilangkan tugasan → tulis ke IndexedDB dahulu dan panggil pengosong yang selamat untuk dimainkan semula (replay-safe).
- Hanya bergantung pada Background Sync → ia masih bukan ciri Baseline yang disokong oleh setiap pelayar utama → cuba semula juga semasa pemulaan, kembali ke latar hadapan, dan penyambungan semula.
- Memaksa setiap kemas kini mengambil kawalan serta-merta → halaman lama dan worker baharu mungkin mempunyai protokol yang tidak serasi → buat versi mesej, cache, dan migrasi sebelum memilih untuk melangkau penungguan (skip waiting).
- Mencache setiap respons yang berjaya → data peribadi mungkin kekal merentasi akaun atau diguna semula secara salah → gunakan senarai dibenarkan (allowlist) bagi URL, pengasingan bagi setiap pengguna, pembersihan semasa log keluar, dan pengesahan respons.
Soalan susulan dan jawapan
Susulan 1: Apakah yang berubah apabila CSV membesar kepada 2 GiB dan memori mudah alih tidak mencukupi?
Berhenti memanggil file.arrayBuffer() untuk keseluruhan input. Baca ketulan Blob.stream() atau slice(), kekalkan baris separa merentasi sempadan nyahkod, dan biarkan worker mengembalikan agregat atau kelompok lajur. Hadkan ketulan yang sedang diproses dan wajibkan perakuan untuk tekanan balik. Sediakan titik pembatalan. Jika produk mesti mengekalkan setiap baris, limpahkan ke IndexedDB atau fail bersegmen dan pecahkan hasil kepada halaman (page the results) dan bukannya mengekalkan graf objek lengkap pada timbunan (heap) JavaScript. Tambah had khusus peranti dan laluan penolakan yang eksplisit.
Susulan 2: Bagaimana jika halaman pada subdomain berbeza mesti berkongsi tepat satu WebSocket?
SharedWorker tidak boleh merentasi sempadan asal yang tepat. Satu pilihan ialah asal terkawal yang memiliki sambungan langsung dan mendedahkan jambatan mesej iframe yang diaudit, dengan pengesahan targetOrigin, penghantar, dan skema yang ketat. Pilihan lain ialah memindahkan penyelarasan sambungan tunggal ke pelayan sementara setiap halaman mengekalkan sambungan klien bebas. Pilihan pertama menggabungkan keselamatan dan ketersediaan; pilihan kedua memerlukan lebih banyak sambungan pelayan. Buat pilihan berdasarkan kekangan tegar sebenar dan bukannya cuba memintas dasar asal sama (same-origin policy).
Susulan 3: SharedWorker ialah Baseline 2026, jadi mengapa perlu simpan sandaran?
Gunakan matriks pelayar produk anda. Baseline 2026 menerangkan keupayaan yang baru menjadi lazim merentasi keluaran pelayar semasa; ia tidak merangkumi setiap peranti lama, versi perusahaan yang dibekukan, mod privasi, atau persekitaran terbenam. Pengesanan ciri adalah murah. Mulakan dengan sambungan bagi setiap tab sebagai sandaran dan bina sistem pemilihan hanya jika kekangan sambungan yang ketat mewajarkannya.
Susulan 4: Bagaimanakah anda mengelakkan penulisan pendua apabila Background Sync mengulangi simpanan?
Klien mencipta satu kunci keidempotanan yang stabil untuk operasi perniagaan. Baris gilir menyimpan sekurang-kurangnya muatan, kunci, bilangan percubaan, dan masa percubaan seterusnya. Pelayan menguatkuasakan keunikan atau menyimpan hasil mengikut pengguna dan kunci, mengembalikan hasil asal untuk permintaan pendua. Klien memadamkan item baris gilir hanya selepas pengesahan. Tamat masa bermaksud hasil tidak diketahui dan percubaan semula dibuat dengan kunci yang sama, jangan gunakan kunci baharu. Percanggahan versi perniagaan beralih kepada semakan manual dan bukannya ditulis ganti secara senyap.
Susulan 5: Service Worker baharu telah dipasang, tetapi pengguna membiarkan halaman lama dibuka selama-lamanya. Apakah yang anda lakukan?
Beritahu halaman terkawal bahawa kemas kini telah sedia dan biarkan pengguna memuat semula pada waktu yang selamat. Pembaikan keselamatan boleh menggunakan skipWaiting() dan clients.claim() hanya apabila halaman lama dan baharu kekal serasi dengan protokol mesej worker serta migrasi cache dan IndexedDB adalah reentrant. Ujian keluaran mesti menguji halaman lama bersama worker baharu. Apabila keserasian tidak dapat dijamin, kekalkan fasa menunggu dan bukannya mengoptimumkan hanya untuk pengaktifan serta-merta.
Susulan 6: Mengapa tidak menggunakan Service Worker untuk berkongsi WebSocket merentasi tab juga?
Jangka hayat Service Worker adalah berasaskan peristiwa, dan pelayar boleh menghentikannya apabila ia melahu (idle). WebSocket memerlukan sambungan berterusan dan sesi dalam ingatan, yang bercanggah dengan model tersebut. SharedWorker ialah pemilik yang lebih baik selagi rujukan halaman masih wujud. Jika pelayar sasaran tiada SharedWorker dan satu sambungan adalah wajib, gunakan pemilihan rentas tab atau ubah seni bina pelayan dan bukannya mengandaikan Service Worker kekal aktif dalam ingatan.