- Từ Firefox 148, tối ưu hóa asm.js của SpiderMonkey đã bị tắt theo mặc định và phần mã liên quan sẽ bị loại bỏ trong các bản phát hành tới
- asm.js là một tập con của JavaScript nên các trang hiện có vẫn tiếp tục hoạt động, nhưng sẽ chạy theo luồng JIT thông thường nên lợi ích tối ưu hóa sẽ biến mất
- Nội dung asm.js có thể được biên dịch lại sang WebAssembly để có tốc độ thực thi nhanh hơn và tệp nhị phân nhỏ hơn
- asm.js đã cho phép thực thi gần mức native bên trong nội dung web mà không cần sandbox riêng hay API thay thế để đối đầu với NaCl·PNaCl
- OdinMonkey được đưa vào Firefox 22 năm 2013 đã giúp triển khai các dự án C/C++ như Unity và Unreal lên web, đồng thời trở thành nền tảng dẫn tới WebAssembly
Tắt tối ưu hóa asm.js
- Từ Firefox 148, tối ưu hóa asm.js của SpiderMonkey đã bị tắt theo mặc định và toàn bộ mã liên quan sẽ bị loại bỏ trong các bản phát hành tương lai
- Các trang sử dụng asm.js vẫn sẽ tiếp tục hoạt động
- asm.js là một tập con của JavaScript thông thường, nên mã hiện có sẽ chạy theo luồng JIT thông thường như các script khác
- Tuy vậy, lợi ích của các tối ưu hóa chuyên biệt cho asm.js sẽ không còn
- Nếu bạn vẫn đang phân phối nội dung asm.js, khuyến nghị nên biên dịch lại sang WebAssembly
- Biên dịch lại sang WebAssembly có thể mang lại tốc độ thực thi nhanh hơn và tệp nhị phân nhỏ hơn
- Pipeline WebAssembly của SpiderMonkey đã phát triển vượt xa pipeline asm.js
- Khi WebAssembly đã thành công và phần lớn việc sử dụng asm.js đã được chuyển đổi, chi phí duy trì đồng thời cả hai con đường trở nên quá lớn
- Vẫn liên tục cần thời gian bảo trì
- Để lại thêm bề mặt tấn công trong VM
Vai trò của asm.js và sự kết thúc của OdinMonkey
- asm.js là câu trả lời của Mozilla cho câu hỏi mà NaCl và PNaCl đặt ra: “liệu có thể chạy mã với tốc độ native trên web hay không”
- Cách tiếp cận là chọn một tập con JavaScript nghiêm ngặt, được định kiểu tĩnh, mà engine có thể nhận diện ngay lập tức rồi biên dịch thành mã native
- Có thể ở lại bên trong nội dung web và dùng các Web API hiện có mà không cần sandbox riêng, IPC hay API thay thế
- asm.js được đưa vào Firefox 22 năm 2013, cho phép các dự án như Unity và Unreal triển khai codebase C/C++ lên web chỉ bằng các công nghệ web tiêu chuẩn
- Trình biên dịch asm.js có tên là OdinMonkey, và quá trình loại bỏ đang được theo dõi trong bug Ragnarök với tên “Twilight of OdinMonkey”
- BaldrMonkey sinh ra từ OdinMonkey là trình biên dịch tối ưu hóa cho WebAssembly
- RabaldrMonkey là trình biên dịch baseline cho WebAssembly
- OdinMonkey đang bước vào giai đoạn kết thúc sau 13 năm hoàn thành vai trò của mình
1 bình luận
Ý kiến Hacker News
asm.js là câu trả lời của Mozilla cho câu hỏi mà NaCl và PNaCl đặt ra: “Làm sao chạy code với tốc độ native trên web?”
Nếu là bây giờ thì có lẽ Chrome đã cứ thế thúc đẩy NaCl và PNaCl, rồi mọi người sẽ than phiền vì sao Safari và Firefox lại không theo kịp tiêu chuẩn “web”
Có một thời gian tôi thật sự nghĩ rằng rồi chúng ta sẽ làm mọi thứ trong trình duyệt. Theo một nghĩa nào đó thì đúng là đang dần thành như vậy, nhưng cảm nhận tổng thể thì tệ hơn bao giờ hết. Tôi thích WASM và muốn tiếp tục thích nó, nhưng tốc độ trưởng thành của hệ sinh thái thì tệ đến mức khó tin.
Tệ hơn nữa là giờ ta phải chạy các công cụ AI không đáng tin cùng đầu ra của chúng ngay trong chính các sandbox đó, trong khi các công ty lại đang bán sandbox được host và VM nền JS được host, tức là đi ngược hoàn toàn.
Cuối cùng thì vấn đề dường như lúc nào cũng vậy. Không có tiền ở phía sandbox phía client.
Về nội bộ thì nó hữu ích để sandbox Flash player, nhưng những giới hạn của cách tiếp cận dựa trên LLVM nhanh chóng trở nên rõ ràng với tất cả những người liên quan.
Nếu tôi nhớ không nhầm thì lý do lớn khiến nó thất bại là NaCl là công nghệ quá “lớn”, còn asm.js lại quá “nhỏ”, nên dù asm.js khởi đầu muộn hơn vài năm, nó vẫn đạt mức sẵn sàng cho production trước.
Nhưng Apple có vẻ đã tăng đầu tư vào WebKit trong thập kỷ này sau khi áp lực quản lý bắt đầu nóng lên, nên nếu là ngày nay thì kết quả có thể đã khác.
Vì thế khi đó ít bị than phiền hơn, còn bây giờ người ta phàn nàn về những thứ Safari không làm vì chúng bị xem là có hại cho App Store. May là EU giờ đang cố chỉnh Apple lại phần nào.
Buồn thì buồn nhưng cũng dễ hiểu. Một chi tiết thú vị là Figma ban đầu khởi đầu với codebase C++ hoàn chỉnh, và asm.js là yếu tố then chốt chứng minh rằng có thể chạy công cụ thiết kế trong trình duyệt.
Họ chỉ chuyển sang WebAssembly sau khi đã có khách hàng trả tiền, và mức cải thiện thời gian tải cũng khá lớn. asm.js vẫn là JS nên bundle nặng hơn và code phải được parse thành AST, còn WASM thì không.
Cũng giống như buồn vì i386-unknown-freebsd1 không còn được hỗ trợ nữa.
Vậy là cái chết của asm.js cuối cùng đã đến sao? Chúng ta đang rời xa dòng thời gian của lời tiên tri.
https://www.destroyallsoftware.com/talks/the-birth-and-death...
Nếu bạn chưa xem thì cực kỳ khuyến nghị. Tùy định nghĩa “hay nhất”, đây có thể là bài thuyết trình công nghệ hay nhất từng có.
Một ngày nào đó, sau khi đi qua thời chiến và thoát khỏi sự ám ảnh tâm lý với các mô hình lập trình cũ kỹ, chúng ta có thể chuyển sang những cách tiến bộ hơn. Tất nhiên điều đó không có nghĩa ngân hàng của bạn sẽ ngừng chạy YavaScript trong ít nhất 85 năm tới.
Tôi sẽ không bao giờ quên lúc xem bài nói về JavaScript của Gary Bernhardt.[0] Đó là lần đầu tôi biết đến asm.js, và cũng là lúc rơi xuống hố thỏ của việc biên dịch code để chạy trong trình duyệt.
Giờ đã 12 năm trôi qua, thật đáng ngạc nhiên khi bao nhiêu phần trong câu chuyện hư cấu của ông ấy đã trở thành hiện thực.
[0] https://www.destroyallsoftware.com/talks/the-birth-and-death...
Lúc xem bài đó lần đầu tôi còn là thực tập sinh, và công ty đã tự làm toàn bộ compiler, IDE và debugger cho một hộp IO công nghiệp nhỏ. Compiler được viết bằng C, rồi chuyển sang JS bằng Emscripten, sau đó được “biên dịch” cùng phần IDE và debugger thành một file HTML khổng lồ, thực chất là nối lại với nhau. Việc upload code và debug diễn ra qua Ethernet, và mọi thứ được đẩy bằng Ajax.
Nghe như một kiến trúc bị nguyền rủa, nhưng khách hàng lại thích. Vì nó không phải EXE nên không bị các bộ lọc IT doanh nghiệp quá tay của khách hàng chặn. Thế nên chúng tôi không chuyển sang Electron. Theo một nghĩa nào đó, nó đã có những yếu tố nguyên thủy của thick app.
Từ lâu tôi từng viết một chương nhỏ về asm.js trong một cuốn sách về WebGL.
https://webglinsights.github.io/
Chứng kiến sự trỗi dậy của asm.js, tiền thân của WebAssembly, là một điều thú vị. Trong những demo đầu tiên có những thứ thực sự ấn tượng, như Unreal Engine chạy trong trình duyệt. Nhìn nó lặn xuống ở đây thì hơi chua xót, nhưng nó đã mở đường cho những thứ tốt hơn rất nhiều.
Có lẽ chúng ta sẽ cần một transpiler từ asm.js sang WASM.
Việc biên dịch code legacy bằng các phiên bản Emscripten cũ khá là bực bội. Đôi khi còn khổ chẳng kém việc phải cập nhật code JS để theo các thay đổi ABI tích lũy của Emscripten.
Ít nhất thì code asm.js vẫn sẽ chạy ngay cả khi tối ưu hóa asm.js bị tắt, nhưng có bộ chuyển đổi thì vẫn tốt hơn.
asm.js đã chết! WebAssembly muôn năm!
Cá nhân tôi thấy quyết định này là một sai lầm. Dù vậy tôi không biết tác động thực tế sẽ lớn đến đâu. Theo tôi biết thì giờ cũng không còn nhiều người dùng asm.js.
Nhưng wasm quá tách biệt khỏi JavaScript. Sau khi thử dùng ở mức hạn chế, tôi đã nghĩ hay là cứ biên dịch sang asm.js cho rồi.
Tôi cũng không chắc Emscripten còn hỗ trợ đầy đủ hay không.
Trên wasm, phần lớn web API đều không gọi được.
Quan trọng hơn với công việc tôi định làm là từ JS không thể chuyển buffer zero-copy vào wasm.
Mọi thứ đều là đánh đổi. Sự tách biệt là ưu điểm, nhưng cũng là nhược điểm.
Trong khi đó wasm ngày nay đã có GC types và còn có thể giữ các giá trị JS bằng externref.
asm.js có lẽ cũng không làm được zero-copy buffer. Bên wasm có một proposal cho zero-copy buffer: https://github.com/WebAssembly/memory-control/blob/main/prop...
Ngay cả với asm.js nghiêm ngặt thì cũng không thể gọi trực tiếp phần lớn web API. Nó chỉ hỗ trợ số, không hỗ trợ chuỗi JS hay object, và quản lý heap C bên trong một đối tượng ArrayBuffer giống như WASM.
Zero-copy buffer cũng vướng cùng vấn đề. Trong asm.js, bạn phải thoát ra “JavaScript thật” để gọi, và cũng không thể map trực tiếp một ArrayBuffer khác vào heap asm.js, nên cần copy. “JavaScript FFI” thực ra không khác nhiều giữa asm.js và WASM.
Tôi nhớ khi Mozilla công bố OdinMonkey, thứ được tối ưu hóa cực mạnh riêng cho code asm.js. Còn đội Chrome/V8 thì tập trung vào tối ưu JIT mang tính tổng quát hơn để chạy JavaScript nói chung nhanh hơn, đồng thời cũng có lợi cho asm.js.
Chênh lệch tốc độ khi đó nghiêng về Firefox từ 2 đến 4 lần, và họ quảng bá điều đó khá mạnh :D
Ngày nay hầu hết VM JavaScript của các trình duyệt đã hội tụ về thiết kế và tối ưu khá giống nhau, nên ngay cả không có Odin thì code asm.js vẫn sẽ chạy khá nhanh thôi.
Kế hoạch của tôi về việc tạo code JS lúc runtime để làm thuật toán chạy nhanh hơn coi như xong. Làm điều này bằng wasm có vẻ khó hơn nhiều.
Có một thư viện nhỏ xử lý khá nhiều việc như thế để phục vụ test: https://searchfox.org/firefox-main/source/js/src/jit-test/li...
Còn trong JS thì có lẽ sẽ dùng https://www.npmjs.com/package/binaryen
https://www.assemblyscript.org/
Chỉ là nó sẽ không được parse hay thực thi nhanh như khi có pipeline chuyên biệt cho asm.js. Trừ khi là ứng dụng cực lớn, tôi nghĩ bạn sẽ khó nhận ra khác biệt lớn.