Angular, React, Vue, Svelte… rồi tiếp theo sẽ là gì?

Bài viết được sự cho phép của tác giả Tống Xuân Hoài

Vấn đề

Angular, React, Vue, Svelte (A, R, V, S)… là những cái tên mà không quá xa lạ với bạn đọc. Có lẽ mọi người sẽ ngạc nhiên hơn khi nhắc đến một nhân vật như là jQuery- một tượng đài già cỗi, đã lặng lẽ nhường ngôi cho các thanh niên trẻ bấy giờ.

Nếu chịu khó tìm hiểu, cuộc đọ sức giữa các tên này không bao giờ hạ nhiệt. Rất nhiều bài viết phân tích cũng như so sánh chúng với nhau. Rằng A có cấu trúc rất chặt chẽ, R rất mạnh mẽ, nhưng V lại cho khả năng phát triển với tốc độ tuyệt vời. Còn S, một cái tên sinh sau đẻ muộn nhưng lại đang thể hiện ưu thế rất lớn khi kết hợp cả hai Back-end và Front-end làm một. Vâng! Trông nó giống như PHP, nhưng lại là… JavaScript.

Có rất nhiều câu chuyện hài hước xoay xung quanh các thư viện dựa trên JavaScript. Mỗi khi xuất hiện một cái tên mới, thay vì ngó lơ nó thì lập trình viên JS thường phải thốt lên rằng: Chu choa… lại phải học thêm một cái mới à!!!

Quả thật cùng một chức năng, cùng giải quyết một vấn đề nhưng lại sinh ra biết bao nhiêu là thư viện/framework. A, R, V, S là một ví dụ. Nói vui vậy thôi chứ quyền lựa chọn sử dụng là ở mỗi người. Nếu thấy thích hoặc cái nào giải quyết được vấn đề một cách hợp lý thì có lý gì mà không chọn. Ví dụ, vì R rất phổ biến, nếu chọn R để phát triển dự án thì sau này không phải lo sợ tìm người bảo trì nữa (chẳng thế mà một số người luôn miệng nói một mét vuông có 100 người biết React).

Tôi là một người đã thử sử dụng cả 4 cái tên ở trên và rút ra cho mình được một số kinh nghiệm nhất định. Trong khi cấu trúc của Angular rất rõ ràng, còn React thì được hậu thuẫn bởi rất nhiều thư viện, Vue thì rất dễ để phát triển và Svelte thì cực kỳ đa năng. Nhưng dường như tất cả lại cùng có chung một điểm chí mạng là… dùng quá nhiều JavaScript!

Nếu bạn là một nhà phát triển Web Application hay một hệ thống CMS phức tạp, 4 cái tên bên trên rất phù hợp. Còn nếu bạn xây dựng một ứng dụng đòi hỏi tốc độ xử lý siêu nhanh, như ứng dụng nhúng qua CDN hoặc một trang web cần tải nhanh nhất có thể, thân thiện với SEO thì thành thật mà nói: Phải vất vả lắm để tối ưu nó nếu như không muốn điểm của Lighthouse thấp một cách thậm tệ.

Thực tế, hãy nhìn vào trang blog này, bạn có thấy nó đơn giản không? Chẳng có tính năng gì đáng kể nhưng sự thật đằng sau nó, JavaScript xuất hiện ở khắp mọi nơi, do đó điểm của Lighthouse luôn biến đổi mỗi khi tôi vừa làm xong một cái gì đó mới.

Điểm của Lighthouse 2coffee.dev

Bạn đọc có thể tìm thấy một số bài viết nói về cách tôi tăng hiệu năng cho blog. Nào là sử dụng CSS Grid, thiết lập kích thước ảnh cố định, tận dụng Static Site Generate (SSG)… nhưng có vẻ vấn đề chưa được giải quyết một cách triệt để.

Một số bạn sẽ thắc mắc tại sao lại trú trọng vào điểm của Lighthouse thì tôi xin phép được nhắc lại. Core Web Vitals là tập hợp các chỉ số mà Google đề ra để đánh giá một trang web thân thiện với người dùng. Lighthouse là một trong số các công cụ giúp chúng ta tính được điểm số đó. Ngoài ra, nó còn cung cấp giải pháp để khắc phục vấn đề khiến cho điểm số thấp.

Quay trở lại, mặc dù đã lựa chọn SSG và tôi nghĩ trang web của mình đã loại bỏ hết mã JavaScript phía máy khách nhưng sự thật không phải thế. Nuxt.js (thư viện tôi dùng để phát triển blog) vẫn trả về rất nhiều mã JavaScript và điều đó làm giảm điểm của Lighthouse trên di động một cách đáng kể.

Khi tìm hiểu thêm về cách Nuxt hoạt động, các đoạn mã JS được trả về là cần thiết để nó xử lý các mã JS trong hàm mounted, ngoài ra một phần mã là mã của thư viện Vue.js để khởi tạo một đối tượng Vue. Nhưng nó chưa đủ thông minh để trả về JS ở những nơi cần thiết mà chọn cách đóng gói tất cả JS và trả về ngay lập tức. Hệt như tiêu chí “thà giết nhầm còn hơn bỏ sót”. Điều đó khiến cho mặc dù bạn chỉ dùng một ít mã JS nhưng nó vẫn trả về tất cả mã của thư viện Vue hoặc mã từ nơi khác.

