14 điểm bởi GN⁺ 2024-10-23 | 15 bình luận | Chia sẻ qua WhatsApp
  • Xu hướng gần đây muốn viết lại các công cụ Node.js bằng những ngôn ngữ nhanh hơn như Rust, Zig, Go... là điều đáng lo ngại, và bài viết này tổng hợp các mối bận tâm mang tính khách quan

[Hiệu năng]

  • Tác giả cho rằng các khả năng để tăng tốc công cụ JavaScript vẫn chưa được khai thác hết
  • Vẫn còn nhiều điểm có thể cải thiện dễ dàng trong ESLint, Tailwind và các công cụ tương tự
  • Trên trình duyệt, JavaScript là “đủ nhanh” cho phần lớn workload
  • Vậy tại sao trong các công cụ CLI lại muốn từ bỏ JavaScript?

Viết lại quy mô lớn

  • Trong thời gian dài, hệ sinh thái công cụ JavaScript tập trung vào việc “làm cho nó chạy được”
  • Giờ đây API phần lớn đã ổn định, và mọi người đều muốn “cùng một thứ, nhưng nhanh hơn”
  • Công cụ mới có thể nhanh hơn vì được viết mới với hiệu năng trong đầu, đồng thời API đã được định hình sẵn nên tiết kiệm thời gian phát triển
  • Khi viết lại từ A sang B rồi thấy nhanh hơn, rất dễ kết luận rằng B nhanh hơn A
  • Nhưng cũng có thể chính việc viết lại mới là lý do nhanh hơn (vì ở lần thứ hai người ta biết nhiều hơn và chú ý đến hiệu năng hơn)

Bytecode và JIT

  • Trên trình duyệt, ta thường xem là hiển nhiên việc được hưởng lợi từ cache bytecode và JIT (trình biên dịch Just-In-Time)
  • Nếu JavaScript được cache đúng cách, trình duyệt không cần parse và biên dịch mã nguồn thành bytecode nữa
  • Những hàm được chạy thường xuyên sẽ được tối ưu thêm thành mã máy (JIT)
  • Nhưng script Node.js lại hoàn toàn không được hưởng lợi từ cache bytecode
  • Tuy nhiên giờ đây Node cũng đã có thể dùng compile cache (thiết lập biến môi trường NODE_COMPILE_CACHE)
  • JIT cần một hàm được chạy nhiều lần để trở thành “hot”, nên với các script chạy một lần thì khó hưởng lợi
  • Trong Pinafore, tác giả từng muốn thay thư viện blurhash viết bằng JavaScript bằng phiên bản Rust (Wasm), nhưng đến lần lặp thứ 5 thì chênh lệch hiệu năng biến mất
  • Có thể cân nhắc AOT-compile các script Node bằng những công cụ như Porffor
  • Dùng Wasm vẫn có suy giảm hiệu năng so với công cụ native thuần túy

[Khả năng đóng góp và dễ gỡ lỗi]

  • Đây là lý do hoài nghi chính đối với phong trào “viết lại mọi thứ sang native”
  • JavaScript là ngôn ngữ phổ biến nhờ kiểu dữ liệu dễ chịu, dễ học và được trình duyệt hỗ trợ
  • Trong thời gian dài, cả tác giả thư viện lẫn người dùng trong hệ sinh thái JavaScript đều dùng JavaScript
  • Điều này giúp hạ thấp rào cản đóng góp
  • Nhưng khi tác giả thư viện JavaScript chuyển sang dùng ngôn ngữ khác, lợi thế đó bị phá vỡ
  • Ngoài ra, việc sửa trực tiếp dependency JavaScript trên máy local cũng rất đơn giản (chỉnh ngay trong node_modules)
  • Ngược lại, nếu được viết bằng ngôn ngữ native thì phải checkout source code riêng rồi biên dịch
  • Khi debug thư viện JavaScript, có thể dùng các công cụ quen thuộc như DevTools của trình duyệt hoặc debugger của Node.js
  • Với Wasm không phải là không thể debug, nhưng sẽ cần một bộ kỹ năng khác

