"Web Platform"

Giới thiệu WebAssembly

Về cơ bản, WebAssembly là một ngôn ngữ mới có thể chạy trên trình duyệt (dĩ nhiên là ngoài JavaScript ra). Nó được thiết kế để dịch ra từ ngôn ngữ low-level khác như C/C++ và Rust, nhưng không nhằm để thay thế JavaScript. Tuy bản thân JavaScript đủ mạnh để giải quyết đa số các vấn đề trên web. Nhưng hiện nay chúng ta cũng gặp phải một số vấn đề về hiệu năng (performance) của JavaScript, trong các ứng dụng cần xử lý nhiều như các ứng dụng trò-chơi lập-thể (3D games), thực-tế ảo (virtual reality)thực-tế tăng-cường (augmented reality), thị giác máy tính (computer vision), chỉnh sửa hình ảnh và phim v.v

WebAssembly có một ý nghĩa không nhỏ với nền tảng web nói chung, nó cho phép chương trình được viết bằng nhiều ngôn ngữ khác nhau có thể chạy trên web, mà trước đó là bất khả thi. Các modules WebAssembly không chỉ có thể được đưa vào các ứng dụng web (trên trình duyệt) mà cũng có thể được sử dụng trong các ứng dụng node.js. Cũng phải nói thêm là hiện nay, định dạng WASM đã được hỗ trợ rộng rãi trên các trình duyệt phổ biến như Chrome, Firefox, Safari và Edge.

"Browser party"

Ngày nay, các ứng dụng của WebAssembly đã phát triển vượt khỏi phạm vi của các trò chơi trực tuyến (online games). Cùng với trình biên dịch EmScripten, ngày càng có nhiều thử nghiệm với WebAssembly được triển khai. Ví dụ như

WebAssembly có vài trò như thế nào đối với web?

"WebAssembly"

Nền tảng web có thể được tách ra làm 2 phần

  • Phần máy ảo (virtual machine) để thực thi JavaScript code
  • Phần Web APIs để điều khiển các chức năng của trình duyệt, thiết bị (DOM, CSSOM, WebGL, IndexedDB, Web Audio API, etc)

Hầu như từ trước đến giờ, cái máy ảo trong trình duyệt chỉ có thể tải và chạy JavaScript, và cũng đã đề cập ở trên ngôn ngữ độc quyền này cũng có một số nhược điểm. Sự ra đời WebAssembly không được tạo ra để thay thế JavaScript, mà để bổ sung cũng như hoạt đồng song song với JavaScript. Cả hai ngôn ngữ này mang lại nhiều lợi thế riêng của mình cho web. Ví dụ:

  • JavaScript là một ngôn ngữ cấp cao, linh động và hiệu quả đủ để viết các ứng dụng web. Nó có nhiều lợi thế như là một ngôn ngữ có kiểu động (dynamically typed langugage), không yêu cầu phải biên dịch và một hệ sinh thái khổng lồ gồm nhiều khung-làm-việc (framework), thư viện (libraries) và đủ các chủng loại công cụ (tools chain).

  • Trong khi đó, WebAssembly là một ngôn ngữ cấp thấp, với một định dạng nhị phân nhỏ gọn (compact binary format), được thực thi với một tốc độ gần-tương-đương với các ngôn ngữ cấp thấp. Đồng thời nó cũng cho phép chương trình được viết bằng các ngôn ngữ cấp thấp cho phép quản lý nhớ như C++ hoặc Rust có khả năng chạy trên nền web. Ngoài ra trong tương lai, WebAssembly cũng có mục tiêu là hỗ trợ các ngôn ngữ có bộ dọn rác (garbage collector), như Python hay Ruby.

Nói về tốc độ thực thi và hiệu năng, thì trên trang Hỏi-Đáp của WebAssembly cũng có nói rằng, WebAssembly được phân-tích cú-pháp (parse) nhanh hơn JavaScript 20 lần.

The kind of binary format being considered for WebAssembly can be natively decoded much faster than JavaScript can be parsed (experiments show more than 20× faster). On mobile, large compiled codes can easily take 20–40 seconds just to parse, so native decoding (especially when combined with other techniques like streaming for better-than-gzip compression) is critical to providing a good cold-load user experience.

Nguồn: WebAssembly FAQ

Về cơ bản, WebAssembly là một ngôn ngữ khác và độc lập so với JavaScript, nhưng WebAssembly JavaScript API đóng gói các WebAssembly code thành các hàm JavaScript để có thể được thực thi bình thường như JavaScript trong browser hay node.js.

Nói nhiều quá, cho xem code đi!

Thực chất WebAssembly không được thiết kể để viết bằng tay (mà để compile từ C++/Rust sang wasm), tuy nhiên chúng ta hoàn toàn có thể làm thủ công.

Trong đặc tả ngôn ngữ của WebAssembly (specification) có mô tả về hai định dạng của WebAssembly, một là dạng nhị phân nén WASM, thường được đem đi phân phối. Dạng thứ hai là WAT (WebAssembly Text Format), cũng rất gần với dạng nhị phân, nhưng thân thiện với loài người hơn.

(module
  (func (result i32)
    (i32.const 42)
  )
  (export "helloWorld" (func 0))
)

Đây là một hàm đơn giản trả về hằng số 42 (câu trả lời cho tất cả câu hỏi trong vũ trụ :-P). Để biên dịch code WAT ở trên ra WASM, ta cần cài WABT (The WebAssembly Binary ToolKit).

Sau khi cài xong WABT, chỉ cần chạy lệnh sau từ console là ta có file .wasm

wat2wasm hello.wat -o hello.wasm

Sau khi được biên dịch thành định dạng .wasm, ta có thể gọi hàm helloWorld trong node.js như sau:

const { readFileSync } = require("fs");

const run = async () => {
  const buffer = readFileSync("./hello.wasm");
  const module =  await WebAssembly.compile(buffer);
  const instance = await WebAssembly.instantiate(module);
  console.log(instance.exports.helloWorld());
};

run();

Để chạy trong browser, ta cần chỉ cần nhúng script sau vào html

fetch("hello.wasm").then(reponse =>
    reponse.arrayBuffer()
).then(bytes =>
    WebAssembly.instantiate(bytes, {})
).then(result =>
    result.instance
).then(instance =>
    console.log(instance.exports.helloWorld())
);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello WebAssembly</title>
</head>
<body>
    <!-- The only thing that matters is the following line,
    although having a valid HTML5 page is nice. -->
    <script src="hello.js"></script>
</body>
</html>

Tham khảo

  1. WebAssembly Concepts

  2. Loading and running WebAssembly code

  3. WebAssembly support now shipping in all major browsers

  4. 7 Things You Should Know About WebAssembly

  5. WebAssembly - FAQ