3 นาที

Web Workers กับ Service Workers: คืออะไรและทำไมจึงสำคัญ

เรียนรู้ว่า Web Workers และ Service Workers คืออะไร แตกต่างกันอย่างไร และเมื่อใดควรใช้แต่ละแบบเพื่อให้หน้าเร็วขึ้น งานเบื้องหลัง การแคช และการรองรับออฟไลน์

Web Workers กับ Service Workers: คืออะไรและทำไมจึงสำคัญ

Web Workers vs Service Workers: the quick overview

เบราว์เซอร์รัน JavaScript ส่วนใหญ่ของคุณบน เธรดหลัก (main thread)—ที่เดียวกันกับที่จัดการอินพุตผู้ใช้, แอนิเมชัน และการวาดหน้า เมื่อมีงานหนักเกิดขึ้นที่นั่น (การแยกวิเคราะห์ข้อมูลขนาดใหญ่, ประมวลผลภาพ, การคำนวณซับซ้อน) UI อาจสะดุดหรือ "ค้าง" ได้ Workers ถูกออกแบบมาเพื่อย้ายงานบางอย่าง ออกจากเธรดหลัก หรือ ออกจากการควบคุมโดยตรงของหน้า เพื่อให้แอปของคุณยังตอบสนองได้

The problem workers solve

ถ้าหน้าของคุณกำลังยุ่งกับการคำนวณ 200ms เบราว์เซอร์จะไม่สามารถเลื่อนหน้าได้อย่างราบรื่น ตอบสนองการคลิก หรือรักษาแอนิเมชันที่ 60fps ได้ Workers ช่วยโดยการให้คุณทำงานเบื้องหลัง ขณะที่เธรดหลักยังมุ่งไปที่อินเทอร์เฟซ

Quick definitions

A Web Worker คือเธรด JavaScript เบื้องหลังที่คุณสร้างจากหน้า เหมาะกับงานที่หนักด้าน CPU ที่ถ้าไปรันบนเธรดหลักจะบล็อก UI

A Service Worker เป็น worker พิเศษที่อยู่ระหว่างเว็บแอปของคุณกับเครือข่าย มันสามารถดักคำขอ แคชการตอบกลับ และเปิดใช้งานฟีเจอร์เช่นการรองรับออฟไลน์และการแจ้งเตือนแบบ push

A simple mental model: “threads” vs “network proxy”

คิดว่า Web Worker เป็นผู้ช่วยที่ทำงานคำนวณในห้องอื่น คุณส่งข้อความไปให้ มันทำงาน แล้วส่งกลับมา

คิดว่า Service Worker เป็นผู้คัดกรองหน้าประตูด้านหน้า คำขอสำหรับหน้า สคริปต์ และ API จะผ่านมัน และมันสามารถตัดสินใจว่าจะดึงจากเครือข่าย เสิร์ฟจากแคช หรือตอบในแบบกำหนดเอง

What you’ll learn in this article

By the end, you’ll know:

  • เมื่อ web worker คือเครื่องมือที่เหมาะสมสำหรับประสิทธิภาพ (และสิ่งที่มันเข้าถึงไม่ได้)
  • สิ่งที่ service worker ทำได้สำหรับการแคชแบบออฟไลน์ การอัปเดต และพฤติกรรมของ PWA
  • วิธีที่การสื่อสาร (เช่น postMessage) เข้ากับโมเดล worker และทำไม Cache Storage API ถึงสำคัญสำหรับออฟไลน์

บทนำนี้อธิบาย "ทำไม" และโมเดลความคิด—ต่อไปเราจะลงรายละเอียดว่าทำงานแต่ละประเภทเป็นอย่างไรและเหมาะกับโปรเจกต์จริงอย่างไร

Why browsers have workers in the first place

เมื่อคุณเปิดเว็บเพจ ส่วนใหญ่ที่คุณ "รู้สึก" ว่าเกิดขึ้นจะอยู่บน เธรดหลัก มันรับผิดชอบการวาดพิกเซล (rendering), ตอบสนองการแตะและคลิก (input) และรัน JavaScript จำนวนมาก

The main thread is a shared checkout line

เพราะการเรนเดอร์ การจัดการอินพุต และ JavaScript มักสลับกันใช้เธรดเดียวกัน งานหนึ่งงานช้าอาจทำให้ทุกอย่างอื่นต้องรอ นั่นคือสาเหตุที่ปัญหาประสิทธิภาพมักแสดงออกมาในรูปแบบของปัญหาการตอบสนอง ไม่ใช่แค่ "โค้ดช้า"

