Ở thời điểm 28/02/2017 tất cả 4 trình duyệt chính đạt được thống nhất về phiên bản MVP của WebAssembly. Giúp các trình duyệt có thể release phiên bản ổn định đầu tiên của WebAssembly.

Bộ core này không bao gồm đầy đủ tính năng mà nhóm phát triển đã lên kế hoạch, nhưng nó đủ để WebAssembly có thể hoạt động nhanh và ổn định.

Nhờ đó lập tình viên đã có thể code web bằng WebAssembly. Với những phiên bản cũ của trình duyệt, lập trình viên có thể sử dụng file asm.js thay thế. Vì asm.js bản chất là một tập nhỏ của Javascript, bất kì JS engine nào cũng có thể chạy nó. Với Emscripten, bạn có thể lựa chọn biên dịch ra asm.js hoặc WebAssembly.

Kể cả với phiên bản đầu tiên, WebAssembly cũng chứng minh là nó có thể chạy nhanh. Nhưng nó còn có thể nhanh hơn trong tương lai gần, thông qua một vài chỉnh sửa và cập nhật tính năng mới.

Cải thiện hiệu năng WebAssembly trong trình duyệt

Một vài cải thiện hiệu năng có thể đơn giản đến từ việc các đơn vị xuất trình duyệt hỗ trợ đầy đủ hơn cho WebAssembly trong JS engine của họ. Các đơn vị này một cách độc lập đang từng bước cải thiện hoạt động của engine trong các phiên bản cập nhật trình duyệt.

Gọi hàm nhanh hơn giữa JS và WebAssembly

Hiên tại, việc gọi hàm WebAssembly từ JS đang chậm hơn cần thiết. Lý do là bởi vì nó cần thực hiện thao tác gọi là “trampolining”. JIT không biết phải xử lý trực tiếp với WebAssembly như thế nào, nên nó cần route lệnh gọi hàm tới chỗ nào đó biết cách xử lý. Đây vấn đề của bản thân engine – bộ phận đáng lẽ đảm nhận việc tối ưu code WebAssembly.

Person jumping from JS on to a trampoline setup function to get to WebAssembly

“Trampolining” có thể chậm hơn 100x so với khi JIT biết cách xử lý lệnh gọi hàm WebAssembly một cách trực tiếp.

Người dùng có thể không nhận thấy vấn đề khi JS chỉ gọi một task lớn của WebAssembly một vài lần. Nhưng nếu WebAssembly và JS gọi đi gọi lại nhau nhiều lần trong code (ví dụ với các task nhỏ), thì ảnh hưởng có thể sẽ xuất hiện rõ ràng.

Load nhanh hơn

JIT phải cân bằng giữa thời gian load và thời gian thực thi JS. Nếu dành nhiều thời gian hơn để biên dịch và tối ưu code, thời gian thực thi sẽ nhanh hơn, nhưng thời gian khởi động lại chậm hơn.

Các nhà phát triển trình duyệt đã đổ rất nhiều công sức để cân bằng quá trình dịch (đảm bảo một khi code được chạy nó sẽ không đến nỗi chậm), nhưng có điều cơ bản là hầu hết code sẽ không được thực thi đủ nhiều để có thể được đưa đi tối ưu.

Vì WebAssembly không cần phải phán đoán kiểu biến nào sẽ được sử dụng, engine không cần mất công quan sát kiểu biến lúc thực thi. Điều này giúp nó có nhiều lựa chọn hơn, ví dụ như tối ưu hóa song song với thực thi code.

Hơn nữa, một số bổ sung gần đây cho API của Javascript cho phép dịch WebAssembly  theo stream. Có nghĩa là engine có thể bắt đầu dịch ngay khi file vẫn đang được download.

Với Firefox, có hệ thống 2 trình dịch. Trình dịch đầu tiên sẽ dịch thô trước khi code thực thi, và nó làm khá tốt nhiệm vụ tối ưu code. Và khi code được thực thi, trình dịch còn lại sẽ thực hiện đầy đủ việc tối ưu trong tiến trình background. Phiên bản tối ưu đầy đủ sẽ được thay thế lại khi nó đã sẵn sàng.

Thêm cải tiến sau phiên bản MVP

Một trong những mục tiêu của WebAssembly là định nghĩa yêu cầu theo từng phần nhỏ và test dần trong khi thực hiên, chứ không phải xậy dựng đầy đủ mọi thứ ngay từ đầu.

Có nghĩa là có thể có rất nhiều tính năng được kì vọng, nhưng vấn chưa được bàn bạc thấu đáo 100%. Nó cần được thông qua quy trình định nghĩa yêu cầu, với sự tham gia của tất cả đơn vị sản xuất tình duyệt.

