21 คะแนน โดย GN⁺ 2026-03-12 | 4 ความคิดเห็น | แชร์ทาง WhatsApp
  • นับตั้งแต่เปิดตัวครั้งแรกในปี 2017 WebAssembly ได้พัฒนามาอย่างต่อเนื่องพร้อม รองรับการรันภาษาระดับล่างอย่าง C/C++ แต่ก็ยังคง ถูกปฏิบัติเป็นภาษาชั้นสอง บนแพลตฟอร์มเว็บ
  • มีเพียง JavaScript เท่านั้นที่ โต้ตอบกับ Web API ได้โดยตรง ส่วน WebAssembly ต้องเขียน โค้ด binding ของ JS (glue code) ที่ซับซ้อนเพื่อทำสิ่งนี้
  • โครงสร้างเช่นนี้นำไปสู่ ขั้นตอนการโหลดที่ซับซ้อน, โอเวอร์เฮดด้านประสิทธิภาพ, และ การแยกขาดของ toolchain ตามภาษา ซึ่งทำให้ประสบการณ์ของนักพัฒนาแย่ลง
  • เพื่อแก้ปัญหานี้ Mozilla จึงเสนอ WebAssembly Component Model ที่ทำให้สามารถ เรียกใช้ Web API และโหลดโมดูลด้วยวิธีที่เป็นมาตรฐานได้โดยไม่ต้องพึ่ง JS
  • หากโมเดลนี้ได้รับการใช้งานอย่างแพร่หลาย WebAssembly ก็มีแนวโน้มจะกลายเป็น สภาพแวดล้อมการรันชั้นหนึ่งภายในเบราว์เซอร์ และวางรากฐานให้แม้นักพัฒนาทั่วไปก็ใช้งานได้ง่ายขึ้น

เหตุใด WebAssembly จึงถูกปฏิบัติเป็นภาษาชั้นสอง

  • WebAssembly สามารถ เข้าถึงแพลตฟอร์มเว็บ ได้ผ่าน JavaScript เท่านั้น และไม่มีสิทธิ์เรียก Web API โดยตรง
    • JavaScript โหลดได้ง่ายผ่านแท็ก <script> แต่ WebAssembly ต้องมี กระบวนการโหลดแบบแมนนวลผ่าน JS API
    • ต้องผ่านการเรียก API ที่ซับซ้อนอย่าง WebAssembly.instantiateStreaming() และนักพัฒนาต้องจำสิ่งเหล่านี้หรือใช้เครื่องมือช่วยอัตโนมัติ
  • ข้อเสนอ esm-integration ทำให้สามารถ import ไฟล์ .wasm ได้โดยตรงผ่านระบบโมดูลของ JS จึงช่วยลดความซับซ้อนของขั้นตอนการโหลด
    • สามารถโหลดได้โดยตรงในรูปแบบ <script type="module" src="/module.wasm"></script>

ข้อจำกัดในการเข้าถึง Web API

  • งานที่ใน JavaScript ทำได้ด้วย console.log("hello, world") เพียงบรรทัดเดียว กลับต้องใช้ขั้นตอนซับซ้อนใน WebAssembly เช่น การเข้าถึงหน่วยความจำของ JS, การถอดรหัสสตริง, การห่อฟังก์ชัน
    • WebAssembly ไม่สามารถเข้าถึงอ็อบเจ็กต์ console หรือ DOM ได้ จึงต้องเรียกผ่าน JS ทางอ้อมด้วย การแชร์หน่วยความจำและการ import/export ฟังก์ชัน
  • โค้ด binding (glue code) ที่เกิดขึ้นในกระบวนการนี้แตกต่างกันไปในแต่ละภาษา และมักถูกสร้างอัตโนมัติด้วยเครื่องมืออย่าง embind, wasm-bindgen
    • อย่างไรก็ตาม สิ่งนี้ทำให้เกิดปัญหาอย่างความซับซ้อนในการ build ที่เพิ่มขึ้น, runtime overhead และความไม่เข้ากันระหว่างภาษา