[Kết luận]

  • Việc xuất hiện một thế hệ công cụ mới cho hệ sinh thái JavaScript là điều tốt
  • Các công cụ hiện tại rất chậm và có lẽ sẽ được hưởng lợi từ cạnh tranh
  • Tuy nhiên, tác giả không cho rằng bản thân JavaScript vốn chậm một cách bản chất hay không còn dư địa cải thiện
  • Nhìn vào các cải tiến gần đây của Chromium DevTools, có cảm giác là vẫn còn rất nhiều việc có thể làm
  • Tác giả lo ngại về một thế giới trở thành sân chơi riêng của các lập trình viên Rust và Zig
  • Một lập trình viên JavaScript trung bình có thể cảm thấy bất lực khi gặp bug trong build tool
  • Điều đó có thể vô tình dạy cho các lập trình viên web trẻ một cảm giác bất lực đã được học sẵn
  • Đây là việc đi vào một con đường chưa được kiểm chứng, có thể dẫn đến những hệ quả ngoài ý muốn
  • Trong khi đó vẫn có những con đường khác ít rủi ro hơn mà có thể đạt gần như cùng kết quả
  • Nhưng dường như xu hướng hiện tại không có dấu hiệu chậm lại

Ý kiến của GN⁺

  • Viết lại bằng Rust hay Zig không phải lúc nào cũng là lựa chọn tốt nhất. Có vẻ JavaScript vẫn còn chỗ để cải thiện, như compile cache chẳng hạn
  • Cũng đáng đặt câu hỏi liệu việc để người mới phải đối mặt với các vấn đề phức tạp như segfault có thực sự tốt hay không; biết đâu nó chỉ dạy họ sự bất lực
  • Cần suy nghĩ liệu có nên hy sinh những lợi thế của hệ sinh thái đã được xây dựng lâu năm bằng JavaScript (như khả năng sửa tự do giữa các thư viện, môi trường debug quen thuộc...) chỉ để đổi lấy tốc độ hay không
  • Có lẽ các nỗ lực cải thiện các thư viện JavaScript hiện có cũng cần được tiếp tục. Tiềm năng của JavaScript vẫn chưa được khai thác hết
  • Dù có vẻ khó cưỡng lại xu thế, cộng đồng vẫn cần thảo luận và cân nhắc nghiêm túc hơn về hướng đi này

15 bình luận

 
labeldock 2024-10-27

Cách vận hành của một cửa hàng nhỏ và một đại siêu thị có thể hơi khác nhau. Thay vì chỉ giữ thái độ phê phán đối với bản thân việc thay đổi, tôi nghĩ sẽ lành mạnh hơn nếu suy nghĩ về ý nghĩa của hiện tượng này.
Có thể trông như thể họ thay đổi theo sở thích hay theo trào lưu, nhưng các doanh nghiệp thường đâu đưa ra quyết định theo cách đó.

 
ndrgrd 2024-10-25

Python hay chính bản thân JavaScript có chậm không? Thì chưa chắc có thể nói là như vậy
Nhưng các công cụ thường dùng được viết bằng Python hay JavaScript có chậm không? Tôi nghĩ là có.
Tôi đang dùng nhiều thiết bị công suất thấp, và có thật sự rất nhiều công cụ chậm đến mức bực bội..

 
youknowone 2024-10-24

Ngay cả trong cộng đồng Python cũng gần như đang lặp lại đúng cùng một kiểu câu chuyện như vậy.

JavaScript không được viết bằng JavaScript, nhưng phần lớn lập trình viên JavaScript không bận tâm đến điều đó. Việc JavaScript không được viết bằng JavaScript không phải là vấn đề đối với "lập trình viên mới vào nghề" hay "nhà phát triển web trẻ", nhưng việc các công cụ phát triển JavaScript không được viết bằng JavaScript lại bị xem là vấn đề thì quả là một lập luận không thật sự trước sau nhất quán. Đúng hơn thì, những lập trình viên bận tâm đến chuyện đó chỉ là một thiểu số rất nhỏ trong cả hai nhóm mà thôi.

Ngay cả khi không phủ nhận rằng sau khi tối ưu hóa đầy đủ thì có thể đạt tốc độ gần như tương đương, liệu điều đó có thật sự đáng hay không?
Đây đơn giản là sự chuyển đổi từ một thời kỳ mà viết công cụ phát triển bằng JavaScript thay vì C++ trở nên kinh tế hơn, sang một thời kỳ mà viết bằng Rust trở nên kinh tế hơn so với viết bằng JavaScript.
Cách để đảo ngược xu hướng này không phải là phát động một phong trào tối ưu hóa bằng JavaScript với chi phí cao hơn, mà là tạo ra một môi trường nơi có thể phát triển các công cụ JavaScript hiệu quả với chi phí phát triển thấp hơn. (Có thể nghe giống nhau, nhưng khác biệt nằm ở chỗ phải dồn nỗ lực vào đâu)

 
savvykang 2024-10-24

Tôi đồng ý. Tôi nghĩ cần định nghĩa lại tính kinh tế theo hướng lấy người dùng công cụ làm trung tâm.

Trong suốt thời gian qua, có lẽ tính kinh tế là một thước đo được đặt ra với nhiều cân nhắc cho nhà phát triển công cụ hơn là cho người dùng công cụ. Cảm giác như những vấn đề về hiệu năng và sự kém hiệu quả mà người dùng công cụ phải trải qua đã bị đẩy xuống khá xa trong thứ tự ưu tiên. Cá nhân tôi đang dùng rất tốt uv và vite, và nếu có thể thì tôi muốn tránh các công cụ như pip hay create-react-app.

 
click 2024-10-24

Tôi khó mà đồng ý vì tôi cho rằng công cụ CLI nên có thể hoạt động mà không cần runtime.
Nếu hỏi rằng chẳng phải có thể tạo file thực thi WASM độc lập sao, thì như bài viết cũng nói, sẽ có suy giảm hiệu năng.
Tôi nghĩ JavaScript cũng tương tự như việc viết CLI bằng Java không phải là điều phổ biến.

 
savvykang 2024-10-23

Có vẻ như tác giả đang nhầm rằng vì cả SPA lẫn việc phát triển công cụ JavaScript đều dùng JavaScript nên các năng lực nền tảng cần thiết cũng giống nhau. Tôi cho rằng công cụ JavaScript đòi hỏi năng lực về lập trình hệ thống và lĩnh vực trình biên dịch.


Trong một thời gian dài, trong hệ sinh thái JavaScript, cả tác giả thư viện lẫn người dùng đều sử dụng JavaScript
Điều này giúp hạ thấp rào cản đóng góp
Nhưng nếu tác giả thư viện JavaScript dùng ngôn ngữ khác thì điểm này sẽ bị phá vỡ

Ngay cả khi cùng một ngôn ngữ, môi trường thực thi vẫn khác nhau giữa trình duyệt và NodeJS, và có lẽ chỉ những người có thể vượt qua khoảng cách đó mới có thể đóng góp cho công cụ JavaScript. Vì môi trường thực thi khác nhau nên chẳng phải nên xem đó là những hệ sinh thái khác nhau sao?


Một lập trình viên JavaScript trung bình có thể cảm thấy bất lực khi đối mặt với lỗi của build tool
Điều đó có thể chẳng khác nào dạy cho các nhà phát triển web trẻ sự bất lực đã học được

Tôi nghĩ điều này cũng tương tự, ở chỗ nó đã đánh giá quá cao số người có thể vượt qua ranh giới giữa phát triển SPA và phát triển công cụ JavaScript. Đòi hỏi kiến thức tương đương với lập trình hệ thống từ một lập trình viên frontend là điều quá sức. Chẳng phải người dùng công cụ rốt cuộc chỉ có thể hiểu các thông báo lỗi bề mặt hoặc hiện tượng biểu hiện ra ngoài thôi sao? Tôi không nghĩ đây là vấn đề có thể giải quyết chỉ bằng việc biết cùng một ngôn ngữ.

 
regentag 2024-10-23