Sau đây là một vài ví dụ về những tính năng đang được đưa ra bàn thảo

Làm việc trực tiếp với DOM

Hiện nay không có cách nào để thao tác với DOM. Nghĩa là bạn không thể thực hiện thao tác như element.innerHTML  khi sử dụng WebAssembly.

Thay vào đó nó phải thông qua JS để set giá trị. Hoặc là nó phải gửi lại kết quả cho hàm JS, hoặc gọi hàm callback JS từ WebAssembly (WebAssembly  có thể import cả hàm của JS cũng như hàm của module WebAssembly khác).

Person reaching around from WebAssembly through JS to get to the DOM

Dù bằng cách nào nó cũng sẽ chậm hơn truy cập trực tiếp, một vài ứng dung của WebAssembly  sẽ không thể hiện thực nếu vấn đề này không được giải quyết.

Bộ nhớ chia sẻ cho các tiến trình chạy song song

Một trong những cách để tăng tốc độ xử lý là thực hiện những phần khác nhau của code song song cùng một lúc. Đôi khi nó có thể phản tác dụng do việc giao tiếp giữa các tiến tình có thể mất nhiều thời gian hơn việc thực hiện task.

Nhưng nếu bạn có thể chia sẻ bộ nhớ giữa các tiến trình, việc giao tiếp sẽ hiệu quả hơn. Để làm đc điều này WebAssembly có thể sử dụng tính năng mới của Javascript SharedArrayBuffer. Một khi tính năng này sẵn sàng trên tình duyệt, nhóm phát triển có thể tiếp tục xác định cách WebAssembly có thể sử dụng nó.

SIMD

Nếu bạn theo dõi thông tin về WebAssembly , bạn có thể đã nghe đến việc hỗ trợ SIMD – single instruction muliple data. Một cách native để chạy code song song.

SIMD có thể lấy một khối dữ liệu lớn, như một mảng của nhiều số, và áp dụng cùng một lệnh cho nhiều thành phần của dữ liệu cùng một lúc. Bằng cách này những ứng dụng nặng về tính toán phức tạp như game hay VR có thể được cải thiện một cách đáng kể.

Điều này có thể không quan trọng lắm với hầu hết các lập trình viên, nhưng nếu bạn làm game hay ứng dụng multimedia trên web, điều này sẽ rất có ý nghĩa.

Exception handling

Rất nhiều codebase trong các ngôn ngữ như C++ sử dụng exceptions. Tuy nhiên exceptions chưa phải là một phần trong đặc tả của WebAssembly.

Nếu bạn biên dịch code bằng Emscripten, nó sẽ giả lập xử lý exception ở level chương trình dịch. Cách này khá là chậm, bạn có thể sẽ muốn sử dụng flag DISABLE_EXCEPTION_CATCHING để tắt chức năng này đi.

Nếu exceptions được hỗ trợ bởi WebAssembly, việc giả lập sẽ không còn cần thiết nữa.

Một vài cải tiến giúp lập trình viên dễ tiếp cận hơn

Một số tính năng sẽ không làm cải thiện hiệu năng, nhưng sẽ giúp làm việc với WebAssembly dễ dàng hơn.

  • First-class source-level developer tools. Hiện tại debug WebAssembly trên trình duyệt giống như debug trực tiếp trên Assembly. Có không nhiều lập trình viên có thể map code của họ với source code WebAssembly tương ứng. Kì vọng rằng công cụ hỗ trợ có thể cải thiện đến mức giúp lập trinh viên debug dựa trên source code gốc
  • Garbage collection. Nếu bạn có thể định nghĩa kiểu biến cố định trong code, thì bạn có thể dịch source code sang WebAssembly. Thế nên code được viết bới tool như Typescript có thể được biên dịch sang WebAssembly. Trở ngại lớn nhất hiện tại là WebAssembly không biết cách làm việc với garbage collectors. Ý tưởng ở đây là cho phép WebAssembly được sử dụng một vài tính năng ở level thấp của GC
  • ES6 Module integration. Trình duyệt hiện nay đang thêm tính năng load Javascript thông qua thẻ script. Khi tính năng này được hoàn thiện, thẻ tag có dạng như  <script src=url type="module"> có thể hoạt động ngay cả khi url được trỏ đến WebAssembly module.

Kết luận

WebAssembly hiện nay đã nhanh, với những tính năng mới đang trong giai đoạn phát triển và những cải thiện của trình duyệt, nó sẽ còn nhanh hơn nữa trong tương lai