ความรู้สึกเมื่อมีการบล็อกสำหรับผู้ใช้:

  • การเลื่อนกระตุก (jank)
  • ปุ่มไม่ตอบสนองทันที
  • การพิมพ์หน่วงตามแป้นพิมพ์
  • แอนิเมชันหยุดชั่วขณะ

Async isn’t the same as parallel

JavaScript มี API แบบอะซิงโครนัสมากมาย—เช่น fetch(), timers, events—ซึ่งช่วยให้คุณหลีกเลี่ยงการรออย่างเฉยๆ แต่ async ไม่ได้ทำให้งานหนักรันพร้อมกับการเรนเดอร์โดยอัตโนมัติ

หากคุณทำการคำนวณหนัก (การประมวลผลภาพ, การ crunch JSON ขนาดใหญ่, crypto, การกรองซับซ้อน) บนเธรดหลัก มันยังแข่งกับการอัปเดต UI อยู่ "Async" อาจเลื่อน เวลา ที่มันรัน แต่ยังอาจรันบนเธรดหลักและทำให้เกิด jank เมื่อมันประมวลผล

Where workers fit in the browser architecture

Workers มีเพื่อให้เบราว์เซอร์สามารถรักษาการตอบสนองของหน้าได้ ในขณะที่ยังทำงานสำคัญในเบื้องหลัง

  • Web Workers ให้คุณรัน JavaScript บนเธรดพื้นหลังสำหรับงานหนักด้าน CPU
  • Service Workers รันแยกจากหน้าใดหน้าหนึ่ง ทำงานเหมือนเลเยอร์เครือข่าย/แคชที่สามารถทำงานแม้หน้าไม่ได้เปิดอยู่

สรุป: workers คือวิธีปกป้องเธรดหลัก เพื่อให้แอปของคุณยังโต้ตอบได้ขณะมีการทำงานในเบื้องหลังจริง

What is a Web Worker?

A Web Worker คือวิธีรัน JavaScript นอกเธรดหลัก แทนที่จะไปแข่งกับงาน UI (การเรนเดอร์ การเลื่อน ตอบคลิก) worker จะรันบนเธรดพื้นหลังของตัวเอง งานหนักจึงเสร็จโดยไม่ทำให้หน้ารู้สึก "ติด"

คิดว่าเป็น: หน้าโฟกัสกับการโต้ตอบผู้ใช้ ขณะที่ worker จัดการงานหนักด้าน CPU อย่างการแยกวิเคราะห์ไฟล์ขนาดใหญ่ การคำนวณตัวเลข หรือเตรียมข้อมูลสำหรับกราฟ

Where it runs

Web Worker รันใน เธรดแยกพร้อม global scope ของตัวเอง มันยังเข้าถึง API เว็บบางอย่างได้ (timers, fetch ในเบราว์เซอร์หลายตัว, crypto เป็นต้น) แต่ถูกแยกจากหน้าจงใจ

Dedicated Worker vs Shared Worker

มีรูปแบบที่พบบ่อย:

  • Dedicated Worker: เชื่อมต่อกับหน้า/แท็บเดียว เมื่อหน้านั้นปิด worker มักจะถูกยุติ
  • Shared Worker: แชร์กันระหว่างหลายหน้า/แท็บจาก origin เดียวกัน เหมาะสำหรับประสานงานข้ามแท็บ (เช่น แชร์การเชื่อมต่อเดียวหรือซิงก์สถานะ)

ถ้าคุณไม่เคยใช้ workers มาก่อน ตัวอย่างส่วนใหญ่ที่เห็นเป็น dedicated workers

How Web Workers communicate

Workers ไม่สามารถเรียกฟังก์ชันในหน้าโดยตรง การสื่อสารทำโดยส่งข้อความ:

  • หน้าส่งข้อมูลไปยัง worker ด้วย postMessage()
  • worker ตอบกลับด้วย postMessage() เช่นกัน
  • ข้อมูลถูกโอนด้วย structured clone ซึ่งรองรับชนิดข้อมูลมากมาย (วัตถุ, อาเรย์, สตริง, ตัวเลข, Maps/Sets, ArrayBuffers และอื่นๆ)