Có vẻ như đang trộn lẫn giữa công cụ và thư viện. Với thư viện thì tôi có thể đồng cảm ở một mức độ nào đó, nhưng còn công cụ thì tôi không chắc lắm..
Ngay cả các lập trình viên ngôn ngữ khác cũng đã quen với việc công cụ được viết bằng mã native rồi mà.

 
ragus 2024-10-23

Cá nhân tôi nghĩ rằng, dù là công cụ hay thư viện, nếu chúng được viết bằng JavaScript thì các nhà phát triển quen với JavaScript có thể gỡ lỗi cho chúng và nếu cần thì cũng có thể đóng góp. Nhưng một khi đã bị viết lại bằng Rust, việc đóng góp cho mã nguồn mở rốt cuộc sẽ chỉ còn các nhà phát triển Rust mới làm được. Vì số lượng nhà phát triển JavaScript áp đảo so với Rust, nên trong hệ sinh thái mã nguồn mở, việc các công cụ hay thư viện được viết bằng JavaScript có thể lại có lợi hơn.

 
savvykang 2024-10-23

JavaScript có môi trường thực thi bị phân mảnh giữa trình duyệt và NodeJS, vì vậy tôi cho rằng việc so sánh đơn giản số lượng người dùng ngôn ngữ này có giới hạn khi dùng làm luận cứ. Lập trình viên backend Spring và lập trình viên phát triển JDK, lập trình viên React/Angular/Vue và lập trình viên công cụ JavaScript có mối quan tâm và lập trường khác nhau; họ ở trong mối quan hệ giữa bên tiêu dùng và bên sản xuất

Nếu mục tiêu là cải thiện hiệu năng và tính dễ dùng của các công cụ JavaScript, thì theo cá nhân tôi, việc thay đổi ngôn ngữ triển khai như một phương tiện cũng là một lựa chọn khả dĩ.

 
unqocn 2024-10-24

Tôi nghĩ rất khó để phân tách rõ ràng giữa người tiêu dùng và người tạo ra các công cụ phát triển. Khi công ty lớn dần, rất nhiều trường hợp họ sẽ tùy biến toolchain hoặc tự triển khai thêm plugin theo các quy tắc mà họ mong muốn, và trong những trường hợp đó, chỉ riêng việc dùng cùng một ngôn ngữ cũng đã là một lợi thế lớn.
Cũng có nhiều trường hợp người dùng của công cụ quan tâm đến các cải tiến hoặc việc triển khai chính bản thân công cụ, rồi từ đó tự nhiên đóng góp vào nó.

 
savvykang 2024-10-24

Tôi nghĩ rằng những người bắt đầu quan tâm đến việc tùy biến toolchain hoặc trực tiếp làm công việc đó đang đảm nhận vai trò vượt ra ngoài người tiêu dùng, gần với prosumer hoặc thậm chí là nhà sản xuất. Với plugin, tôi cho rằng chúng hoạt động trong khuôn khổ quy ước plugin giữa nhà sản xuất và người tiêu dùng. Trong tình huống đó, tôi cũng đồng ý rằng việc dùng cùng một ngôn ngữ sẽ có lợi hơn về mặt kỹ thuật lẫn chi phí giao tiếp so với việc cung cấp một định dạng tệp cấu hình riêng hoặc các extension point.

Tuy vậy, tôi không cho rằng vấn đề hiệu năng của các công cụ JavaScript hay độ trễ JIT của NodeJS nằm trong phạm vi ra quyết định của người tiêu dùng. Bởi vì chính các nhà sản xuất công cụ và các nhà phát triển runtime mới là chủ thể đã tạo ra kiến trúc và đặc tả vận hành đó.

 
passerby 2024-10-23

