Dedicated Web Workers
การสร้าง Worker
หัวข้อที่มีชื่อว่า “การสร้าง Worker”new Worker(url) รับ URL ที่ชี้ไปยังไฟล์ JavaScript browser จะดาวน์โหลดไฟล์นั้นและรันในเธรดพื้นหลังแยกต่างหาก ในบทเรียนเหล่านี้แทนที่จะต้อง host ไฟล์แยก เราจะสร้าง URL แบบ on-the-fly จาก Blob ซึ่งทำให้ทุกอย่างอยู่ในที่เดียวและรันได้ทันที
// worker.js (separate file)self.onmessage = function(e) { const result = heavyCompute(e.data); self.postMessage(result);};
// main.jsconst worker = new Worker('/worker.js');worker.onmessage = function(e) { console.log('result:', e.data); };worker.postMessage(inputData);API หลัก 4 ตัว
หัวข้อที่มีชื่อว่า “API หลัก 4 ตัว”worker.postMessage(data)— ส่งข้อมูลไปยัง worker จาก main threadworker.onmessage = fn— รับข้อมูลจาก worker บน main threadself.onmessage = fn— (ภายใน worker) รับข้อมูลจาก main threadself.postMessage(data)— (ภายใน worker) ส่งผลลัพธ์กลับไปยัง main threadworker.terminate()— หยุด worker ทันทีจาก main thread โดย worker จะไม่ได้รับการแจ้งเตือนใดๆ
Inline worker ผ่าน Blob URL
หัวข้อที่มีชื่อว่า “Inline worker ผ่าน Blob URL”แทนที่จะใช้ไฟล์แยก คุณสามารถกำหนด worker source เป็น string ห่อด้วย Blob แล้วแปลงเป็น object URL ด้วย URL.createObjectURL URL ที่ได้จะมีรูปแบบ blob:https://example.com/uuid และทำงานเหมือน URL ของไฟล์ที่ host ไว้จริงๆ เมื่อไม่ต้องการใช้ worker แล้ว ให้เรียก URL.revokeObjectURL(url) เพื่อคืน memory
รันได้: คำนวณแบบ off-thread
หัวข้อที่มีชื่อว่า “รันได้: คำนวณแบบ off-thread”Worker ด้านล่างจะรวมจำนวนเต็มตั้งแต่ 1 ถึง N ด้วย N = 1,000,000 ที่เป็น loop ที่ใช้เวลาพอสมควร หากรันบน main thread โดยตรงจะทำให้ UI ค้างชั่วขณะ — แต่นี่รันอยู่บน background thread แทน
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| ประมวลผลใน Web Worker | ได้ true parallelism เธรดพื้นหลังแยกจาก main thread ทำให้ UI ไม่ค้างระหว่างงานหนัก | ต้นทุนการสื่อสารผ่าน postMessage (structured clone) และ overhead ของการสร้าง/ทำลาย worker |
| ประมวลผลบน main thread โดยตรง | เรียบง่าย เข้าถึง DOM ได้ทันที ไม่มีต้นทุนการสื่อสารข้ามเธรด | งานหนักบล็อก UI thread ทำให้หน้าเว็บค้างหรือ frame drop |
| Inline worker ผ่าน Blob URL | ไม่ต้อง host ไฟล์แยก รวมโค้ดไว้ที่เดียว deploy ง่าย | Debug ยากกว่าไฟล์จริงเพราะไม่มี source map/breakpoint ที่ตรงไปตรงมา |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- คาดว่า worker เข้าถึง DOM ได้ — worker ไม่มี
window,documentหรือ DOM API ใดๆ เลย เป็นความเข้าใจผิดที่พบบ่อยที่สุดของมือใหม่ ต้อง postMessage ผลลัพธ์กลับมาให้ main thread จัดการ DOM แทน - ลืมเรียก
worker.terminate()— worker ที่ยังไม่ terminate จะค้างอยู่ใน memory และกิน CPU ต่อไปแม้งานจะเสร็จแล้ว ทำให้เกิด memory leak โดยเฉพาะถ้าสร้าง worker ใหม่ซ้ำๆ - ใช้ worker กับงานสั้นๆ ที่ใช้เวลาน้อยกว่า 2-3 ms — ต้นทุนของการสร้าง worker และ
postMessageไป-กลับสูงกว่าประโยชน์ที่ได้ ควรใช้ worker เฉพาะงานที่ใช้เวลานานพอจะคุ้มกับ overhead
💡 ตัวอย่างจากของจริง
Figma — รัน rendering และการคำนวณ geometry ที่หนักหน่วงบน Web Worker แยกจาก main thread เพื่อให้ canvas ยังคง responsive ระหว่างที่ผู้ใช้แก้ไข design
Squoosh (เครื่องมือบีบอัดภาพของ Google) — รัน codec การบีบอัดภาพ (เช่น MozJPEG, WebP) ทั้งหมดใน Web Worker เพื่อไม่ให้ UI ค้างระหว่างประมวลผลไฟล์ขนาดใหญ่