สาเหตุทางเทคนิคที่ทำให้ WebAssembly ยังไม่กลายเป็นภาษาชั้นหนึ่ง

  • ความยากในการผสานรวมกับคอมไพเลอร์: คอมไพเลอร์ของแต่ละภาษาต้องสร้างโค้ดสำหรับผสานรวมกับ JS และแพลตฟอร์มเว็บแยกกัน ซึ่งไม่สามารถนำกลับมาใช้ซ้ำได้
  • ความไม่เข้ากันของคอมไพเลอร์มาตรฐาน: ไฟล์ที่สร้างด้วย rustc --target=wasm ไม่สามารถรันในเบราว์เซอร์ได้ทันที
    • จำเป็นต้องติดตั้ง toolchain ที่ไม่เป็นทางการ เพิ่มเติมเพื่อรองรับการผสานรวมกับแพลตฟอร์ม
  • อคติของ ecosystem ด้านเอกสาร: เอกสารเว็บอย่าง MDN ส่วนใหญ่เขียนโดย ยึด JavaScript เป็นศูนย์กลาง ทำให้ผู้ใช้ภาษาอื่นมีอุปสรรคในการเริ่มต้นสูง
  • ปัญหาด้านประสิทธิภาพ: การเรียก DOM ผ่าน JS binding ทำให้ ประสิทธิภาพลดลง 45% เมื่อเทียบกับการเรียกโดยตรง
    • ในการทดลองของเฟรมเวิร์ก Dodrio เมื่อเอา JS glue ออก เวลาที่ใช้ในการนำการเปลี่ยนแปลง DOM ไปใช้ลดลงครึ่งหนึ่ง
  • การพึ่งพา JavaScript: หากต้องการใช้ WebAssembly ในงานจริง สุดท้ายก็ยังต้องเข้าใจ JS อยู่ดี ซึ่งนำไปสู่ปัญหา abstraction leakage

การมาของ WebAssembly Component Model

  • WebAssembly Component Model กำหนด หน่วยการรันที่เป็นมาตรฐาน ซึ่งหลายภาษาและหลายรันไทม์สามารถใช้ร่วมกันได้
    • ทำให้สามารถเข้าถึง Web API, โหลดโมดูล และลิงก์ได้ โดยตรงโดยไม่ต้องผ่าน JS
    • สามารถสร้างได้จากหลายภาษา และรองรับการรันได้ทั้งบนเบราว์เซอร์หรือรันไทม์อย่าง Wasmtime
  • สามารถประกาศ API ที่ต้องการผ่าน WIT (Interface Description Language) และเรียกใช้ได้โดยตรงจากภายในคอมโพเนนต์
    • ตัวอย่าง:
      component {
        import std:web/console;
      }
      
      → สามารถเรียก console::log("hello, world") ได้จากโค้ด Rust
  • เบราว์เซอร์สามารถโหลดคอมโพเนนต์ได้โดยตรงผ่าน <script type="module" src="component.wasm"></script> และ จัดการ Web API binding ให้อัตโนมัติโดยไม่ต้องใช้ JS

การทำงานร่วมกับ JavaScript

  • Component Model ยังรองรับ โครงสร้างแอปแบบไฮบริด
    • ตัวอย่างเช่น เขียน image decoder ด้วย WebAssembly แล้วเรียกจาก JS ในรูปแบบ import { Image } from "image-lib.wasm"; ได้
    • JS สามารถใช้ WebAssembly component ผ่านการ import/export เหมือนโมดูลทั่วไป

