21 điểm bởi GN⁺ 2026-03-12 | 4 bình luận | Chia sẻ qua WhatsApp
  • Kể từ lần ra mắt đầu tiên vào năm 2017, WebAssembly đã phát triển với khả năng hỗ trợ thực thi các ngôn ngữ mức thấp như C/C++, nhưng trên nền tảng web, nó vẫn bị đối xử như ngôn ngữ hạng hai
  • Chỉ JavaScript mới có thể tương tác trực tiếp với Web API, còn WebAssembly phải viết mã binding JS phức tạp (glue code) để làm điều đó
  • Cấu trúc này dẫn đến quy trình tải phức tạp, chi phí hiệu năng bổ sung, đứt gãy toolchain theo từng ngôn ngữ, làm suy giảm trải nghiệm lập trình viên
  • Để giải quyết vấn đề này, Mozilla đề xuất WebAssembly Component Model, cho phép gọi Web API và tải mô-đun theo cách chuẩn hóa mà không cần JS
  • Nếu mô hình này được thiết lập rộng rãi, WebAssembly được kỳ vọng sẽ trở thành môi trường thực thi hạng nhất trong trình duyệt, tạo nền tảng để cả các lập trình viên phổ thông cũng có thể dễ dàng sử dụng

Vì sao WebAssembly bị xem là ngôn ngữ hạng hai

  • WebAssembly chỉ có thể truy cập nền tảng web thông qua JavaScript và không có quyền gọi Web API trực tiếp
    • JavaScript có thể được tải đơn giản bằng thẻ <script>, nhưng WebAssembly cần quy trình tải thủ công qua JS API
    • Phải đi qua các lệnh gọi API phức tạp như WebAssembly.instantiateStreaming(), và lập trình viên либо phải ghi nhớ chúng hoặc tự động hóa bằng công cụ
  • Đề xuất esm-integration đơn giản hóa quy trình tải bằng cách cho phép import trực tiếp tệp .wasm qua hệ thống mô-đun JS
    • Có thể tải trực tiếp dưới dạng <script type="module" src="/module.wasm"></script>

Hạn chế trong việc truy cập Web API

  • Một việc trong JavaScript chỉ cần một dòng console.log("hello, world") thì trong WebAssembly lại đòi hỏi truy cập bộ nhớ JS, giải mã chuỗi, bọc hàm và nhiều bước phức tạp khác
    • WebAssembly không thể truy cập đối tượng console hay DOM, nên phải gọi gián tiếp từ JS thông qua chia sẻ bộ nhớ và import/export hàm
  • Mã binding (glue code) sinh ra trong quá trình này khác nhau theo từng ngôn ngữ, và thường được tạo tự động bằng các công cụ như embind, wasm-bindgen
    • Tuy nhiên, điều này lại gây ra các vấn đề như tăng độ phức tạp khi build, overhead lúc chạy, và thiếu tương thích giữa các ngôn ngữ

Các nguyên nhân kỹ thuật khiến WebAssembly chưa thể trở thành ngôn ngữ hạng nhất

  • Khó khăn trong tích hợp compiler: compiler của mỗi ngôn ngữ phải tự sinh mã tích hợp với JS và nền tảng web, và phần này không thể tái sử dụng
  • Compiler chuẩn không tương thích: tệp được tạo bằng rustc --target=wasm không thể chạy ngay trong trình duyệt
    • Cần cài thêm toolchain không chính thức có triển khai tích hợp nền tảng
  • Sự thiên lệch của hệ sinh thái tài liệu: tài liệu web như MDN phần lớn được viết xoay quanh JavaScript, khiến người dùng ngôn ngữ khác gặp rào cản gia nhập cao
  • Vấn đề hiệu năng: các lệnh gọi DOM đi qua binding JS bị chậm hơn 45% so với gọi trực tiếp
    • Trong thử nghiệm với framework Dodrio, khi bỏ JS glue thì thời gian áp dụng thay đổi DOM giảm còn một nửa
  • Sự phụ thuộc vào JavaScript: để dùng WebAssembly trong thực tế, cuối cùng vẫn phải hiểu JS, dẫn đến vấn đề abstraction bị rò rỉ (leaky abstraction)

