3 điểm bởi GN⁺ 2024-10-11 | 1 bình luận | Chia sẻ qua WhatsApp
  • Wasm có thể được xem không phải như giao thức CGI mà là mô hình ứng dụng tiếp theo sẽ thay đổi đơn vị thực thi và cách triển khai của ứng dụng web, giống như cách cgi-bin từng làm
  • CGI, FastCGI, Rack/WSGI và serverless đều đã liên tục thiết kế lại cách xử lý yêu cầu và quản lý máy chủ, với mục tiêu chung là giúp việc xây dựng và duy trì ứng dụng hiệu năng cao trở nên dễ dàng hơn
  • Mô-đun Wasm chạy trong runtime của host, và thông qua bộ nhớ cô lập cùng snapshot có thể giữ trạng thái thực thi sạch đồng thời giảm chi phí khởi động
  • Việc thiếu native thread, không thể dùng JIT, chi phí sao chép dữ liệu, và sự non trẻ của Interface Types cùng module linking là những ràng buộc chính của mô hình thực thi máy chủ dựa trên Wasm
  • Khi hàm serverless và edge function kết hợp với môi trường thực thi Wasm, có thể giảm chi phí cold start và cô lập, đồng thời kết hợp các mô-đun đa ngôn ngữ nhẹ nhàng hơn

Mô hình ứng dụng web từ CGI đến serverless

  • Cốt lõi của CGI không nằm ở chính giao thức Common Gateway Interface mà ở mô hình ứng dụng gọi script hay file thực thi đặt trong thư mục cgi-bin bằng URL
  • Cách này là mô hình ứng dụng web thời kỳ đầu, biến web từ kho lưu trữ tài liệu thành mạng lưới ứng dụng có khả năng tương tác
  • Vì cấu trúc chạy một tiến trình mới cho mỗi yêu cầu, theo tiêu chuẩn ngày nay chi phí khởi động tiến trình và phân tích script trở thành nút thắt lớn

FastCGI và sự thay đổi của web server theo từng ngôn ngữ

  • FastCGI đưa vào mô hình trong đó các tiến trình sống lâu xử lý yêu cầu CGI để giảm vấn đề hiệu năng của CGI
    • Web server không khởi chạy tiến trình mới cho mỗi yêu cầu mà giao tiếp với một hoặc nhiều tiến trình chạy dài hạn
    • Các ứng dụng CGI cũ được tạo ra với giả định tiến trình sẽ kết thúc sau yêu cầu, nên trong môi trường chạy dài hạn rất dễ phát sinh rò rỉ tài nguyên
  • Sau đó, web server theo ngôn ngữ trở thành thông lệ, và ứng dụng được xây dựng xoay quanh mô hình request/response
    • Cách phổ biến là đặt phía sau các web server giàu tính năng và đã được kiểm chứng như Apache hoặc nginx, để tách ứng dụng khỏi các yêu cầu chậm và chi tiết HTTP
    • Việc triển khai server dùng nhiều chiến lược quản lý tiến trình khác nhau như fork theo từng yêu cầu, thread của OS hoặc ngôn ngữ, mô hình event hoặc reactor
  • Giao diện Rack của cộng đồng Ruby cũng ảnh hưởng đến đặc tả WSGI và application server Flask của Python
    • Nói đơn giản, request gồm phương thức HTTP, hashmap header, và chuỗi byte đầu vào hoặc stream
    • Response gồm mã trạng thái, đối tượng header, và chuỗi byte phản hồi hoặc stream