Đó là Nuxt.js, vậy thì Next.js – một thư viện SSR và SSG tương tự như Nuxt thì sao? Tôi đã thử đo điểm Lighthouse của một số trang làm bằng Next và kết quả không nằm ngoài dự đoán, mã JS vẫn được trả về quá nhiều. Từ đó có thể suy ra chúng hoạt động theo cách tương tự nhau.

Hmm, chẳng lẽ không còn cách nào khác?

  Đo lường thời gian thực hiện hàm trong Javascript một cách thanh lịch

  Quét mảng hiệu quả với hàm reduce trong Javascript

Suy nghĩ về một trang web không có JavaScript

Thành thật, rất nhiều lần tôi nghĩ đến việc xây lại trang blog mà không cần dùng đến JavaScript hay bất kỳ một thư viện hỗ trợ về giao diện ứng dụng nào nhưng điều này quả thực rất khó. Một phần vì đã quá quen với việc sử dụng thư viện, một phần vì muốn tiết kiệm thời gian. Thử nghĩ nếu tạo ra được đi thì quá trình chuyển đổi những gì đang có và cần bảo trì sau này cũng khá vất vả.

Còn có một cách nữa là tìm đến các công cụ hỗ trợ “generate”. Như bạn biết blog chỉ có một vài màn hình chính, trong đó màn hình chi tiết bài viết gần như là thứ quan trọng hơn cả vì nó là nơi mà người đọc tương tác nhiều nhất. Với một bố cục cố định, nội dung chỉ thay đổi tùy vào đường dẫn liên kết (url), tôi có thể chỉ cần tạo nên một trang layout có bố cục nhất định, rồi thông qua Hugo để điền nội dung vào các chỗ trống thế là xong!

Nhưng suy đi cũng cần phải tính lại, có thể Hugo tạo trang nội dung tĩnh rất tốt nhưng thế vẫn chưa đủ. Thứ mà tôi muốn là một công cụ tạo tĩnh nhưng lại trông… rất động, tĩnh trong hầu hết trường hợp và động trong chỉ một số ít trường hợp. Hay nói tóm lại là dễ dàng viết thêm mã JavaScript ở một số nơi và đừng nên trả về mã JS thừa.

Deno Fresh

Fresh là một cái tên rất mới tham gia vào làng phù thủy giao diện. Fresh được giới thiệu là một “The next-gen web framework – Built for speed, reliability, and simplicity”. Fresh không yêu cầu JavaScript ở máy khách (client) nếu không cần thiết. JS chỉ được áp dụng nếu bạn cho phép.

Nghe thì có vẻ tuyệt đấy, một khung giao diện nhưng không cần JavaScript. Để làm được điều đó, Fresh sử dụng kết xuất phía máy chủ (SSR) như Next.js hay Nuxt.js… Nhưng có thể chạy mà không cần JS, hay nói cách khác là với lượng JS tối thiểu nhất có thể, từ đó giúp cho trang web chạy nhanh hơn và không gây cản trở cho Vitals.

Thành thật, tôi biết đến Fresh cách đây một thời gian, từ khi nó còn ở phiên bản 1.x – x tiểu học. Vì thế cho nên nhiều hạn chế về tính năng cùng với tài liệu chưa được hấp dẫn cho lắm nên nhiều điều thú vị bị bỏ qua. Cho đến hôm nay khi vô tình trở lại thì mọi thứ đã thay đổi rất nhiều. Có vẻ Fresh đã làm được nhiều hơn xưa.

Điểm thú vị nhất ở Fresh là kiến trúc “đảo tương tác” – Interactive islands, với tiêu chí mọi thứ đều tĩnh và chỉ nên có một số thành phần động như những hòn đảo giữa đại dương. Các thành phần tĩnh được kết xuất phía máy chủ, trả về mã HTML và ngược lại, khi gặp các hòn đảo tương tác, mã JavaScript mới được trả về cho máy khách xử lý. Như vậy, JavaScript không được gửi về một cách ồ ạt mà chỉ khi nào nó được phép, được sử dụng.

Tôi đã thử đo điểm chuẩn của một số trang xây dựng bằng Fresh thì thật ấn tượng, tất cả đều đạt điểm số tối đa và cực kỳ thân thiện với điểm Core Web Vitals.

Điểm của Lighthouse Fresh

Ngoài ra, Fresh cũng được hỗ trợ bởi Cloudflare Worker – là một nền tảng cho phép triển khai các ứng dụng “web on the egde”. Woker gặp một một số hạn chế về tốc độ và giới hạn truy vấn miễn phí khác với Cloudflare Pages nhưng Pages hiện tại chưa hỗ trợ Fresh.

Nhưng tất cả chỉ là lý thuyết, còn cần phải chứng minh liệu nó có đúng như quảng cáo? Như vậy, ngay bây giờ tôi đã bắt tay vào nghiên cứu Fresh và hy vọng trong thời gian sớm nhất, biết đâu lại lên một bài viết nói về quá trình chuyển đổi từ Nuxt.js sang Fresh thì sao!

Còn bạn nghĩ sao về quan điểm trong bài viết này? Hãy để lại bình luận cho tôi và bạn đọc cùng biết nhé!

Bài viết gốc được đăng tải tại 2coffee.dev

Có thể bạn quan tâm: