ทำไมต้องใช้ Wasm? และรันที่ไหนได้บ้าง?
WebAssembly ไม่ได้เกิดขึ้นโดยบังเอิญ แต่ถูกออกแบบมาเพื่อแก้ปัญหาเฉพาะกลุ่มที่ JavaScript เพียงอย่างเดียวแก้ไม่ได้ การเข้าใจ ว่าทำไม Wasm ถึงมีอยู่ และ ที่ไหน ที่ Wasm รันได้ จะให้ mental model ที่คุณต้องใช้ตัดสินใจว่าเมื่อไหร่ควรหยิบ Wasm มาใช้
4 เหตุผลในการใช้ Wasm
หัวข้อที่มีชื่อว่า “4 เหตุผลในการใช้ Wasm”1. ความเร็ว
หัวข้อที่มีชื่อว่า “1. ความเร็ว”Wasm ถูกคอมไพล์เป็น binary กะทัดรัดก่อนที่จะถึง runtime engine ไม่ต้อง parse source text, tokenize หรือสร้าง AST เมื่อโหลด การคอมไพล์แบบ AOT หรือ JIT จาก binary format นั้นรวดเร็วและสร้าง machine code ใกล้เคียง native สำหรับงาน compute-intensive เช่น image processing, audio codec, cryptography, physics simulation ช่องว่างนี้วัดได้และมีนัยสำคัญ
2. Portability
หัวข้อที่มีชื่อว่า “2. Portability”ไฟล์ .wasm เพียงไฟล์เดียวรันเหมือนกันทุกที่: laptop x86-64, โทรศัพท์ ARM, embedded board RISC-V, browser, edge node ไม่มีขั้นตอน recompile สำหรับแต่ละ target architecture runtime ตรวจสอบและรัน binary ตาม instruction set ที่ระบุไว้อย่างดี
3. การเลือกภาษา
หัวข้อที่มีชื่อว่า “3. การเลือกภาษา”Wasm คือ target สำหรับการคอมไพล์ ไม่ใช่ภาษาที่คุณเขียนด้วยมือในการใช้งานจริง ซึ่งหมายความว่าคุณเลือกเครื่องมือที่เหมาะสมสำหรับงาน:
- Rust — zero-cost abstraction, ไม่มี garbage collector, toolchain
wasm-packที่ยอดเยี่ยม - C / C++ — native library ที่มีอยู่มานานหลายทศวรรษ, คอมไพล์ด้วย Emscripten
- Go — รองรับ standard library ดี, ecosystem กำลังเติบโต
- AssemblyScript — syntax คล้าย TypeScript ที่คอมไพล์ตรงไปยัง Wasm
- Python — ผ่าน Pyodide ที่เป็น CPython เต็มรูปแบบที่คอมไพล์เป็น Wasm รันใน browser
4. ความปลอดภัย
หัวข้อที่มีชื่อว่า “4. ความปลอดภัย”Wasm รันใน sandbox ที่เข้มงวด module ไม่สามารถเข้าถึง memory, file system หรือ network ของ host ได้ เว้นแต่ host จะ provide ความสามารถเหล่านั้นอย่างชัดเจนในรูปแบบ import linear memory ถูกตรวจสอบขอบเขตทุกครั้งที่เข้าถึง ไม่มี ambient permission Wasm module เริ่มต้นโดยไม่มีอะไรและได้รับเฉพาะสิ่งที่จำเป็นเท่านั้น
ที่ที่ Wasm รันได้ในปัจจุบัน
หัวข้อที่มีชื่อว่า “ที่ที่ Wasm รันได้ในปัจจุบัน”ใน Browser
หัวข้อที่มีชื่อว่า “ใน Browser”บ้านหลักของ Wasm คือ browser ผ่าน WebAssembly JavaScript API หน้าเว็บโหลดไฟล์ .wasm binary, instantiate ด้วย WebAssembly.instantiate และเรียกฟังก์ชันที่ export มาโดยตรงจาก JavaScript
const response = await fetch('module.wasm');const bytes = await response.arrayBuffer();const { instance } = await WebAssembly.instantiate(bytes, {});instance.exports.myFunction();browser หลักทุกตัว ได้แก่ Chrome, Firefox, Safari, Edge ได้รองรับ Wasm เต็มรูปแบบตั้งแต่ปี 2017
บน Server และ Edge
หัวข้อที่มีชื่อว่า “บน Server และ Edge”Node.js เปิดเผย WebAssembly.* API เดียวกับ browser Deno และ Bun ก็ทำเช่นเดียวกัน Cloudflare Workers และ Fastly Compute รองรับ Wasm module โดยกำเนิด ซึ่งหมายความว่าคุณสามารถ deploy binary เดิมไปยัง browser และ edge ได้โดยไม่ต้องเปลี่ยนแปลงอะไร
ผ่าน WASI
หัวข้อที่มีชื่อว่า “ผ่าน WASI”WebAssembly System Interface (WASI) คือ ABI มาตรฐานที่ให้ Wasm code รันนอก browser ด้วยการเข้าถึง OS capabilities อย่างควบคุม ไม่ว่าจะเป็น file, socket, clock, random โดยไม่ต้องมี JavaScript host เลย runtime อย่าง wasmtime และ wasmer implement WASI ทำให้คุณรันไฟล์ .wasm เป็น standalone process ได้
ในระบบ Plugin
หัวข้อที่มีชื่อว่า “ในระบบ Plugin”Sandboxing ของ Wasm ทำให้เหมาะกับ plugin architecture อย่างยิ่ง เครื่องมืออย่าง Extism และ embedded wasmtime ให้แอปพลิเคชันโหลด Wasm plugin ที่ไม่น่าไว้ใจ, expose API surface ที่ควบคุมได้ และบังคับใช้ข้อจำกัด memory และ capability ที่เข้มงวด ทั้งหมดนี้โดยไม่ต้องเปิด process แยกต่างหาก
Wasm เสริม JavaScript
หัวข้อที่มีชื่อว่า “Wasm เสริม JavaScript”Wasm ไม่ได้แทน JavaScript DOM, event handling, fetch และ web platform API ส่วนใหญ่เข้าถึงได้เฉพาะจาก JavaScript pattern ในทางปฏิบัติคือการแบ่งงาน: เก็บ IO, event และการจัดการ DOM ไว้ใน JavaScript และส่งงาน algorithm ที่ใช้ CPU หนักไปให้ Wasm module
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| ใช้ Wasm สำหรับ compute path | ความเร็วใกล้ native, portable ไปได้ทั้ง browser, server, edge, WASI runtime โดยไม่ต้อง recompile | เพิ่ม bundle size จาก binary + JS glue code สำหรับ marshal ข้อมูลข้าม boundary |
| ใช้ JavaScript ล้วนทุกที่ | debugging tooling mature เต็มที่ (breakpoint, source map, profiler) และ ecosystem ใหญ่ | ไม่ portable เท่าในแง่ raw compute performance และไม่มี sandbox ระดับ memory แบบ Wasm |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- เห็นว่า Wasm “เร็วกว่า native เกือบเท่า” แล้วสรุปว่าเร็วกว่า JavaScript เสมอในทุก workload ทั้งที่ JS engine สมัยใหม่ optimize hot loop ได้ดีมากเช่นกัน
- เลือกคอมไพล์ทั้งแอปพลิเคชันไปเป็น Wasm ตั้งแต่ต้น แทนที่จะดูจาก 4 เหตุผล (ความเร็ว, portability, การเลือกภาษา, ความปลอดภัย) ว่าจริงๆ แล้วมีแค่บาง module เช่น codec หรือ physics engine ที่ควรเป็น Wasm
- deploy Wasm module เล็กๆ ไปยัง edge หรือ WASI runtime โดยไม่คำนึงถึง cold-start cost ของการ compile และ instantiate ซึ่งอาจสำคัญมากกว่าความเร็วในการ execute เมื่อ module ถูกเรียกไม่บ่อย
💡 ตัวอย่างจากของจริง
Adobe ใช้ Wasm พอร์ต Photoshop C++ codebase ทั้งก้อนมารันใน browser เป็น Photoshop Web โดยยังคง algorithm การประมวลผลภาพเดิมไว้ทั้งหมด
Google Earth ใช้ Wasm รัน C++ rendering engine เดิมใน browser ได้โดยไม่ต้องเขียนใหม่เป็น JavaScript ตรงกับเหตุผลเรื่อง portability และความเร็วที่กล่าวถึงในบทนี้