WebAssembly เมื่อการพัฒนาเว็บเข้าสู่อีกโลกนึง

ในยุคที่มองไปทางไหนก็มีแต่การพัฒนา Software ด้วย Web Technology ไปหมดทุกทางและยิ่งเป็น Modern Web ที่มี JavaScript เป็นหัวใจสำคัญแล้วนั้น หลายๆปัญหาทางด้าน Performance ก็จะไปติดคอขวดอยู่ที่ Layer ของ JavaScript Engine ดังนั้นทางออกหนึ่งที่ทาง Community นั้นได้มองเห็นก็คือการต่อตรงกับ OS ไปเลยแทนที่จะต้องผ่านการแปล JavaScript ซึ่งนี่ก็คือหนึ่งในที่มาของ WebAssembly

WebAssembly คือการนำ Low Level Code ที่เขียนด้วย C/C++ (และอาจจะมีภาษาอื่นๆในอนาคตเพราะตอนนี้ก็มีภาษา Rust ที่ใช้ได้ด้วยเหมือนกัน) มาทำการรันภายใต้ Web Browser เพื่อให้ได้ Performance  สูงที่สุดรวมทั้งยังสามารถติดต่อกับ JavaScript ได้ด้วย ซึ่งหมายความว่ามันไม่ได้เป็นภาษาใหม่ที่จะมาแทน JavaScript แต่มันคือสิ่งที่จะช่วยยกระดับการพัฒนาเวปมากกว่าครับ และที่สำคัญโปรเจคนี้พัฒนาด้วยเจ้าใหญ่แห่งวงการทั้งนั้น เช่น Mozilla Microsoft Google Apple

เนื่องจากว่า WebAssembly นั้นค่อนข้าง Low Level มาก(แค่มีคำว่า Assembly ก็แลดูน่ากลัวแล้ว) ดังนั้นนักพัฒนาที่สนใจในเรื่องนี้ก็จำเป็นต้องรู้จักสิ่งเหล่านี้ก่อนครับ

  • Source Code แน่นอนว่าคือไฟล์ที่พวกเราเขียน Code ลงไปโดยจะแบ่งเป็น 2 ส่วนคือฝั่ง C/C++ กับฝั่ง JavaScript ครับ
  • Compiler เป็นตัวแปลงภาษา C/C++ ไปเป็น Bytes Code หรือ Machine Code ซึ่งภาษาที่ต้องใช้ Compiler นั้นจะเป็นภาษาที่มี Performance สูงกว่าภาษาพวก Script เพราะไม่ต้องแปลง Code ตอน เวลา Runtime
  • Bytes Code เป็นภาษาระดับกลางที่ทาง WebAssembly Runtime นั้นเข้าใจและทำงานติดต่อกับ OS ตรงๆ
  • Interoperability เป็นการทำงานเชื่อมกันระหว่างระบบหนึ่งกับอีกระบบหนึ่งเช่น การเรียกให้ Module ที่เขียนด้วย C++ ทำงานด้วย Code ของภาษา JavaScript หรือด้านสลับกัน

หลักการพัฒนาเว็บด้วย WebAssembly ก็คือ

  1. Developer เขียนโปรแกรมด้วย C/C++
  2. Developer ทำการ Compile C/C++ ที่เขียนไว้ให้เป็น WebAssembly Bytes Code (ไฟล์ .wasm) เพื่อให้พร้อมที่จะรันได้ใน Browser
  3. Developer ต้องเขียน JavaScript ให้ทำการโหลด .wasm ไฟล์มาไว้ใน Memory เพื่อให้ WebAssembly Runtime ที่อยู่บน Browser นั้นทำการแปลง Bytes Code ให้เป็น JavaScript Object
  4. Developer เรียกใช้งาน function ที่เขียนด้วย C/C++ ผ่าน JavaScript

ทีนี้เรามาลองดูแบบ Step by Step กัน

ก่อนอื่นเลยผมมี Code ที่เขียนด้วย C ง่ายๆคือ function การบวกเลข ช่ือไฟล์ demo.c

Screen Shot 2560-03-05 at 7.04.29 PM.png