Sự xuất hiện của WebAssembly Component Model

  • WebAssembly Component Model định nghĩa đơn vị thực thi chuẩn hóa có thể dùng chung giữa nhiều ngôn ngữ và runtime
    • Có thể trực tiếp thực hiện việc truy cập Web API, tải mô-đun và liên kết mà không cần JS
    • Có thể được tạo từ nhiều ngôn ngữ khác nhau và được hỗ trợ thực thi trên nhiều runtime như trình duyệt hay Wasmtime
  • Thông qua WIT (Interface Description Language), có thể khai báo API cần dùng và gọi trực tiếp từ bên trong component
    • Ví dụ:
      component {
        import std:web/console;
      }
      
      → Có thể gọi console::log("hello, world") trong mã Rust
  • Trình duyệt có thể tải component trực tiếp bằng <script type="module" src="component.wasm"></script>, và tự động xử lý binding Web API mà không cần JS

Khả năng tương tác với JavaScript

  • Component Model cũng hỗ trợ cấu trúc ứng dụng hybrid
    • Ví dụ: viết bộ giải mã ảnh bằng WebAssembly, rồi gọi từ JS theo dạng import { Image } from "image-lib.wasm";
    • JS có thể dùng component WebAssembly như một mô-đun thông thường thông qua import/export

Triển vọng và cách tham gia

  • Mozilla đang hợp tác với WebAssembly CG để chuẩn hóa Component Model, và Google cũng đang ở giai đoạn xem xét
  • Lập trình viên có thể thử nghiệm trên trình duyệt hoặc CLI thông qua Jco hay Wasmtime
  • Nếu mô hình này được phổ biến, WebAssembly có thể mở rộng từ “tính năng dành cho power user” thành công nghệ web mà cả lập trình viên phổ thông cũng có thể sử dụng

4 bình luận

 
jeeeyul 2026-03-12

Đây gần như chỉ là kiểu kỳ vọng mang màu sắc Mozilla mà thôi. Frontend về mặt cấu trúc không thể thoát khỏi hệ viền của phản ứng thị trường. Ngay khi WebAssembly xuất hiện thì Doom 3 đã được port sang rồi. DOM trong các trình duyệt hiện đại từ lâu đã chuyển thành các đối tượng proxy nhẹ, và nếu xét đến tập lệnh chuyên dụng cho JavaScript của CPU hiện đại cùng giới hạn lượng tử của lõi đơn, thì cách tiếp cận này sẽ không bao giờ giành được ưu thế về giá trị thị trường.

Một binary WebAssembly chạy bên trong Electron thì có ý nghĩa gì? Cái này chỉ giống thêm một cuộc săn danh tiếng kiểu GitKraken CLI hoặc port sang Rust mà thôi.

 
carnoxen 2026-03-14

Không nói về những thứ khác, nhưng cách nhúng module wasm dưới dạng tệp như &lt;script type=&quot;module&quot; src=&quot;/module.wasm&quot;&gt;&lt;/script&gt; thì khá hấp dẫn đấy.

 
jeeeyul 2026-03-12