สำหรับข้อมูลไบนารีขนาดใหญ่ คุณมักปรับปรุงประสิทธิภาพด้วยการโอนกรรมสิทธิ์ของ ArrayBuffer (เพื่อไม่ให้คัดลอก) ซึ่งช่วยให้การส่งข้อความเร็ว

Common limits (by design)

เพราะ worker ถูกแยก มีข้อจำกัดสำคัญบางอย่าง:

  • ไม่สามารถเข้าถึง DOM โดยตรง: worker อ่านหรือแก้ไข HTML, CSS หรือเลย์เอาต์ของหน้าไม่ได้
  • globals ต่างกัน: คุณจะไม่มี window หรือ document worker รันภายใต้ self (global scope ของ worker) และ API ที่มีให้จะแตกต่างจากหน้าหลัก
  • แนวคิดแบบอะซิงโครนัส: ทุกอย่างเป็นแบบส่งข้อความ จึงต้องออกแบบโค้ดให้ส่งงานเข้าไปแล้วรอผลกลับ

เมื่อใช้อย่างถูกต้อง Web Worker เป็นวิธีง่ายๆ ในการปรับปรุง ประสิทธิภาพเธรดหลัก โดยไม่ต้องเปลี่ยนพฤติกรรมของแอป—แค่ย้ายที่ให้การทำงานหนักเกิดขึ้น

When to use Web Workers (and when not to)

Web Workers เหมาะเมื่อหน้าของคุณรู้สึก "ติด" เพราะ JavaScript รันงานหนักบนเธรดหลัก เธรดหลักยังรับผิดชอบอินเทอร์แอ็คชันผู้ใช้และการเรนเดอร์ ดังนั้นงานหนักตรงนั้นสามารถทำให้เกิด jank, คลิกหน่วง และการเลื่อนค้างได้

Best fits for Web Workers

ใช้ Web Worker เมื่อคุณมีงานหนักด้าน CPU ที่ไม่จำเป็นต้องเข้าถึง DOM โดยตรง:

  • การคำนวณหนัก: การคำนวณ, การจำลอง, การ crunch ข้อมูล
  • การแยกวิเคราะห์และแปลง: การแยกวิเคราะห์ JSON ขนาดใหญ่, แยก CSV, ตรวจสอบสคีมา
  • การบีบอัด/ถอดรหัส: งานแบบ zip/gzip, การเข้ารหัส/ถอดรหัส
  • การประมวลผลภาพ: ย่อ ขยาย ฟิลเตอร์ สร้าง thumbnails (มักจับคู่กับ OffscreenCanvas ในเบราว์เซอร์ที่รองรับ)

ตัวอย่างปฏิบัติ: หากคุณได้รับ payload JSON ขนาดใหญ่และการแยกวิเคราะห์ทำให้ UI กระตุก ให้ย้ายการแยกวิเคราะห์ไปยัง worker แล้วส่งผลกลับ

Data handling tips (for speed)

การสื่อสารกับ worker เกิดผ่าน postMessage สำหรับข้อมูลไบนารีขนาดใหญ่ ให้ใช้ transferable objects (เช่น ArrayBuffer) เพื่อให้เบราว์เซอร์โอนกรรมสิทธิ์หน่วยความจำแทนการคัดลอก:

// main thread
worker.postMessage(buffer, [buffer]); // transfers the ArrayBuffer

สิ่งนี้มีประโยชน์สำหรับบัฟเฟอร์เสียง ไบต์ภาพ หรือข้อมูลชิ้นใหญ่ๆ

When not to use Web Workers

Workers มีค่าใช้จ่าย: ไฟล์เพิ่มเติม การส่งข้อความ และการดีบักที่ต่างออกไป หลีกเลี่ยงเมื่อ:

  • งาน เล็กน้อย (มิลลิวินาที) และเกิดไม่บ่อย
  • งานต้องการ อ่าน/เขียน DOM บ่อย (workers ทำไม่ได้)
  • ต้องการการส่งข้อความเร็วสุดขีดแบบรอบต่อรอบ; การ ping-pong บ่อยๆ อาจลบประโยชน์

A simple rule of thumb

ถ้างานสามารถทำให้เกิดการหยุดสังเกตได้ (มัก ~50ms+) และสามารถระบุเป็น "input → compute → output" โดยไม่ต้องเข้าถึง DOM มักคุ้มค่าที่จะใช้ Web Worker หากงานส่วนใหญ่เป็นการอัปเดต UI ให้อยู่บนเธรดหลักและปรับแต่งตรงนั้นแทน