สิ่งที่ต้องทำขั้นต่อไปคือ Compile Code ชุดนี้ให้เป็น .wasm ซึ่งเครื่องมือที่ใช้ค่อนข้างซับซ้อนสำหรับมือใหม่(อย่างผม) ซึ่งใช้ emcc (Emscriptenซึ่งเป็น Open Source โปรเจคซึ่งติดตั้งจาก ที่นี่

$emcc demo.c -Os -s WASM=1 -s SIDE_MODULE=1 -o democ.wasm

ด้วย command ข้างบนนี้เราก็จะได้ democ.wasm ซึ่งเป็นไฟล์ Bytes Code ที่ใช้งานได้กับ Browser ที่สนับสนุนแล้ว เช่น Google Chrome 57+ ขึ้นไป

หน้าตาของไฟล์ .wasm ก็เป็นแบบนี้ครับ!! อ่านไม่ออกแน่นอน เพราะเป็น Bytes Code 🙂

Screen Shot 2560-03-05 at 7.03.33 PM.png

ถัดมาเราก็มาเขียน JavaScript ให้การโหลดไฟล์ democ.wasm ซึ่งผมใช้ fetch API ครับและหลังจากนั้นเป็นการเรียกใช้งาน function

Screen Shot 2560-03-05 at 7.06.57 PM.png

จาก Code นี้ในฝั่งของ JavaScript นั้นผมขอแบ่งออกเป็น 4 ส่วนครับ

  1. โหลดไฟล์ .wasm ด้วย fetch API
  2. ทำการประกาศ imports Object เพื่อให้ตัว WenAssembly ทำงานได้ถูกต้อง เช่นการกำหนดขนาดของ  Memory
  3. เป็นการสร้าง Module Object จาก .wasm
  4. เป็น Code ที่ใช้เรียก function “add” ที่เขียนด้วยภาษา C (ในการ Compile นั้นทาง Compiler ได้เติม _ เพื่อเป็น prefix ให้กับชื่อ function ทำให้เราต้องเรียก function นี้ด้วย _add แทน)

ทีนี้ลองมารันดูครับด้วย localhost:8080/demo.html แต่ก่อนอื่นเราต้องมี Browser ที่รองรับก่อน

เตรียม Browser ให้พร้อม

ผมเลือกใช้ Google Chrome Canary Build (ซึ่งเป็น Google Chrome เวอร์ชั่นทดสอบ) ซึ่งตอนนี้เป็นเวอร์ชั่น 59 ครับ เราต้องเปิด flag สำหรับ WebAssembly ด้วยเพราะตอนนี้ยังเป็นแค่ฟีเจอร์สำหรับการทดสอบอยู่ด้วย

chrome://flags/#enable-webassembly

Screen Shot 2560-03-05 at 8.34.54 PM.png

ผลของการทำงานก็จะเห็นได้ว่า function _add นั้นทำการบวกค่าได้อย่างถูกต้อง

Screen Shot 2560-03-05 at 7.11.48 PM.png

สรุป

ก่อนอื่นต้องบอกว่า WebAssembly นั้นเป็นของที่ยังถือว่าใหม่และยังไม่นิ่งเพราะถึงแม้ว่าจะเปิดตัวมาตั้งแต่ปี 2015 แต่จนถึงวันนี้ก็ยังอยู่ในสถานะที่กำลังออกแบบกันอยู่ ซึ่งจากการที่ผมได้ลองอ่านและเล่นๆดูก็พบว่าบทความบนอินเตอร์เน็ตนั้นน้อยมาก กว่าผมจะพอปะติดปะต่อภาพรวมของการทำงานของมันจนมาถึงลองเขียน Code ตัวอย่างดูก็ใช้เวลาอยู่พักนึง แต่ผมว่าเมื่อถึงเวลาที่มันออกสู่สาธราณะเป็น Official Release ฟีเจอร์นี้ก็น่าจะถูกจับตามองอีกครั้งกับการใช้งานหนักๆ เช่น เกมหรืองานคำนวณ รวมทั้งงานที่เน้นกราฟฟิคหนักๆ