แนวโน้มในอนาคตและการมีส่วนร่วม

  • Mozilla กำลังทำงานด้าน การทำมาตรฐานของ Component Model ร่วมกับ WebAssembly CG และ Google ก็อยู่ในขั้นตอนการพิจารณา
  • นักพัฒนาสามารถทดลองได้ผ่าน Jco หรือ Wasmtime ทั้งในเบราว์เซอร์และ CLI
  • หากโมเดลนี้ได้รับการยอมรับอย่างแพร่หลาย WebAssembly ก็มีโอกาสขยายจาก ฟีเจอร์สำหรับผู้ใช้ขั้นสูง ไปเป็น เทคโนโลยีเว็บที่นักพัฒนาทั่วไปใช้งานได้

4 ความคิดเห็น

 
jeeeyul 2026-03-12

นี่ก็แทบจะเป็นแค่ความหวังแบบฉบับ Mozilla มากกว่า ฟรอนต์เอนด์ไม่อาจหลุดพ้นจากโครงสร้างของระบบลิมบิกที่ตอบสนองต่อปฏิกิริยาของตลาดได้ ตั้งแต่ตอนที่ WebAssembly ปรากฏตัวขึ้นก็มีการพอร์ต Doom 3 ทันที DOM ในเบราว์เซอร์สมัยใหม่ก็เปลี่ยนเป็นอ็อบเจ็กต์พร็อกซีแบบน้ำหนักเบามานานแล้ว และเมื่อพิจารณาถึงชุดคำสั่งเฉพาะสำหรับ JavaScript ของ CPU สมัยใหม่ รวมถึงข้อจำกัดเชิงควอนตัมของซิงเกิลคอร์ ก็ไม่มีวันที่แนวทางแบบนี้จะได้เปรียบในเชิงมูลค่าตลาด

ไบนารี WebAssembly ที่รันอยู่ใน Electron จะมีความหมายอะไรล่ะ? นี่ก็ดูเหมือนเป็นแค่อีกกรณีของการล่าชื่อเสียงจากการพอร์ต Rust หรือไม่ก็ GitKraken CLI เท่านั้นเอง

 
carnoxen 2026-03-14

อย่างอื่นไม่รู้หรอก แต่แนวทางการแทรกโมดูล wasm เป็นไฟล์แบบ <script type="module" src="/module.wasm"></script> นี่ชวนสนใจทีเดียว

 
jeeeyul 2026-03-12