What is a Service Worker?

Add offline support fast
สร้างการตั้งค่า Service Worker ง่ายๆ สำหรับการแคชแบบออฟไลน์และการเข้าเยี่ยมชมที่เร็วขึ้น

A Service Worker คือไฟล์ JavaScript พิเศษที่รันในพื้นหลังของเบราว์เซอร์และทำงานเหมือน เลเยอร์เครือข่ายที่โปรแกรมได้ สำหรับไซต์ของคุณ แทนที่จะรันบนหน้า มันอยู่ระหว่างเว็บแอปของคุณกับเครือข่าย ให้คุณตัดสินใจว่าเมื่อแอปร้องขอทรัพยากร (HTML, CSS, API, รูปภาพ) จะทำอย่างไร

Lifecycle basics (register → install → activate → control)

Service Worker มีวงจรชีวิตแยกจากแท็บใดแท็บหนึ่ง:

  • Register: หน้าบอกเบราว์เซอร์ว่า "ไซต์นี้มี service worker" (มักจาก JS หลัก)
  • Install: เบราว์เซอร์ดาวน์โหลดและรันขั้นตอนติดตั้ง มักใช้เพื่อ precache ไฟล์สำคัญ
  • Activate: worker ใหม่เข้าควบคุม โดยปกติหลังจากปิดแท็บเก่าหรือเมื่อปลอดภัยที่จะทดแทนเวอร์ชันเดิม
  • Control: เมื่อตัวใหม่ active แล้ว มันสามารถ "ควบคุม" หน้าภายในสโคปของมันและเริ่มดักคำขอ

เพราะมันอาจถูกหยุดและเริ่มใหม่ได้ตลอดเวลา ให้มองมันเป็นสคริปต์ขับเคลื่อนด้วยเหตุการณ์: ทำงานให้เร็ว เก็บสถานะใน storage ที่ถาวร และอย่าสมมติว่ามันจะทำงานตลอดเวลา

Scope and origin rules (high level)

Service Workers ถูกจำกัดให้อยู่ ภายใน origin เดียวกัน (domain/protocol/port เดียวกัน) และควบคุมหน้าภายใต้ scope ของมัน—โดยปกติตำแหน่งโฟลเดอร์ที่ไฟล์ worker ถูกเสิร์ฟ (และด้านล่าง) นอกจากนี้ต้องใช้ HTTPS (ยกเว้น localhost) เพราะมันสามารถกระทบคำขอเครือข่ายได้

Key APIs you’ll see often

  • Fetch event: ดักคำขอและตัดสินใจว่าจะไปเครือข่าย ดึงจากแคช หรือคืน response แบบกำหนดเอง
  • Cache Storage API: เก็บและดึงการตอบกลับที่แคชไว้สำหรับออฟไลน์และความเร็ว
  • Clients API: สื่อสารกับและจัดการแท็บ/หน้าต่างที่ worker ควบคุม

What Service Workers are used for

Service Worker ถูกใช้เป็นหลักเพื่อยืนอยู่ระหว่างเว็บแอปของคุณกับเครือข่าย มันสามารถตัดสินใจว่าเมื่อใดจะใช้เครือข่าย ใช้ข้อมูลจากแคช และเมื่อใดจะทำงานเบื้องหลัง—โดยไม่บล็อกหน้า

Offline support (smart caching)

งานที่พบบ่อยที่สุดคือเปิดใช้งานประสบการณ์ออฟไลน์หรือการใช้งานเมื่อการเชื่อมต่อไม่ดีโดยการแคชแอสเซ็ตและการตอบกลับ

กลยุทธ์แคชที่ใช้กันบ่อย:

  • Cache-first: เหมาะกับไฟล์คงที่ (CSS, JS, โลโก้). เร็ว ทำงานออฟไลน์
  • Network-first: เหมาะกับเนื้อหาที่เปลี่ยนบ่อย (ข่าว, ฟีด). สำรองเป็นแคชเมื่อออฟไลน์
  • Stale-while-revalidate: แสดงเนื้อหาจากแคชทันที จากนั้นรีเฟรชในเบื้องหลังสำหรับครั้งถัดไป