Autoscaling đám mây và sự đánh đổi của serverless

  • Trong mô hình dựa trên máy chủ vật lý hoặc máy chủ ảo, phải trực tiếp quản lý số lượng server đang chạy
    • Khi lưu lượng cao, application server có thể chậm lại
    • Khi lưu lượng thấp, nhiều máy tính có thể bị bỏ không
  • autoscaling trên đám mây cho phép điều chỉnh số lượng application server theo CPU, tải bộ nhớ hoặc khung giờ
    • Việc mở rộng thêm máy mới có thể mất 2~20 phút tùy ứng dụng và cấu hình
    • Việc mở rộng cũng phụ thuộc vào tài nguyên khả dụng của vùng cloud hosting
  • Serverless compute kết hợp Amazon LambdaAPI Gateway tạo ra mô hình quản lý hàm thay vì quản lý server
    • Bảo đảm một tiến trình duy nhất, CPU cô lập và bộ nhớ cô lập cho mỗi yêu cầu
    • Tiến trình có thể được tái sử dụng tối đa vài giờ nhưng sẽ bị tạm dừng hoặc loại bỏ nếu không dùng
    • AWS có thể scale up và scale down theo nhu cầu yêu cầu trong đơn vị vài giây
  • Serverless có những trade-off rõ ràng
    • Do chi phí tạo tiến trình mới, khi mở rộng theo số lượng yêu cầu đồng thời thì một số yêu cầu sẽ gặp cold start
    • Vì tiến trình có thể bị tạm dừng sau khi phản hồi, việc quản lý kết nối TCP bền vững giữa các yêu cầu trở nên khó khăn
    • API cơ sở dữ liệu dựa trên HTTP phổ biến trong mô hình serverless vì chịu được nhiều kết nối và dễ scale up/down cùng hàm
  • Đặc tính cung cấp CPU và bộ nhớ chuyên dụng cho mỗi yêu cầu vừa có thể là lợi thế vừa có thể là bất lợi tùy workload
    • Một số workload có thể giảm việc quản lý tài nguyên cũng như lo ngại về chi phí và mở rộng
    • Các workload khác có thể hiệu quả hơn khi một tiến trình đơn xử lý nhiều yêu cầu hoặc tận dụng batch/cache bằng bộ nhớ chia sẻ
    • Bài viết đưa ra cả trường hợp chuyển ứng dụng web dựa trên CMS sang serverless giúp giảm 90% chi phí và trường hợp chuyển dịch vụ phân tích sự kiện sang mô hình server-based cũng giúp giảm 90% chi phí

Mô hình thực thi Wasm trên máy chủ

  • Wasm ban đầu được phát triển để chạy mã hiệu năng cao trong trình duyệt, và cũng có liên hệ với những nỗ lực như asm.js
  • WebAssembly là định dạng lệnh nhị phân cho máy ảo stack-based, được thiết kế làm đích biên dịch di động cho nhiều ngôn ngữ lập trình
    • Cho phép triển khai ứng dụng client và server trên web
    • Được thiết kế để mã hóa thành định dạng nhị phân hiệu quả về kích thước và thời gian tải
    • Hướng tới thực thi gần tốc độ native bằng cách tận dụng các tính năng phần cứng chung trên nhiều nền tảng
  • Hiện nay có thể biên dịch nhiều ngôn ngữ thành lệnh Wasm để chạy cả trên trình duyệt lẫn máy chủ
  • Mô hình cô lập và bảo mật mà trình duyệt yêu cầu cũng hữu ích cho ứng dụng máy chủ
    • Có thể cô lập mã không đáng tin cậy dưới dạng nhẹ hơn nhiều so với VM hay container Docker
  • Các môi trường serverless dựa trên V8 như Node.js, Cloudflare Workers và Deno tận dụng năng lực thực thi Wasm tích lũy từ trình duyệt
  • Cũng tồn tại các môi trường native Wasm như Fastly, Shopify và Suborbital

Mô-đun, host, bộ nhớ và snapshot

  • Vì mô-đun Wasm là lệnh cho máy ảo nên cần runtime để thực thi
    • Runtime biên dịch Wasm thông thường sang kiến trúc cục bộ và cung cấp môi trường thực thi
    • Một số môi trường cung cấp giao diện tương tự POSIX API của hệ Linux
    • Một số môi trường chỉ cung cấp các hàm cụ thể của hệ host và cho chạy các hàm export của mô-đun
  • Chương trình WebAssembly được cấu thành theo đơn vị modules, và VM chạy mô-đun được gọi là host
    • Mô-đun là đơn vị triển khai, nạp và biên dịch
    • Tập hợp các định nghĩa về type, function, table, memory và global value
    • Có thể khai báo import và export, đồng thời cung cấp khởi tạo dưới dạng data segment, element segment và start function
  • “memories” của Wasm được biểu diễn bằng một mảng byte liên tục không ngắt quãng, do host cấp phát tại thời điểm khởi tạo instance
    • Mỗi mô-đun guest có được sự cô lập bộ nhớ
    • Bộ nhớ này hoạt động như RAM của máy ảo
    • Có thể được cung cấp rỗng hoặc được điền sẵn bằng data segment
  • Nhờ cách cô lập mô-đun, có thể tạm dừng mô-đun và lưu bộ nhớ của nó thành data segment
    • Đây là khái niệm tương tự snapshot máy ảo
    • Có thể khởi chạy nhiều bản sao của mô-đun đã tạm dừng
  • Wizer khởi tạo mô-đun Wasm, chạy hàm khởi tạo rồi ghi lại trạng thái instance để ghi lại Wasm binary
    • Khởi tạo trực tiếp trạng thái của global value
    • Ghi lại các vùng bộ nhớ khác 0
    • Xóa data segment hiện có và thay bằng data segment cho các vùng bộ nhớ đã được ghi lại
  • Cách làm này mang lại trạng thái thực thi sạch như tiến trình mới nhưng tránh được chi phí khởi động của tiến trình mới
    • Gần giống CGI nhưng không có nhược điểm của CGI
    • Theo cách diễn đạt hiện đại hơn, gần giống serverless không có cold start