Việc miếng bánh JavaScript lớn không có nghĩa là sẽ có nhiều nhà phát triển hơn có thể đóng góp cho codebase của compiler / transpiler. Tôi nghĩ thư viện, framework và các công cụ nền tảng là những lĩnh vực hoàn toàn khác nhau.

 
aer0700 2024-10-23

Nhưng có thể chính việc viết lại mới là lý do khiến nó nhanh hơn
-> Nghĩ lại thì đúng là câu này rất chuẩn...

 
coremaker 2024-10-23

Tôi đồng cảm với ý kiến của người này vì đó là một lựa chọn rất có chọn lọc.
Tuy vậy, ở một khía cạnh khác, việc tồn tại nhiều cách giải quyết đa dạng ngoài JS cũng là một yếu tố rất quan trọng xét trên phương diện tiến bộ công nghệ, nên tôi nghĩ quan điểm ngược lại cũng cần được tôn trọng!

 
GN⁺ 2024-10-23
Ý kiến Hacker News
  • Có ý kiến cho rằng JavaScript vốn dĩ chậm. Nhiều kỹ sư đã nỗ lực làm cho nó nhanh hơn, nhưng nó vẫn chậm hơn các ngôn ngữ kiểu tĩnh. Với các chương trình quy mô lớn, ngôn ngữ có kiểu dữ liệu rõ ràng phù hợp hơn

    • Rust và Go phù hợp để phát triển công cụ; có thể tạo nguyên mẫu bằng TypeScript, nhưng với các tác vụ đồng thời quy mô lớn thì nên dùng ngôn ngữ khác
    • Hệ thống kiểu của Rust mang lại sự tự tin khi phát triển công cụ, còn hệ thống kiểu của Go được cho là vẫn cần cải thiện
  • JavaScript không hề dễ học, và có hệ thống prototype cùng hệ thống kiểu phức tạp. TypeScript giúp bù đắp điều này, nhưng vẫn còn phức tạp

    • Hệ sinh thái JavaScript rất phức tạp và khó dùng công cụ. Go thì dễ học và cách dùng công cụ cũng đơn giản
    • Để triển khai tính đồng thời trong JavaScript, cần hiểu những khái niệm phức tạp
  • Chỉ riêng việc đổi ngôn ngữ cũng có thể cải thiện hiệu năng đáng kể. Khi thay hệ thống hiện có từ JS và PHP sang Go, đã từng ghi nhận mức cải thiện hiệu năng 8-10 lần

  • Tầm quan trọng của xử lý song song đang bị xem nhẹ. Rust phù hợp để viết mã song song, còn JS thì không phù hợp

    • Rust bảo đảm tính an toàn luồng, giúp giảm các vấn đề bảo trì
  • JavaScript giờ đã có tốc độ tương đương Java và chậm hơn C++ khoảng 2-4 lần. Muốn tăng hiệu năng thì phải bước ra khỏi vùng an toàn

    • Phản ứng của các lập trình viên với hiệu năng quá cực đoan đến mức có người đã chuyển sang nghề khác
  • Các chương trình viết bằng Rust, Zig và Go dễ kiểm tra mã nguồn và biên dịch. Việc học ngôn ngữ mới cũng ảnh hưởng đến cách giải quyết vấn đề

  • Có ý kiến cho rằng tiềm năng cải thiện hiệu năng của các công cụ JavaScript vẫn chưa bị khai thác hết. Tuy vậy, xây dựng trên một nền tảng tốt hơn sẽ hiệu quả hơn

  • Rspack là bản viết lại tương thích của Webpack bằng Rust, cho hiệu năng tốt hơn 5-10 lần. Có thể thay thế Webpack một cách dễ dàng

  • Việc chỉnh sửa dependency JavaScript ngay trên máy cục bộ thì dễ, nhưng Rust ít lỗi hơn nên ít khi cần sửa. Rust khó học, nhưng nhờ đó có thể trở thành lập trình viên tốt hơn cả ở các ngôn ngữ khác

    • Độ chính xác quan trọng hơn tốc độ, và nếu phát hành một thư viện có lỗi thì sẽ làm lãng phí thời gian của người dùng