นี่มักทำโดยใช้ Cache Storage API และการจัดการเหตุการณ์ fetch

Faster repeat visits

Service Workers ช่วยให้ความรู้สึกเร็วขึ้นเมื่อกลับมาเยือนโดย:

  • Precaching: บันทึกไฟล์สำคัญในขั้นตอนติดตั้ง (มักเรียกว่า app shell)
  • Runtime caching: แคชหน้า หรือการตอบ API ขณะที่ผู้ใช้นำทาง

ผลคือคำขอเครือข่ายลดลง การเริ่มต้นเร็วขึ้น และประสิทธิภาพสม่ำเสมอบนการเชื่อมต่อที่ไม่เสถียร

Background features (when supported)

Service Workers สามารถขับเคลื่อนฟีเจอร์เบื้องหลังเช่น push notifications และ background sync (การรองรับแตกต่างกันไปตามเบราว์เซอร์และแพลตฟอร์ม) นั่นหมายความว่าคุณสามารถแจ้งผู้ใช้หรือพยายามส่งคำขอที่ล้มเหลวอีกครั้งในภายหลัง แม้หน้าไม่ได้เปิดอยู่

PWA building blocks

ถ้าคุณกำลังสร้าง progressive web app Service Workers เป็นส่วนสำคัญเบื้องหลัง:

  • Installability (ทำงานร่วมกับ web app manifest)
  • เพจออฟไลน์ที่เชื่อถือได้ (เช่น fallback ที่เป็นมิตร)
  • โมเดล app shell สำหรับการนำทางที่รวดเร็ว

Key differences: Web Worker vs Service Worker

Test in production conditions
ปรับใช้แอปของคุณและทดสอบการแคช การอัปเดต และพฤติกรรมของ worker ในสภาพแวดล้อมจริง

ถ้าจำได้เพียงอย่างเดียว: Web Workers ช่วยให้หน้าทำงานหนักได้โดยไม่ทำให้ UI ค้าง ในขณะที่ Service Workers ช่วยให้แอปควบคุมคำขอเครือข่ายและทำงานเหมือนแอปที่ติดตั้งได้ (PWA)

Where they run (what job they’re for)

A Web Worker เหมาะกับ งานหนักด้าน CPU—การแยกวิเคราะห์ข้อมูลขนาดใหญ่ สร้าง thumbnails คำนวณ—เพื่อให้เธรดหลักยังตอบสนอง

A Service Worker เหมาะกับ การจัดการคำขอและงานวงจรชีวิตของแอป—การแคชแบบออฟไลน์ การซิงค์เบื้องหลัง การแจ้งเตือน push มันสามารถยืนอยู่ระหว่างแอปกับเครือข่าย

Lifetime and “who owns it”

A Web Worker มัก ผูกกับหน้า/แท็บ เมื่อหน้าปิด worker มักจะถูกยุติ (ยกเว้นกรณีพิเศษเช่น SharedWorker)

A Service Worker เป็น event-driven เบราว์เซอร์สามารถเริ่มมันเพื่อจัดการเหตุการณ์ (เช่น fetch หรือ push) แล้วหยุดเมื่อว่าง นั่นหมายความว่ามันสามารถทำงานแม้จะไม่มีแท็บเปิด

Network access and control

A Web Worker ไม่สามารถดักคำขอเครือข่ายของหน้าได้ มันสามารถ fetch() ข้อมูลด้วยตัวเอง แต่ไม่สามารถเขียนทับ แคช หรือเสิร์ฟการตอบสำหรับส่วนอื่นของไซต์ได้

A Service Worker สามารถดักคำขอเครือข่าย (ผ่านเหตุการณ์ fetch) ตัดสินใจว่าจะไปเครือข่าย ดึงจากแคช หรือคืน fallback

Storage and caching

A Web Worker ไม่จัดการ HTTP caching ให้กับแอปของคุณ

A Service Worker มักใช้ Cache Storage API เพื่อเก็บและเสิร์ฟคู่ request/response—ซึ่งเป็นพื้นฐานสำหรับการแคชแบบออฟไลน์และการโหลดซ้ำที่ "ทันที"

How to set them up (high-level steps)

Practice PWA patterns
สร้างโปรโตไทป์ขนาดเล็กแบบ PWA เพื่อฝึกการติดตั้ง นโยบายแคช และการอัปเดต

