WebAssembly - Làm việc với Node.js

Xin chào các bạn đang theo đuổi lập trình! Hôm nay, chúng ta sẽ bắt đầu một chuyến hành trình thú vị vào thế giới của WebAssembly và Node.js. Đừng lo lắng nếu những thuật ngữ này听起来 như là ngôn ngữ ngoài hành tinh - đến cuối bài hướng dẫn này, bạn sẽ có thể sử dụng chúng một cách lưu loát!

WebAssembly - Working with Nodejs

WebAssembly là gì?

WebAssembly, thường được viết tắt là Wasm, giống như một siêu anh hùng trong thế giới lập trình. Đó là một định dạng chỉ thị nhị phân cho phép mã được viết bằng các ngôn ngữ như C, C++, và Rust chạy trong các trình duyệt web với tốc độ gần như tốc độ bản địa. Hãy tưởng tượng việc bạn có thể chơi các trò chơi 3D phức tạp trực tiếp trong trình duyệt - đó chính là sức mạnh mà WebAssembly mang lại!

Tại sao lại là Node.js?

Bây giờ, bạn có thể tự hỏi, "Node.js có liên quan gì đến tất cả những điều này?" Well, Node.js giống như đội ngũ hậu trường giúp tạo ra phép màu. Đó là một môi trường chạy JavaScript cho phép chúng ta chạy JavaScript bên ngoài trình duyệt web. Khi chúng ta kết hợp WebAssembly với Node.js, chúng ta có được sự kết hợp tốt nhất của cả hai thế giới - tốc độ của WebAssembly và sự linh hoạt của Node.js.

Thiết lập Môi trường Làm Việc

Trước khi chúng ta nhảy vào mã, hãy thiết lập không gian làm việc của mình. Đừng lo lắng, nó dễ dàng hơn việc thiết lập một chiếc điện thoại mới!

  1. Cài đặt Node.js từ trang web chính thức (https://nodejs.org)
  2. Mở terminal hoặc command prompt
  3. Tạo một thư mục mới cho dự án của chúng ta:
    mkdir wasm-nodejs-tutorial
    cd wasm-nodejs-tutorial
  4. Khởi tạo một dự án Node.js mới:
    npm init -y

Tuyệt vời! Bây giờ chúng ta đã sẵn sàng để bắt đầu lập trình.

.Module WebAssembly Đầu Tiên của Bạn

Hãy tạo một module WebAssembly đơn giản để cộng hai số. Chúng ta sẽ viết nó bằng C và biên dịch nó thành WebAssembly.

Bước 1: Viết mã C

Tạo một tệp có tên add.c với nội dung sau:

#include <emscripten.h>

EMSCRIPTEN_KEEPALIVE
int add(int a, int b) {
return a + b;
}

Đừng hoảng hốt nếu điều này trông giống như các chữ viết tượng hình! Hãy để chúng ta phân tích nó:

  • #include <emscripten.h> bao gồm thư viện Emscripten, giúp chúng ta biên dịch C thành WebAssembly.
  • EMSCRIPTEN_KEEPALIVE là một chỉ thị đặc biệt cho biết bộ biên dịch giữ lại hàm này để có thể truy cập từ JavaScript.
  • int add(int a, int b) là hàm của chúng ta nhận hai số nguyên và trả về tổng của chúng.

Bước 2: Biên dịch thành WebAssembly

Để biên dịch mã C này thành WebAssembly, chúng ta cần cài đặt Emscripten. Theo các hướng dẫn cài đặt trên trang web Emscripten (https://emscripten.org/docs/getting_started/downloads.html).

Sau khi cài đặt, chạy lệnh này:

emcc add.c -s WASM=1 -s EXPORTED_FUNCTIONS='["_add"]' -o add.js

Lệnh này biên dịch mã C của chúng ta thành WebAssembly và tạo ra hai tệp: add.wasmadd.js.

Sử dụng WebAssembly trong Node.js

Bây giờ đến phần thú vị - sử dụng module WebAssembly của chúng ta trong Node.js!

Tạo một tệp có tên index.js với nội dung sau:

const fs = require('fs');
const path = require('path');

const wasmBuffer = fs.readFileSync(path.join(__dirname, 'add.wasm'));

WebAssembly.instantiate(wasmBuffer).then(wasmModule => {
const add = wasmModule.instance.exports._add;
console.log('5 + 3 =', add(5, 3));
});

Hãy phân tích điều này:

  1. Chúng ta nhập các mô-đun cần thiết của Node.js: fs cho các hoạt động hệ thống tệp và path cho việc làm việc với các đường dẫn tệp.
  2. Chúng ta đọc tệp WebAssembly vào một bộ đệm.
  3. Chúng ta sử dụng WebAssembly.instantiate() để tải và biên dịch module WebAssembly của chúng ta.
  4. Khi đã tải, chúng ta có thể truy cập hàm add thông qua wasmModule.instance.exports._add.
  5. Cuối cùng, chúng ta gọi hàm này và ghi kết quả.

Chạy script này bằng lệnh:

node index.js

Nếu mọi thứ đều hoạt động đúng, bạn nên thấy: 5 + 3 = 8

Chúc mừng! Bạn vừa chạy module WebAssembly đầu tiên của mình trong Node.js!

So Sánh Hiệu Suất

Bây giờ, hãy so sánh hiệu suất của hàm WebAssembly của chúng ta với một hàm JavaScript bản địa.

Thêm đoạn mã này vào index.js của bạn:

function jsAdd(a, b) {
return a + b;
}

const iterations = 1000000;

console.time('WebAssembly');
for (let i = 0; i < iterations; i++) {
add(5, 3);
}
console.timeEnd('WebAssembly');

console.time('JavaScript');
for (let i = 0; i < iterations; i++) {
jsAdd(5, 3);
}
console.timeEnd('JavaScript');

Đoạn mã này chạy cả hai版本 của hàm add của chúng ta một triệu lần và đo lường thời gian từng phiên bản.

Chạy script một lần nữa, và bạn có thể thấy rằng phiên bản WebAssembly nhanh hơn!

Kết Luận

Chúng ta chỉ mới chạm đến bề mặt của những gì có thể thực hiện được với WebAssembly và Node.js. Hãy tưởng tượng những khả năng - bạn có thể sử dụng các thuật toán phức tạp viết bằng C hoặc Rust, các engine trò chơi, hoặc thậm chí là các ứng dụng hoàn chỉnh, tất cả đều chạy với tốc độ gần như bản địa trong Node.js!

Nhớ rằng, việc học lập trình giống như học骑自行车. Nó có thể trông不稳定 ban đầu, nhưng với sự luyện tập, bạn sẽ nhanh chóng zoom qua không gian trong thời gian ngắn. Hãy tiếp tục thử nghiệm, học hỏi và quan trọng nhất, hãy vui vẻ!

Dưới đây là bảng tóm tắt các phương thức chính chúng ta đã sử dụng:

Phương thức Mô tả
WebAssembly.instantiate() Biên dịch và khởi tạo một module WebAssembly
fs.readFileSync() Đọc một tệp đồng bộ
path.join() Kết hợp các đoạn đường dẫn
console.time() Bắt đầu một bộ đếm thời gian
console.timeEnd() Kết thúc một bộ đếm thời gian và ghi kết quả

Chúc mừng các pháp sư WebAssembly tương lai! Hãy tiếp tục lập trình và vui vẻ!

Credits: Image by storyset