Ràng buộc và lợi thế của Wasm

  • Theo cấu hình native, Wasm không có thread
    • Công việc blocking phải được chuyển sang phương thức host
    • Host có thể cung cấp wrapper đọc/ghi file hoặc giao diện mạng, tạm dừng mô-đun, hoặc cung cấp callback handler
    • Có thể xây dựng mô hình reactor hoặc blocking, nhưng trước khi thread proposal được áp dụng thì thiết kế môi trường thực thi vẫn chiếm tỷ trọng lớn
  • Vì lý do bảo mật, không cho phép tạo mã Wasm động nên không thể dùng JIT compilation
    • Không thể xử lý chính đoạn mã như địa chỉ trong runtime
    • Các môi trường thực thi như V8 hay CRuby vốn phụ thuộc hiệu năng vào JIT không thể chạy trong Wasm VM hoặc phải từ bỏ JIT
    • Đã có đề xuất cách tiếp cận “pre-jit” xuất runtime tối ưu cho script ở giai đoạn build, nhưng chưa được dùng rộng rãi
  • Vì giao diện cơ bản giữa mô-đun Wasm và host là bộ nhớ, việc di chuyển dữ liệu có thể cần sao chép
    • Có thể chia sẻ các khối bộ nhớ nhưng việc đó có khả thi hay được khuyến nghị hay không còn tùy mô hình bộ nhớ của runtime
    • Trong hầu hết runtime, giao tiếp zero-copy giữa mô-đun và thao tác I/O bị xem là khó khăn
    • Việc đưa dữ liệu streaming vào/ra mô-đun Wasm có thể chậm hơn so với xử lý tại host
  • Wasm VM mang lại khả năng kiểm soát cao về giới hạn sử dụng
    • Một số runtime có thể cưỡng chế giới hạn CPU bằng cách đếm số lệnh CPU như Wasmtime fuel concept
    • VM có thể giới hạn bộ nhớ và wall clock time
  • Interface Types và module linking có thể giảm kích thước mô-đun, cải thiện tốc độ I/O và khả năng sử dụng
    • Interface Types có thể dùng được nhưng vẫn chưa phải chuẩn đã được phê chuẩn
    • module linking có prototype hoạt động nhưng chưa có cách tiếp cận chuẩn
    • Wizer hiện có thể xung đột với module linking; đã có cách tiếp cận tùy biến để giải quyết nhưng chưa có bên thắng thế rõ ràng
    • Interface Types hướng tới việc cho phép các đối tượng trung lập ngôn ngữ đi qua ranh giới bộ nhớ Wasm mà không cần mã hóa/giải mã tốn kém
    • Cách phổ biến hiện nay là chép JSON vào và ra khỏi bộ nhớ
  • Mô-đun Wasm về cơ bản chỉ có thể truy cập những gì được cấp cho nó nên mô hình bảo mật nhỏ và rõ ràng
    • Chạy mã Wasm không đáng tin cậy nhìn chung khá an toàn
    • Bề mặt tấn công của VM nhỏ hơn Docker hay các mô hình cô lập khác
    • Vì chạy các lệnh đã được chuyển đổi trên phần cứng host nên vẫn có thể xảy ra tấn công timing, nhưng có biện pháp giảm thiểu
    • Cũng có thể biên dịch Wasm thành native binary, nhưng khi đó bề mặt tấn công lớn hơn