การรัน worker ส่วนใหญ่เกี่ยวกับ ตำแหน่งที่มันรัน และ วิธีโหลด Web Workers ถูกสร้างโดยสคริปต์หน้าโดยตรง Service Workers ถูกติดตั้งโดยเบราว์เซอร์และยืนอยู่ "หน้าประตู" ของคำขอเครือข่ายสำหรับไซต์ของคุณ

Web Worker: create it from your page

Web Worker เริ่มเมื่อหน้าของคุณสร้างมัน คุณชี้ไปที่ไฟล์ JavaScript แยกต่างหาก แล้วสื่อสารผ่าน postMessage:

// main.js (running on the page)
const worker = new Worker('/workers/resize-worker.js', { type: 'module' });

worker.postMessage({ action: 'start', payload: { /* ... */ } });

worker.onmessage = (event) => {
  console.log('From worker:', event.data);
};

โมเดลความคิดที่ดี: ไฟล์ worker เป็นสคริปต์อีกตัวที่เพจของคุณสามารถดึงมาได้ แต่จะรันนอกเธรดหลัก

Service Worker: register it (once) and let the browser install it

Service Workers ต้องถูกลงทะเบียนจากหน้าที่ผู้ใช้เยี่ยมชม:

// main.js
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js');
}

หลังการลงทะเบียน เบราว์เซอร์จะจัดการวงจร install/activate ให้ ไฟล์ sw.js ของคุณสามารถฟังเหตุการณ์เช่น install, activate, และ fetch

Why Service Workers require HTTPS

