Web Workers & SharedWorker
ทำไมต้องรัน JS นอก main thread?
หัวข้อที่มีชื่อว่า “ทำไมต้องรัน JS นอก main thread?”JavaScript ทำงานแบบ single-threaded นั่นคือ ทุกสคริปต์ การอัปเดต DOM การคำนวณ layout และ event handler ล้วนทำงานบนเธรดเดียวกัน เมื่อรัน computation ที่หนัก เช่น การ parse ไฟล์ขนาดใหญ่ การคำนวณ hash หรือการประมวลผลภาพ UI จะ “แช่แข็ง” ตลอดช่วงเวลานั้น — scroll หยุด animation กระตุก และ click ไม่ตอบสนอง
Web Workers ช่วยให้โยนงานหนักไปยัง background thread ได้ browser จะสร้าง JS environment แยกต่างหากพร้อม event loop ของตัวเอง เธรดหลักและ worker สื่อสารกันผ่าน postMessage และ onmessage โดยค่าเริ่มต้นทั้งสองเธรดจะไม่แชร์ memory ดังนั้นจึงไม่มีปัญหา race condition
flowchart LR MT["Main Thread (UI, events)"] DW["Dedicated Worker (background JS)"] MT -- "worker.postMessage(data)" --> DW DW -- "self.postMessage(result)" --> MT
Dedicated vs Shared Worker
หัวข้อที่มีชื่อว่า “Dedicated vs Shared Worker”| Dedicated Worker | SharedWorker | |
|---|---|---|
| ขอบเขต | หนึ่งแท็บ / หนึ่งสคริปต์ | ทุกแท็บของ origin เดียวกัน |
| Constructor | new Worker(url) | new SharedWorker(url) |
| การสื่อสาร | Direct: worker.postMessage(data) | ผ่าน MessagePort: port.postMessage(data) |
| ฝั่ง Worker | self.onmessage = fn | ต้องจัดการ onconnect ก่อน แล้วฟัง event.ports[0] |
| ความซับซ้อน | ง่าย | ปานกลาง — ต้องดูแล port |
| กรณีใช้งาน | งาน CPU หนักในแท็บเดียว | Shared cache, ประสานงานข้ามแท็บ |
โมดูลนี้ครอบคลุมอะไรบ้าง
หัวข้อที่มีชื่อว่า “โมดูลนี้ครอบคลุมอะไรบ้าง”| บทเรียน | สิ่งที่จะได้เรียนรู้ |
|---|---|
| index (หน้านี้) | ภาพรวม, Dedicated vs Shared, แผนผังโมดูล |
| web-workers | สร้าง ส่งข้อความ และยกเลิก Dedicated Worker |
| postmessage-and-transferables | Structured clone vs zero-copy transferables |
| sharedworker | เชื่อมต่อหลายแท็บกับ SharedWorker เดียว |
| worker-patterns | Error handling, worker pools, และ best practices |
ลองใช้งานทันที
หัวข้อที่มีชื่อว่า “ลองใช้งานทันที”snippet ด้านล่างสร้าง Dedicated Worker ผ่าน Blob URL ส่งตัวเลข 10 และ worker จะคำนวณ Fibonacci แบบ off-thread แล้วส่งผลลัพธ์กลับมา