Edge function và thực thi hàm dựa trên Wasm

  • Nếu môi trường thực thi và công cụ phát triển Wasm được dùng rộng rãi, các ngôn ngữ script về lý thuyết cũng sẽ chịu áp lực phải trang bị runtime Wasm và cách preboot như Wizer
  • Về lý thuyết, ứng dụng có thể được tiếp tục từ bản sao snapshot cho mỗi yêu cầu và chạy nhanh hơn các mô hình hiện tại
  • CLI cục bộ cũng có thể được viết bằng Ruby rồi triển khai dưới dạng mô-đun Wasm đã snapshot và liên kết với runtime Ruby trên Wasm, để đạt thời gian khởi động gần với utility C++ và bị giới hạn chỉ hoạt động trong thư mục dự án
  • Thay đổi lớn đầu tiên là đưa hàm ra edge gần người dùng
    • Việc tính toán được thực hiện gần người dùng thay vì gần cơ sở dữ liệu
    • Vercel Edge Functions là ví dụ dựa trên V8 nhưng chia sẻ nhiều nguyên tắc tương tự
    • next-auth có thể kiểm soát quyền truy cập vào trang prerender dựa trên JWT login token
    • Có thể cung cấp nội dung cá nhân hóa động được cấu thành từ dữ liệu đã cache trên CDN
  • Một thay đổi khác là thay các hàm dựa trên tiến trình bằng các hàm dựa trên Wasm trong ứng dụng serverless
    • Suborbital cho phép trực tiếp tạo môi trường thực thi hàm dựa trên Wasm, đồng thời cung cấp cách chuỗi các hàm Wasm thành workflow
    • Nhiều nền tảng thực thi khuyến nghị một mô-đun đơn cho mỗi request và chưa tận dụng đầy đủ khả năng chia sẻ bộ nhớ hay gọi nhanh nhiều mô-đun
    • Nếu Interface Types được chuẩn hóa, có thể xuất hiện mô hình dữ liệu middleware tương tự Rack
  • Wasm cũng có thể chạy bên trong hàm Lambda
    • Có thể dùng phiên bản ứng dụng đã snapshot trên hạ tầng hiện có
    • Sự kết hợp này tuy thú vị nhưng được xem là kiểu pha trộn công nghệ cuối cùng có thể biến mất

Hướng đi của mô hình ứng dụng web tiếp theo

  • Wasm được trình bày như công nghệ có thể tăng hiệu năng, giúp bảo mật cấp tiến trình dễ dàng hơn, đồng thời giảm chi phí build và thực thi của các hàm serverless
  • Nó có thể chạy gần như mọi ngôn ngữ, và thông qua module linking cùng Interface Types có thể giảm mạnh độ trễ giữa các hàm
  • Luận điểm cốt lõi để xem Wasm là CGI mới là: khi các ràng buộc của hệ thống thay đổi, những điều trước đây không thể làm được sẽ trở nên khả thi