และคงต้องบอกด้วยว่าคำกล่าวอ้างที่ว่า WebAssembly มีอุปสรรคในการเข้าถึงสูงนั้นช่างน่าขัน สิ่งที่เกิดขึ้นก็แค่ความจำเป็นที่จะต้องทำมันต่ำกว่าความตั้งใจจะจ่ายเท่านั้น อยากได้ความเร็วกับขนาดที่เล็ก แต่ก็ยังอยากใช้ DOM กับ CSS งั้นเหรอ? นี่มันตลกร้ายอะไรกันครับ

 
GN⁺ 2026-03-12
ความเห็นจาก Hacker News
  • ทั้งหมดนี้น่าจะทำได้ตั้งแต่ ห้าปีก่อนครึ่ง แล้ว
    น่าเสียดายที่พอเลิกเป้าหมายแรกเริ่มที่จะรองรับ WebIDL ใน WebAssembly แล้วหันไปสร้าง IDL ตัวใหม่ กลับไม่ได้มองว่าการไม่มีการเข้าถึง DOM เป็นปัญหา
    แน่นอนว่าเข้าใจความเป็นจริงของตลาด แต่ก็ยังอดเสียดายเวลาที่สูญเสียไปไม่ได้
    ลิงก์อ้างอิงที่เกี่ยวข้อง: ประวัติ commit, บทความย้อนหลังเกี่ยวกับ stringref, บทความ ACM
    • ก่อนหน้านี้เคยมีส่วนร่วมทำงานกับ ข้อเสนอ interface-types
      หลังจากนั้นก็มีการเพิ่มเป้าหมายอีกสองข้อ คือ รองรับ API ที่ไม่ใช่เว็บ และ การทำงานร่วมกันระหว่างภาษา
      WebIDL เป็นผลรวมของ JS กับ Web API จึงมีพลังในการแสดงออกสูง แต่ก็มีแนวคิดหลายอย่างที่ขัดกับเป้าหมายเหล่านี้
      เพราะแบบนั้น component interface จึงเลือกแนวทางแบบ จุดตัดที่พกพาได้สูงกว่า แม้จะลดความสามารถในการแสดงออกลง
      ส่วนตัวคิดว่าการเข้าถึง DOM สำคัญ แต่ Wasm CG ก็ยุ่งอยู่กับเรื่องที่มีลำดับความสำคัญสูงกว่า
      เหตุผลที่เขียนบทความนี้ก็เพื่อบอกว่ายังจำปัญหานี้ได้อยู่ และมีแผนจะทำงานต่อไป
    • หวังจริง ๆ ว่า stringref จะกลับมาอีกครั้ง
  • กำแพงการเริ่มต้นใช้งาน ของ WASM สูงมากจริง ๆ
    toolchain กับกระบวนการ build ซับซ้อนเกินไป จนทุกครั้งที่ใช้รู้สึกมีภาระทางความคิด
    ประสิทธิภาพดีกว่ามากเมื่อไม่มี glue แต่ก็มีจุดเสี่ยงมากขึ้นตามไปด้วย
    หวังว่า component model จะไม่เพิ่มความซับซ้อนแบบใหม่ แต่ดูจากตัวอย่างหลายภาษาแล้วก็ค่อนข้างชวนสับสนอยู่แล้ว
    โดยเฉพาะ ตัวอย่าง Go ที่มีไฟล์ที่ถูกสร้างออกมาเยอะเกินไป และในมุมของนักพัฒนา สิ่งที่ต้องการมากคือ ทำให้ tooling เรียบง่ายขึ้น
    ตอนนี้มันดูเหมือนไม่ได้กำจัดความซับซ้อน แต่แค่ ย้ายมันไปที่อื่น
    • ยอมรับว่า tooling ยังอยู่ในช่วงเริ่มต้น
      สเปก wasm component เปลี่ยนอยู่เรื่อย ๆ เลยมี churn มาก
      เป้าหมายคือทำให้นักพัฒนาเว็บไม่ต้องเขียน WIT เอง และสามารถใช้ Web API เหมือนใช้ไลบรารี
      แต่ตอนนี้ก็ยังต้องไปอีกไกล
  • พัฒนาการของ WebAssembly component น่าสนใจ แต่รู้สึกว่ากำลังพลาดโอกาสในการ แยก Web API ออกเป็นหน่วยมาตรฐานเล็ก ๆ
    เช่น ถ้าแยกเป็นการแชร์ข้อความ การแชร์สื่อ การแชร์แอปพลิเคชัน ก็จะช่วยเรื่องความปลอดภัย และทำให้ทีมเล็ก ๆ สร้างทางเลือกแทนเบราว์เซอร์ได้ด้วย
    แต่ขนาดของ Web API และ CSS ที่ใหญ่โตคือสิ่งที่ค้ำจุน การผูกขาดของเบราว์เซอร์ อยู่ จึงน่าจะทำแบบนั้นได้ยาก
    น่าจะดีถ้ามีการทำมาตรฐาน WebAssembly registry เพื่อให้ประกอบคอมโพเนนต์เข้าด้วยกันได้ง่าย
    สุดท้ายแล้วเว็บก็คือกระบวนการสร้าง นิยามของระบบปฏิบัติการแบบกระจายศูนย์
  • ถ้าอยากเรียนรู้ WebAssembly สมัยใหม่ ขอแนะนำ Component Model Book
    อธิบายได้ดีตั้งแต่แนวคิดไปจนถึงตัวอย่างโค้ด
    ใน ecosystem ของ JS มีสามโปรเจ็กต์หลักคือ StarlingMonkey, ComponentizeJS, jco
    ตอนนี้ toolchain ที่สุกงอมที่สุดคือ Rust แต่การรองรับภาษาในสาย LLVM (C/C++, Go, Python ฯลฯ) ก็ดีขึ้นเรื่อย ๆ
    เป้าหมายของ WebAssembly คือการเป็น compile target ที่ผสานเข้ากับ local toolchain ได้อย่างเป็นธรรมชาติ
  • เหตุผลที่คำว่า “first-class” สำคัญ ก็เพราะนักพัฒนาส่วนใหญ่เลิกใช้แพลตฟอร์มเพราะ แรงเสียดทาน (friction) มากกว่าปัญหาเรื่องประสิทธิภาพ
    ถ้ายังต้องเข้าใจ glue code ของแต่ละภาษา หรือยังต้องทำความเข้าใจกับ runtime model สองแบบ WebAssembly ก็จะยังคงเป็น “เครื่องมือที่ใช้เฉพาะในสถานการณ์สุดขั้ว” อยู่ดี
    ถ้าจะให้เกิดการเปลี่ยนแปลงจริง ๆ ต้อง ทำให้เส้นทางการ build แบบทั่วไปเรียบง่ายขึ้น
  • เว็บทำงานไม่ได้เลยหากไม่มี การตรวจจับความสามารถแบบไดนามิก
    ยังไม่ชัดเจนว่าใน Component Model จะจัดการเรื่องนี้อย่างไร
    DOM ต่างกันไปตามเบราว์เซอร์ และความสามารถก็เปลี่ยนไปในแต่ละครั้งที่โหลดหน้า
    ในชั้น JS bridge สามารถใส่ polyfill ได้ง่าย แต่ในอินเทอร์เฟซ WIT การทำ runtime method detection หรือ polyfill ทำได้ยาก
    นอกจากประสิทธิภาพแล้ว ความยืดหยุ่นของ ecosystem ก็สำคัญ
  • บทความนี้ถ่ายทอดความอึดอัดของ “กำแพง WebAssembly” ได้ดี
    การต้องจัดการ JS glue code เองหรือพึ่งเครื่องมือสร้างอัตโนมัติ รู้สึกเหมือนถอยหลังครั้งใหญ่
    การทดลอง Dodrio ที่ตัด glue ออกแล้วได้ ลด overhead ลง 45% น่าประทับใจมาก
    แต่ก็สงสัยว่าเวลา WebAssembly Component Model โต้ตอบกับ Web API โดยตรงนั้น การจัดการหน่วยความจำ เป็นอย่างไร
    อยากรู้ว่าข้อเสนอ Wasm GC ถูกใช้เพื่อคง DOM reference ไว้หรือไม่ หรือท้ายที่สุดแล้วยังต้องพึ่ง JS GC อยู่
    หวังว่า Wasm จะกลายเป็น พลเมืองชั้นหนึ่ง อย่างแท้จริง
    • สงสัยว่าช่วงนี้การปรับปรุง sendMessage ของ v8 และ Bun จะช่วยบรรเทาปัญหานี้ได้หรือไม่
      แต่ตอนนี้ IPC ก็ยังไม่มีประสิทธิภาพอยู่ดี และคิดว่าน่าจะต้องมีวิธีแบบ ส่งเป็นหน่วย memory page
    • มีคนชี้ว่าความเห็นด้านบน ดูเหมือนเขียนโดย LLM และอาจผิดกฎของ HN (แนวทาง)
  • เว็บเป็นชุดของการทดลองที่น่าสนใจมาโดยตลอด
    การยอมให้ใครก็ได้รันโปรแกรมซับซ้อนบนคอมพิวเตอร์ของฉันเป็นความคิดที่ บ้าคลั่งในแง่ความปลอดภัย แต่เราก็ทำแบบนั้นกันมาจริง ๆ
    ด้วย JS เราเจอบั๊กความปลอดภัยของเบราว์เซอร์มานับไม่ถ้วนตลอด 20 ปีที่ผ่านมา แต่ตอนนี้ก็มีหลักการออกแบบและมาตรการบรรเทาที่ลงตัวแล้ว
    พอมาตอนนี้กลับจะพยายามเปลี่ยนไปสู่ กระบวนทัศน์การรันที่เสี่ยงอันตรายอีกแบบ มันทั้งย้อนแย้งและสวยงามในเวลาเดียวกัน
    • จริง ๆ แล้วบทบาทแบบนี้ควรเป็นหน้าที่ของ ระบบปฏิบัติการ (OS)
      ระบบปฏิบัติการบนมือถือทำเรื่องนี้ได้ดีกว่าเดสก์ท็อปมาก
    • ต้นเหตุของปัญหาความปลอดภัยไม่ใช่ JS เอง แต่เป็น Browser API
    • ไม่มีอะไรถูก “แทนที่” แค่กำลังถูกขยายออกไปเท่านั้น
    • อยากรู้ว่าเหตุใด WASM ถึงอันตรายกว่า JS
    • สิ่งที่เป็นปัญหาคือความสามารถแบบ ทำลาย sandbox อย่าง WebUSB ไม่ใช่ wasm เอง
  • มาตรฐานใหม่ ๆ ช่วงนี้ดูจะให้ความสำคัญกับ JS boilerplate ที่ซับซ้อน มากกว่าความเรียบง่าย
    ออกแบบโดยมีวิศวกรเป็นศูนย์กลาง และไม่มี workflow เริ่มต้นที่เป็นมิตรกับผู้เขียน (author)
    ถึงอย่างนั้นก็ดีที่ยังมีคนที่ใส่ใจปัญหาแบบนี้อยู่
  • ส่วนตัวยังคิดว่า มันไม่ใช่ไอเดียที่ดีนัก (การถกเถียงก่อนหน้า)
    ให้ความรู้สึกเหมือนกำลังทำวิศวกรรมเกินจำเป็นเพื่อให้ได้การประมวลผลสตริงเร็วขึ้น 2 เท่า เพียงเพื่อแมป DOM API แบบ 1:1
    สำหรับ API อย่าง WebGL2, WebGPU, WebAudio ต้นทุนของ JS shim เล็กมากอยู่แล้ว
    ปัญหาจริงคือเรื่องอย่างการคัดลอก GPU buffer ซึ่ง component model ก็ไม่ได้ช่วยตรงนั้น
    อยากเห็น benchmark ที่ทดสอบ draw call หลายหมื่นครั้งบน WebGL2 หรือ WebGPU
    • บางกรณีอาจไม่ได้ดีขึ้นมาก แต่ ประสิทธิภาพของ DOM ก็ยังเป็นคอขวดของหลายแอป
      นอกจากประสิทธิภาพแล้ว การปรับปรุง ประสบการณ์นักพัฒนา (DX) ก็สำคัญ
      ตอนนี้มันเริ่มต้นยากเกินไป และมีแต่ผู้เชี่ยวชาญเท่านั้นที่ดึงประโยชน์ออกมาได้
    • ไม่ใช่แค่การประมวลผลสตริงเร็วขึ้น 2 เท่า แต่ข้อดีใหญ่ที่สุดคือ ไม่ต้องมี glue code
    • WebAssembly อาจกลายเป็น ทางเลือกต่อความปิดของระบบปฏิบัติการมือถือ
      ถ้าแข่งขันได้ด้วยประสิทธิภาพระดับแอปเนทีฟ นี่ก็เป็นการเปลี่ยนแปลงที่มีวิสัยทัศน์สำหรับอนาคตของเว็บ
    • แค่ทำให้การเข้าถึง DOM เร็วขึ้นก็มีความหมายมากพอแล้ว
    • component model ดูเหมือนการสร้างงานให้ตัวเองโดยไม่จำเป็น
      ในยุคของ coding agent การปรับปรุง DX แบบที่พวกเขาพูดถึงอาจไม่สำคัญอีกต่อไป