Và cũng phải nói cho rõ rằng những lập luận cho rằng WebAssembly có rào cản gia nhập cao là rất vô lý. Chỉ đơn giản là mức độ cần thiết của việc đó thấp hơn mức sẵn sàng chi trả mà thôi. Muốn vừa nhanh vừa có footprint thấp, nhưng vẫn muốn dùng DOM và CSS ư? Đây là kiểu hài đen gì vậy.

 
GN⁺ 2026-03-12
Ý kiến trên Hacker News
  • Có cảm giác tất cả chuyện này lẽ ra đã có thể làm được từ nửa thập kỷ trước
    Thật đáng tiếc khi họ từ bỏ mục tiêu ban đầu là hỗ trợ WebIDL trong WebAssembly, rồi lại quyết định tạo ra một IDL khác, trong khi không coi việc thiếu truy cập DOM là vấn đề
    Dĩ nhiên tôi hiểu thực tế thị trường, nhưng vẫn không thể xua đi cảm giác tiếc nuối vì thời gian đã mất
    Tham khảo liên quan: lịch sử commit, hồi tưởng về stringref, bài viết trên ACM
    • Trước đây tôi từng tham gia làm đề xuất interface-types
      Sau đó có thêm hai mục tiêu nữa: một là hỗ trợ API ngoài web, hai là khả năng tương tác giữa các ngôn ngữ
      WebIDL là hợp của JS và Web API nên có sức biểu đạt cao, nhưng lại có nhiều khái niệm xung đột với các mục tiêu đó
      Vì vậy component interface đã chọn cách tiếp cận là phần giao nhau có tính di động cao hơn nhiều, dù sức biểu đạt giảm đi
      Cá nhân tôi nghĩ truy cập DOM là quan trọng, nhưng Wasm CG đã bận với những việc có ưu tiên cao hơn
      Lý do tôi viết bài này là muốn cho mọi người biết rằng chúng tôi vẫn nhớ tới vấn đề này và dự định sẽ tiếp tục làm
    • Tôi thật sự mong stringref sẽ quay trở lại
  • Rào cản gia nhập của WASM thực sự rất lớn
    Toolchain và quy trình build quá phức tạp, nên mỗi lần dùng tôi đều cảm thấy gánh nặng nhận thức
    Hiệu năng tốt hơn nhiều khi không có glue, nhưng đồng thời rủi ro cũng lớn hơn tương ứng
    Tôi hy vọng component model sẽ không đưa thêm độ phức tạp mới, nhưng nhìn các ví dụ đa ngôn ngữ thì có vẻ đã khá rối rồi
    Đặc biệt khi xem ví dụ Go, có quá nhiều file được sinh ra, và từ góc độ lập trình viên thì việc đơn giản hóa tooling là cực kỳ cấp thiết
    Hiện giờ trông không giống như đang loại bỏ độ phức tạp, mà chỉ là chuyển nó sang chỗ khác
    • Tôi thừa nhận tooling vẫn còn ở giai đoạn đầu
      Đặc tả wasm component liên tục thay đổi nên có rất nhiều churn
      Mục tiêu là để lập trình viên web không phải tự viết WIT, mà có thể dùng Web API như một thư viện
      Nhưng hiện tại vẫn còn rất nhiều việc phải làm
  • Sự phát triển của WebAssembly component rất ấn tượng, nhưng tôi có cảm giác đang bỏ lỡ cơ hội tách Web API thành các đơn vị chuẩn nhỏ hơn
    Ví dụ có thể chia thành chia sẻ văn bản, chia sẻ media, chia sẻ ứng dụng... như vậy bảo mật cũng tốt hơn và các nhóm nhỏ cũng có thể tạo ra lựa chọn thay thế cho trình duyệt
    Nhưng quy mô khổng lồ của Web API và CSS là thứ đang nâng đỡ thế độc quyền của trình duyệt, nên có lẽ những thử nghiệm như vậy sẽ khó thành hiện thực
    Sẽ rất tốt nếu có thể chuẩn hóa một WebAssembly registry để các component dễ dàng được ghép nối với nhau
    Rốt cuộc web là quá trình tạo ra định nghĩa của một hệ điều hành phân tán
  • Nếu muốn học WebAssembly hiện đại, tôi khuyên đọc Component Model Book
    Từ khái niệm đến ví dụ mã đều được sắp xếp rất tốt
    Trong hệ sinh thái JS, ba dự án cốt lõi là StarlingMonkey, ComponentizeJS, jco
    Hiện tại toolchain trưởng thành nhất là Rust, nhưng hỗ trợ cho các ngôn ngữ dựa trên LLVM (C/C++, Go, Python...) cũng đang dần tốt lên
    Mục tiêu của WebAssembly là trở thành một đích biên dịch hòa nhập tự nhiên vào toolchain cục bộ
  • Lý do cách diễn đạt “first-class” quan trọng là vì phần lớn lập trình viên từ bỏ một nền tảng do ma sát (friction) chứ không phải do hiệu năng
    Nếu vẫn phải hiểu glue code theo từng ngôn ngữ hay phải nắm hai mô hình runtime, thì WebAssembly vẫn sẽ chỉ là “một công cụ chỉ dùng trong tình huống cực đoan”
    Muốn tạo ra thay đổi thật sự thì phải đơn giản hóa con đường build thông thường
  • Web không thể vận hành nếu thiếu phát hiện tính năng động
    Chưa rõ phần này được xử lý như thế nào trong Component Model
    DOM khác nhau giữa các trình duyệt, và tính năng cũng thay đổi theo từng lần tải trang
    Ở lớp JS bridge thì có thể dễ dàng áp dụng polyfill, nhưng với giao diện WIT thì việc phát hiện method lúc runtime hay polyfill lại rất khó
    Ngoài hiệu năng, tính linh hoạt của hệ sinh thái cũng quan trọng
  • Bài viết này diễn tả rất đúng sự bức bối của “bức tường WebAssembly
    Việc phải tự quản lý glue code JS hoặc dựa vào công cụ sinh tự động khiến nó giống như một bước lùi lớn
    Việc thí nghiệm Dodrio bỏ qua glue và đạt giảm 45% overhead là rất ấn tượng
    Tuy vậy tôi vẫn tò mò việc quản lý bộ nhớ sẽ diễn ra thế nào khi WebAssembly Component Model tương tác trực tiếp với Web API
    Tôi muốn biết liệu đề xuất Wasm GC có được dùng để giữ tham chiếu DOM hay vẫn còn phụ thuộc vào JS GC
    Tôi mong Wasm thật sự trở thành một công dân hạng nhất
    • Gần đây tôi tự hỏi liệu các cải tiến sendMessage của v8 và Bun có thể làm dịu vấn đề này không
      Nhưng hiện tại IPC vẫn còn kém hiệu quả, và tôi nghĩ cần những cách như truyền theo đơn vị trang bộ nhớ
    • Có ý kiến chỉ ra rằng các bình luận phía trên trông như do LLM viết, nên có thể vi phạm quy định của HN (hướng dẫn)
  • Web từng là một chuỗi thử nghiệm đầy thú vị
    Việc cho phép bất kỳ ai chạy những chương trình phức tạp trên máy tính của tôi là một ý tưởng điên rồ về mặt bảo mật, nhưng thực tế chúng ta đã làm vậy
    Nhờ JS mà trong 20 năm qua chúng ta đã trải qua vô số lỗi bảo mật trình duyệt, nhưng giờ đây các nguyên tắc thiết kế và biện pháp giảm thiểu đã được định hình
    Thế mà giờ lại định thay nó bằng một mô hình thực thi nguy hiểm khác, điều đó vừa mỉa mai vừa đẹp theo cách nào đó
    • Thực ra đây là việc hệ điều hành (OS) nên làm
      OS di động làm điều đó tốt hơn desktop rất nhiều
    • Thứ gây ra phần lớn vấn đề bảo mật không phải JS mà là API của trình duyệt
    • Không có gì bị “thay thế”, chỉ là đang được mở rộng thôi
    • Tôi tò mò vì sao WASM lại nguy hiểm hơn JS
    • Vấn đề nằm ở những tính năng phá vỡ sandbox như WebUSB, chứ bản thân wasm thì không như vậy
  • Các tiêu chuẩn mới dạo này dường như ưu tiên JS boilerplate phức tạp hơn là sự đơn giản
    Chúng được thiết kế thiên về góc nhìn kỹ sư, và không có workflow mặc định thân thiện với người viết ứng dụng
    Dù vậy vẫn đáng mừng khi còn có những người quan tâm đến các vấn đề này
  • Cá nhân tôi vẫn nghĩ đây không phải là một ý tưởng hay (thảo luận trước đó)
    Nó giống như đang làm quá nhiều kỹ thuật chỉ để có xử lý chuỗi nhanh gấp đôi nhằm ánh xạ DOM API theo kiểu 1:1
    Với các API như WebGL2, WebGPU, WebAudio thì chi phí của JS shim vốn đã rất nhỏ
    Vấn đề thực sự là những chỗ như sao chép buffer GPU, mà component model không giúp được gì ở đó
    Tôi muốn xem benchmark thử nghiệm hàng chục nghìn draw call trên WebGL2 hay WebGPU
    • Trong một số trường hợp sẽ không có cải thiện lớn, nhưng hiệu năng DOM vẫn là nút thắt của nhiều ứng dụng
      Ngoài hiệu năng ra, việc cải thiện trải nghiệm lập trình viên (DX) cũng rất quan trọng
      Hiện giờ việc bắt đầu quá khó, và ai cũng phải trở thành chuyên gia thì mới tận dụng được lợi ích
    • Không chỉ là xử lý chuỗi nhanh gấp đôi, mà lợi ích lớn nhất là không cần glue code
    • WebAssembly có thể trở thành một lựa chọn thay thế cho tính đóng kín của OS di động
      Nếu có thể cạnh tranh với hiệu quả ở mức ứng dụng native, đây sẽ là một thay đổi có tầm nhìn cho tương lai của web
    • Chỉ cần tăng tốc truy cập DOM thôi cũng đã đủ có ý nghĩa lớn
    • component model trông giống như tự tạo thêm việc không cần thiết cho chính mình
      Trong thời đại coding agent, những cải thiện DX mà họ nói tới không còn quan trọng nữa