1 bình luận

 
GN⁺ 2024-10-11
Ý kiến trên Hacker News
  • Không rõ WASM khác gì so với các công nghệ cũ như Java Applet, ActiveX, Silverlight, Macromedia Flash
    Tôi tưởng chúng ta đã rút ra bài học về việc chạy mã biên dịch của bên thứ ba không đáng tin cậy trong trình duyệt, và nó trông giống một kiến trúc chuyển chi phí tính toán từ máy chủ sang client dưới danh nghĩa cải thiện trải nghiệm khách hàng

    • Java và Flash đã không giữ được lời hứa về một sandbox không thể bị phá vỡ có thể chạy mọi thứ một cách an toàn
      Các bản triển khai có nhiều lỗ hổng, cuối cùng về cơ bản không còn dùng được trong trình duyệt; còn các công nghệ khác thì có vẻ ngay từ đầu thậm chí đã không đưa ra lời hứa như vậy
      JavaScript thực sự đã giữ được lời hứa đó, và ngày nay trình duyệt chạy JavaScript tải xuống từ bất kỳ domain nào mà không hỏi người dùng có tin cậy hay không
      WASM nằm trên JavaScript engine và cung cấp bảo đảm bảo mật tương tự, nên về căn bản không khác JVM bytecode; khác biệt thực chất là WASM đã chứng minh được tính an toàn còn JVM thì không
      Giờ đây Google Chrome đủ an toàn để dù hàng tỷ người chạy WASM độc hại thì điện thoại cũng không bị xâm nhập, và có thể đưa engine này lên máy chủ để chạy script của nhiều người dùng trong sandbox mạnh, đồng thời chia sẻ tài nguyên
      Phương án thay thế là ảo hóa: hoặc biên dịch mã thành một khối WASM rồi chạy trên một máy chủ WASM lớn, hoặc đóng gói binary amd64 cùng một nhân Linux được cắt gọn rồi chạy trong VM
      Hiện chưa thể nói bên nào là người thắng rõ ràng, và mỗi cách tiếp cận đều có ưu nhược điểm
    • Khác với ActiveX, Silverlight và Flash, WASM là một tiêu chuẩn mở do nhiều bên trong ngành cùng xây dựng và cũng có nhiều bản triển khai, chỉ riêng điều đó đã tốt hơn các lựa chọn thay thế rất nhiều
      Khác với JVM, WASM cung cấp bộ nhớ tuyến tính và mặc định không có garbage collection, nên phù hợp hơn để làm đích biên dịch cho nhiều ngôn ngữ hơn, chẳng hạn biên dịch C/C++ bằng Emscripten hoặc nhắm tới Rust
      WASM là bytecode, và tôi cho rằng hầu hết các bản triển khai chia sẻ khá nhiều với JavaScript engine và runtime của host
      Việc dịch chuyển chi phí tính toán giữa client và server là một phần của xu hướng ngành đã qua lại từ lâu giữa client dày và client mỏng, và con lắc này sẽ còn tiếp tục dao động
    • Wasm có lợi thế lớn hơn các công nghệ cũ
      Có một đặc tả xác minh mà bytecode Wasm phải tuân theo, và nhờ tập con đã được xác minh này, nhiều lỗ hổng bảo mật từng thấy ở các công nghệ trước đây về cơ bản trở nên bất khả thi
      Các cuộc tấn công dựa vào lỗi phần cứng như Heartbleed hay Rowhammer có thể vẫn khả thi, nhưng chẳng hạn không thể lừa VM diễn giải một con số như con trỏ để tham chiếu ra ngoài vùng nhớ Wasm của chính nó
      Bytecode Wasm khá đơn giản để chuyển thành mã máy, nên bản triển khai có thể nhỏ và nhanh hơn so với dùng VM
      Nó không thuộc sở hữu của một công ty cụ thể, có đặc tả công khai được viết tốt mà ai cũng có thể dùng, và đã được chấp nhận làm tiêu chuẩn web nên không cần tiện ích mở rộng trình duyệt
      Tính toán phía client vốn đã diễn ra với JavaScript, và mã Wasm có thể hiệu quả theo những cách JavaScript không làm được, nên điều đó càng đúng hơn
    • Java Applet và ActiveX ít được trung gian hóa hơn trong việc truy cập hệ điều hành bên dưới
      Applet thì ở một mức độ nào đó, còn ActiveX thì gần như không hề; “nền tảng bên ngoài” của WASM đại khái là JavaScript runtime, trong khi nền tảng bên ngoài của Applet gần với execve(2) hơn
    • Bài viết này nói về WASM trên máy chủ, nên khác với chuyện chuyển chi phí tính toán từ server sang client
      WASM có thể làm vậy, nhưng không phải lúc nào cũng thế; các khác biệt như sandboxing và cô lập tốt hơn cũng đã được những câu trả lời khác đề cập kỹ
  • Nói “Amazon đã mở ra kỷ nguyên điện toán serverless với Lambda” thì Google App Engine đã ra mắt năm 2008, sớm hơn Lambda 6 năm

    • Còn có Heroku và thế hệ PaaS cùng thời
      Những sản phẩm như vậy đã tồn tại từ vài năm trước và cũng đã có tên gọi, nên tôi không rõ vì sao cái tên “serverless” lại xuất hiện, hay nó đến từ đâu
      App Engine cũng có batch worker và web worker, Heroku cũng vậy
      Cả hai đều là sản phẩm trước Docker nên có thể mọi người cảm nhận khác đi, nhưng tôi nghĩ Lambda ban đầu cũng không được ra mắt dựa trên Docker
  • Việc nói rằng “vì lý do bảo mật, không cho phép sinh mã Wasm động nên không thể biên dịch JIT” có vẻ không đúng
    Nếu muốn cho phép các tác vụ như hot reload mã sạch thì về bản chất nó gần như là một tính năng cốt lõi
    Tôi thấy lập luận bảo mật khá lỏng lẻo
    JS có thể hot reload khi đang chạy, hoặc thậm chí sinh mã mạnh tay hơn mà không phá vỡ bảo mật; cũng có thể mô phỏng việc sinh mã hoặc hot reload bằng cách tải lại động toàn bộ runtime Wasm trong khi vẫn giữ bộ nhớ, nhưng trải nghiệm người dùng sẽ thô vụng
    Tôi không thấy lý do kỹ thuật nào khiến việc đó phải là bất khả thi, và nếu đây là biện pháp bảo mật thì có vẻ quá dễ bị đi vòng
    Bytecode WASM về mặt khái niệm rất giống .NET IL hay bytecode Java, những thứ vốn được thiết kế với biên dịch JIT trong đầu
    Tôi không thích WASM lắm vì nó giống một dự án thiếu định hướng mạnh và thiếu ý chí để thành công đúng lúc
    Cái tên là “assembly cho web”, tức gợi ý mã máy cho một CPU ảo, nhưng thực tế lại là một biểu diễn trung gian cho backend của trình biên dịch; lại còn có kế hoạch cho các tính năng cấp cao như hỗ trợ garbage collection, nên khái niệm khá không rõ ràng
    Những tính năng cơ bản như hot reload đã nói ở trên, threading không quá giống hack, tích hợp trực tiếp với DOM mà không cần JavaScript, API đồ họa/tính toán overhead thấp, truy cập âm thanh cấp thấp cũng vẫn còn thiếu
    Khó mà chạy các ứng dụng multimedia lớn mà không phải đánh đổi nhiều

    • Câu đó đúng
      Wasm không thể đánh dấu bộ nhớ là có thể thực thi và trên thực tế tách riêng code và memory như kiến trúc Harvard
      Hơn nữa cũng không thể nhảy tới một vị trí tùy ý trong mã, và bản thân cũng không có lệnh jump
      Ở đây JIT nghĩa là biên dịch và thực thi mã native trong lúc chạy, điều này trong trình duyệt hoặc sandbox Wasm sẽ là một điểm yếu bảo mật lớn
      Điều này đã được gắn vào thiết kế và tập lệnh, nên không phải kiểu có thể dễ dàng đi vòng; có thể xem chi tiết tại https://webassembly.org/docs/security/
      Wasm cũng giống .NET IL hay bytecode Java ở chỗ engine đảm nhiệm JIT, nhưng việc trao cho người dùng quyền tạo mã native bên ngoài runtime rồi nhảy tới đó là nguy hiểm
    • Trình duyệt rõ ràng có dùng một dạng JIT nào đó cho WASM
      Vì vậy, giống JIT, khi chạy mã WASM lần đầu có thể thấy một chút “khựng lúc warm-up”, nhưng vài năm qua đã cải thiện hơn nhiều
      Ngoài ra, tôi hiểu là trong trình duyệt có thể tạo động một khối WASM, instantiate rồi chạy nó
      Tôi không biết các runtime WASM khác có làm được không, và trong trình duyệt thì vẫn phải đi qua JavaScript, nhưng dù sao muốn truy cập bất kỳ “web API” nào thì cũng cần như vậy
  • WASM là việc biến một VM chuyên cho một ngôn ngữ cụ thể như JavaScript VM thành một VM đa dụng có thể dùng ở mọi nơi JavaScript VM được dùng
    Tất nhiên nó không chỉ giới hạn ở đó
    “Đa dụng” nghĩa là chỉ cần có compiler hoặc interpreter thì gần như có thể chạy bất cứ thứ gì, bao gồm cả JavaScript
    Vì phần lớn được triển khai như một phần của JavaScript engine, nó thừa hưởng nhiều đặc tính như sandboxing và quyền truy cập các API tương ứng
    Việc chuẩn hóa cách truy cập đó vẫn đang diễn ra, nhưng cuối cùng những việc hiện chỉ làm được bằng JavaScript sẽ làm được bằng WASM, và còn nhiều việc vốn khó hoặc không thể làm bằng JavaScript cũng sẽ khả thi
    Nó cũng có thể chạy nhanh và mượt hơn
    Cốt lõi của WASM là loại bỏ nhiều hạn chế trong môi trường nơi JavaScript đang phổ biến
    JavaScript là một ngôn ngữ gây nhiều yêu ghét, nên từ lựa chọn duy nhất nó sẽ trở thành một trong nhiều lựa chọn
    WASM từng được mô tả là thứ thay thế JavaScript, thay thế Docker, thay thế Java, thay thế CGI; nói ngắn gọn thì nó là tất cả những điều đó và còn hơn thế nữa

    • Bản thân JavaScript thì tôi không phàn nàn, nhưng tôi cho rằng hệ sinh thái triển khai JS lên web mới là vấn đề
      Có quá nhiều công cụ làm những việc tương tự và ranh giới không rõ ràng
      Cuối cùng dù làm cho mọi thứ chạy được, cá nhân tôi vẫn thấy nó mong manh, và với người không làm chuyên nghiệp thì khá đáng sợ
      Dạo này khi cần làm gì đó cho web tôi dùng leptos; trải nghiệm lập trình viên tốt hơn nhiều, và dù còn chưa tới 1.x, nó vẫn tạo cảm giác ổn định hơn việc nối 5 công cụ lại để transpile, obfuscate, minify và pack bundle JS
  • Bài này làm tôi nhớ đến một định luật phần mềm từng được nhắc khá nhiều trước đây
    Một ứng dụng đủ lớn và sống đủ lâu cuối cùng sẽ tái triển khai toàn bộ software stack mà nó chạy trên đó, thậm chí cả hệ điều hành, và sẽ tái triển khai một cách tệ hại
    Tôi không rõ nguồn, nhưng nhìn chung khá thường đúng

    • Phiên bản dí dỏm được biết đến là định luật thứ 10 của Greenspun
      “Bất kỳ chương trình C hay Fortran đủ phức tạp nào cũng chứa một bản triển khai nửa vời, theo đặc tả không chính thức, đầy lỗi và chậm của một nửa Common Lisp”
      Mẫu tổng quát hơn được gọi là Inner-Platform Effect
  • Nếu mở rộng tiền đề của tiêu đề, để WASM trở thành người kế thừa thực sự của dòng dõi đó, nó phải dễ như việc đưa và triển khai một ứng dụng PHP lên LAMP stack của bất kỳ nhà cung cấp hosting nào
    Có vẻ hiện tại nó vẫn chưa dễ bằng trải nghiệm triển khai PHP

    • WASM chạy trong trình duyệt
      Tôi không rõ bạn kỳ vọng điều gì phải thay đổi ở phía hosting
  • Tôi nhìn chuyện này theo hướng khác
    Tôi nghĩ tương lai là local-first
    Tức là ứng dụng hầu như không cần máy chủ hỗ trợ, mà phần lớn chạy ngay trong trình duyệt của người dùng
    Các ứng dụng như Figma, Linear, Superhuman đang dùng mô hình này rất thành công, và Stackblitz cũng phần nào như vậy
    Nếu một ứng dụng phức tạp ở mức như Figma có thể chạy gần như toàn bộ trong trình duyệt của người dùng, thì tôi nghĩ đa số ứng dụng khác cũng làm được
    Phía máy chủ chủ yếu đóng vai trò đồng bộ dữ liệu giữa các instance khác nhau khi người dùng dùng ứng dụng ở nhiều nơi
    Các công cụ như Electric-SQL đang được xây dựng nhưng vẫn chưa trưởng thành; khi những thư viện kiểu này chín muồi, lĩnh vực này sẽ tăng trưởng mạnh
    Serverless nhìn chung là thứ để các công ty như Amazon và Azure kiếm tiền, và cuối cùng sẽ trở nên giống CGI
    WASM cũng có thể thành công, nhưng nhiều khả năng chủ yếu là bên trong trình duyệt của người dùng
    Microsoft đang dùng WASM cho C#/Blazor, nhưng tôi không nghĩ dotnet trong trình duyệt sẽ nhanh được như JavaScript, nên tôi cho rằng đó không phải cách tiếp cận đúng

    • CGI trao sức mạnh cho người dùng và các website nhỏ
      Chỉ là không ai nói tới vì nó không thể mở rộng tới 1 nghìn tỷ lượt hiển thị quảng cáo mỗi giây
      Mỗi khi ai đó viết một hàm serverless, du thuyền của Bezos lại dài thêm 10 feet
    • Gọi Figma là local-first thì hơi khó
      Nếu đang offline hoặc ở nơi Wi-Fi chập chờn, bạn không thể tải thiết kế; và nếu gần đây không có gì thay đổi, sau khi chỉnh sửa mà Wi-Fi bị mất rồi bạn đóng trình duyệt thì nội dung sẽ không được lưu
    • Vậy ý là tương lai sẽ quay lại cách chúng ta chạy ứng dụng trước thời web chứ gì
    • Tôi ủng hộ sự phát triển của ứng dụng phía client, nhưng không cho rằng chúng nhất thiết phải chạy trong trình duyệt hay sandbox, hoặc phải được mua qua app store
      Và đây cũng chẳng phải ý tưởng hoàn toàn mới
    • dotnet trong trình duyệt có thể không nhanh bằng JavaScript, nhưng cả hai đều sẽ đủ nhanh
      Chúng tôi đang phát triển Blazor WASM, và về mặt hiệu năng thì dotnet không phải vấn đề
  • Về cơ bản là tạo lại JVM và hệ sinh thái của nó à?

    • Ở một mức độ nào đó thì đúng, nhưng WASM được thiết kế với những ràng buộc khác phù hợp hơn khi bạn muốn nhét một runtime vào bất cứ đâu
      Đôi khi việc tạo lại X có tính đến các bài học trong quá khứ thực sự là một ý tưởng tuyệt vời
    • Ở một khía cạnh nào đó thì đúng, nhưng WASM hỗ trợ nhiều ngôn ngữ hơn rất nhiều
      Ví dụ, khoảng năm 2010 khi tôi bắt đầu tìm hiểu việc chạy mã C/C++ trong trình duyệt, việc biên dịch C/C++ sang JVM về cơ bản là bất khả thi
      Khi đó Java Applet vẫn còn có ý nghĩa, nên nếu làm được thì đã tốt, nhưng WASM thì chưa có, còn Emscripten thì đã có, và nó đã dẫn tới asm.js rồi cuối cùng là sự ra đời của WASM
    • JVM rất tuyệt, nhưng điều đó không có nghĩa nó là câu trả lời cuối cùng của thể loại này
      Từ góc nhìn của một người từng nghịch class loader và tự viết assembly JVM trong lớp ngôn ngữ lập trình những năm 2000, tôi cũng không chắc JVM có phải đỉnh cao trong lĩnh vực này không
      Đúng là nó đã tạo điều kiện cho một hệ sinh thái lớn, nhưng giao diện nơi JVM tiếp xúc với thế giới bên ngoài thì thật sự thô kệch và hỗn độn
      Hơn 20 năm qua, mỗi lần gặp thứ gì đó liên quan đến JVM là tôi lại rên lên ngán ngẩm
      Nếu so sánh cách đóng gói và hệ sinh thái của Rust với Python, hoặc tệ hơn nữa là C++, ta sẽ thấy việc tái phát minh có tính đến các bài học của nhiều thập kỷ qua có thể là điều rất tốt
    • Tuy nhiên WASM có một vấn đề class loader/linker lớn
      Việc gộp hai file wasm thành một và căn chỉnh hợp nhất bộ nhớ cho đúng hiện vẫn rất khó
      Component model có thể sửa được chuyện này, nhưng nó có quá nhiều phần cồng kềnh không cần thiết nên có thể còn lâu Safari mới áp dụng
    • Đúng, và .Net CLR v.v. cũng vậy
  • Từ lâu tôi đã nghĩ WASM sẽ đi tới một thế giới nơi nó thay thế mã của các hàm Lambda trên cloud
    Theo truyền thống, WASM được xem là chạy trên nền tảng host, nhưng không có lý do gì bắt buộc phải như vậy
    Nhờ tính chất sandbox của WASM, về mặt kỹ thuật nó có thể chạy bên ngoài hệ điều hành hoặc ở ring0 để tránh được nhiều overhead của hệ điều hành
    Biên dịch sang WASM sẽ đơn giản hóa rất nhiều vấn đề triển khai từ phía người dùng, còn môi trường hosting thì có nhiều không gian để tối ưu hơn
    Thậm chí có thể có cả phần cứng tùy biến để chạy WASM nhanh hơn

  • Việc phải tự động chạy mã tùy ý không đáng tin cậy đến từ các nguồn tùy ý không đáng tin cậy là điều tệ, và cũng không thể nói nó lấp được vai trò giống như CGI phía máy chủ