Service Workers สามารถดักคำขอเครือข่ายและแคชการตอบกลับได้ หากการลงทะเบียนอนุญาตผ่าน HTTP ผู้โจมตีบนเครือข่ายอาจแทนที่ sw.js ด้วยโค้ดที่เป็นอันตรายและควบคุมการเข้าชมในอนาคตได้ HTTPS (หรือ http://localhost สำหรับการพัฒนา) ปกป้องสคริปต์และทราฟฟิกที่มันส่งผลต่อ

Versioning mindset: treat worker files like deployable “releases”

เบราว์เซอร์แคชและอัปเดต worker ต่างจากสคริปต์หน้าโดยปกติ วางแผนการอัปเดต:

  • เปลี่ยนไฟล์เมื่อพฤติกรรมเปลี่ยน (มักโดยปล่อย sw.js/บันเดิล worker ใหม่)
  • ใน Service Workers คาดว่าจะมี flow การอัปเดต: worker ใหม่ติดตั้ง แล้ว activate เมื่อปลอดภัย
  • เมื่อคุณเปลี่ยนนโยบายการแคช ให้รวมตรรกะล้างข้อมูลในขั้นตอน activation เพื่อไม่ให้แคชเก่าเหลืออยู่

ถ้าต้องการกลยุทธ์การเปิดตัวที่ราบรื่นขึ้น ดู /blog/debugging-workers สำหรับแนวทางการทดสอบที่จับ edge cases ของการอัปเดตได้เร็ว

Debugging and testing workers in the browser

Workers ล้มเหลวต่างจาก JavaScript ปกติ: พวกมันรันในคอนเท็กซ์แยก มีคอนโซลของตัวเอง และอาจถูกรีสตาร์ทโดยเบราว์เซอร์ วิธีการดีบักที่ดีจะช่วยประหยัดเวลาได้มาก

Web Worker debugging (DevTools)

เปิด DevTools และหา targets ของ worker ใน Chrome/Edge มักจะเห็น worker ใน Sources (หรือผ่านรายการ "Dedicated worker") และในตัวเลือก context ของ Console

ใช้เครื่องมือเดียวกับที่ใช้บนเธรดหลัก:

  • Console logging: โลกร้านจาก Web Worker จะปรากฏใน DevTools แต่ต้องมั่นใจว่ากำลังดูคอนเท็กซ์ที่ถูกต้อง
  • Breakpoints: ตั้งเบรกพอยต์ในสคริปต์ worker; ก้าวผ่าน onmessage handlers และฟังก์ชันที่รันนาน
  • Performance profiling: บันทึก trace ประสิทธิภาพและยืนยันว่าเธรดหลักยังตอบสนองขณะที่ worker ทำงานหนัก

ถ้าข้อความดูเหมือน "หาย" ให้ตรวจทั้งสองฝั่ง: ยืนยันว่าคุณเรียก worker.postMessage(...), worker มี self.onmessage = ..., และรูปแบบข้อความตรงกัน

Service Worker debugging (Application panel)

Service Workers ดีบักได้ดีที่สุดในแผง Application:

  • ตรวจสอบ registration status, scope, และเวอร์ชัน active/waiting/installed
  • ใช้การควบคุมวงจรชีวิตเช่น Skip waiting และ Unregister เพื่อล้างสถานะที่ผิด
  • เปิด Update on reload เพื่อหลีกเลี่ยงการตามหาโค้ดเก่าในขณะพัฒนา

นอกจากนี้ให้ดู Console สำหรับข้อผิดพลาด install/activate/fetch—มักอธิบายได้ว่าทำไมการแคชหรือการทำงานออฟไลน์ไม่ทำงาน

Common pitfalls and testing tips

ปัญหาการแคชเป็นตัวดูดเวลาที่ใหญ่ที่สุด: แคชไฟล์ผิดหรือแคชแน่นเกินไปอาจเก็บ HTML/JS เก่าไว้ ในการทดสอบลองทำ hard reload และยืนยันว่าอะไรถูกเสิร์ฟจริง

สำหรับการทดสอบที่สมจริง ใช้ DevTools เพื่อ:

  • จำลอง โหมดออฟไลน์ และยืนยันเพจ fallback
  • ใช้ network throttling
  • โหลดซ้ำหลายครั้งเพื่อยืนยันการอัปเดตของ Service Worker และการจัดการข้อความ

ถ้าคุณวนเวียนพัฒนา PWA การสร้างแอปฐานที่สะอาด (มี Service Worker และเอาต์พุตที่คาดเดาได้) แล้วค่อยปรับกลยุทธ์แคช จะช่วยได้ แพลตฟอร์มอย่าง Koder.ai อาจเป็นประโยชน์สำหรับการทดลอง: คุณสามารถโปรโตไทป์แอป React จาก prompt ในแชท ส่งออกซอร์ส แล้วปรับการตั้งค่า worker และนโยบายแคชด้วยวง Feedback ที่กระชับขึ้น

คำถามที่พบบ่อย

How do I decide whether I need a Web Worker?

ใช้ Web Worker เมื่อคุณมีงานหนักด้าน CPU ที่สามารถอธิบายเป็น input → compute → output และไม่ต้องการเข้าถึง DOM โดยตรง。

งานที่เหมาะได้แก่ การแยกวิเคราะห์/แปลง payload ขนาดใหญ่ การบีบอัด/ถอดรหัส การเข้ารหัสลับ การประมวลผลภาพ/เสียง และการกรองข้อมูลที่ซับซ้อน หากงานส่วนใหญ่เป็นการอัปเดต UI หรืออ่าน/เขียน DOM บ่อยๆ worker จะช่วยไม่ได้ (และก็ไม่สามารถเข้าถึง DOM ได้อยู่แล้ว)

How do I decide whether I need a Service Worker?

ใช้ Service Worker เมื่อคุณต้องการ ควบคุมเครือข่าย: การรองรับแบบออฟไลน์ นโยบายการแคช การโหลดที่เร็วขึ้นในการกลับมา เยื้องคำขอ (request routing) และ (เมื่อรองรับ) push หรือ background sync。

ถ้าปัญหาของคุณคือ “UI ค้างเพราะต้องคำนวณ” นั่นคือกรณีของ Web Worker ถ้าปัญหาคือ “การโหลดช้าหรือออฟไลน์ใช้งานไม่ได้” นั่นคือกรณีของ Service Worker

Do Web Workers require a Service Worker (or vice versa)?

ไม่จำเป็นทั้งคู่ Web Workers และ Service Workers เป็นฟีเจอร์ที่แยกจากกัน。

  • Web Worker: ถูกสร้างโดยหน้าเพจเพื่อการประมวลผลเบื้องหลัง。
  • Service Worker: ถูกติดตั้ง/เปิดใช้โดยเบราว์เซอร์เพื่อดักจับคำขอและจัดการการแคช。

คุณสามารถใช้แค่ตัวใดตัวหนึ่งหรือใช้ทั้งสองร่วมกันเมื่อแอปต้องการทั้งการคำนวณและคุณสมบัติด้านเครือข่าย/ออฟไลน์

What’s the biggest difference in lifetime between Web Workers and Service Workers?

ส่วนใหญ่เป็นเรื่องของ ขอบเขตและอายุการทำงาน

  • Web Worker มักผูกกับหน้า/แท็บ (โดยเฉพาะ Dedicated Worker) และมักจะยุติเมื่อหน้าปิดลง。
  • Service Worker เป็นแบบ event-driven และสามารถตื่นขึ้นมาจัดการเหตุการณ์ (เช่น fetch) แม้ไม่มีแท็บเปิดอยู่ แล้วปิดตัวเมื่อว่าง
Can a Web Worker access or modify the DOM?

ไม่สามารถ Web Workers ไม่มี window/document และจึงไม่สามารถอ่านหรือแก้ไข DOM ได้。

ถ้าต้องการอัปเดต UI ส่งข้อมูลกลับมาที่เธรดหลักผ่าน postMessage() แล้วให้โค้ดในเพจอัปเดต DOM ต่อ

Can a Service Worker access the DOM?

ไม่สามารถ Service Workers ไม่มีสิทธิ์เข้าถึง DOM ด้วยเหตุผลเดียวกันกับ Web Worker: มันทำงานแยกจากเพจและอาจจะทำงานเมื่อไม่มีเอกสารใดๆ เปิดอยู่。

หากต้องการมีผลต่อสิ่งที่ผู้ใช้เห็น ให้สื่อสารกับเพจที่ถูกควบคุมผ่าน messaging (เช่น Clients API + postMessage()), แล้วให้เพจอัปเดต UI

What’s the best way to send data to a Web Worker efficiently?

ใช้ postMessage() ทั้งสองฝั่ง。

  • เธรดหลัก → worker: worker.postMessage(data)
  • worker → เธรดหลัก: self.postMessage(result)

สำหรับข้อมูลไบนารีขนาดใหญ่ ให้ใช้ transferables เช่น ArrayBuffer เพื่อลดการคัดลอก:

worker.postMessage(buffer, [buffer]);
How does offline caching work with a Service Worker?

Service Worker ยืนอยู่ระหว่างแอปของคุณกับเครือข่ายและตอบคำขอได้โดยใช้ Cache Storage API

กลยุทธ์ทั่วไป:

  • Cache-first: เหมาะกับไฟล์คงที่
  • Network-first: เหมาะกับข้อมูลที่เปลี่ยนบ่อย
  • Stale-while-revalidate: ส่งข้อมูลแคชทันที แล้วรีเฟรชในเบื้องหลัง

ควรเลือกกลยุทธ์ตามชนิดของทรัพยากร (app shell vs API data) แทนการใช้กฎเดียวทั้งหมด

Can I use a Web Worker and Service Worker together in the same app?

ได้—แต่แยกความรับผิดชอบให้ชัดเจน。

แบบแผนที่พบบ่อย:

  • Web Worker: ประมวลผล (เช่น สร้าง thumbnails, ปรับโครงสร้าง JSON ขนาดใหญ่)
  • Service Worker: แคช/เสิร์ฟ (เก็บผลลัพธ์เพื่อใช้งานออฟไลน์และการโหลดซ้ำที่เร็วขึ้น)
  • เธรดหลัก: UI

การแยกหน้าที่จะช่วยหลีกเลี่ยงการรวมตรรกะ UI เข้าไปในบริบทเบื้องหลังและทำให้ประสิทธิภาพคาดเดาได้

What are the quickest debugging steps when workers don’t behave as expected?

ใช้ DevTools ที่เหมาะสมสำหรับแต่ละชนิด:

  • Web Worker: ตรวจสอบ target ของ worker ใน DevTools (Sources/Console context), ตั้งเบรกพอยต์ใน onmessage, และโปรไฟล์เพื่อตรวจว่าเธรดหลักยังตอบสนองขณะที่ worker ทำงาน
  • Service Worker: ใช้แผง Application เพื่อตรวจสถานะการลงทะเบียน/สโคป/เวอร์ชันที่ active/waiting, ใช้ “Update on reload” และรีเซ็ตด้วย “Unregister” หรือ “Skip waiting.”

เมื่อแก้บั๊กการแคช ให้ยืนยันเสมอว่าอะไรถูกเสิร์ฟจริง (จากเน็ตเวิร์กหรือจากแคช) และทดสอบในโหมดออฟไลน์/การจำลองเครือข่าย

Related posts