Trong cộng đồng nhà phát triển, rất phổ biến khi thấy các khuôn khổ và công cụ mới xuất hiện mỗi ngày. Một số trong số chúng cung cấp một cách tiếp cận khác để giải quyết các tình huống hiện đang được giải quyết bằng các công cụ khác. Những công cụ khác mang đến một khái niệm hoặc ý tưởng mới, đề xuất một cách khác để đối mặt với các dự án. Vì thợ mộc có các công cụ khác nhau để thực hiện các nhiệm vụ khác nhau, nên các nhà phát triển có nhiều khuôn khổ và thư viện có sẵn phù hợp với các trường hợp sử dụng khác nhau.
Chúng ta hãy nói về Remix, (một loại) khuôn khổ mới để tạo các dự án JavaScript bằng cách sử dụng kết xuất phía máy chủ. Chúng ta hãy xem qua các tính năng và khái niệm chính của nó và xem những điểm tương đồng và khác biệt với một khuôn khổ JavaScript phổ biến khác: Next.js.
Vì được xây dựng trên API Web Fetch, các ứng dụng được tạo bằng Remix có thể chạy ở bất kỳ đâu. Remix sử dụng kết xuất phía máy chủ để thao tác dữ liệu và kết xuất nội dung HTML trên máy chủ, gửi ít JavaScript nhất có thể đến máy khách.
Ban đầu, Remix là một khuôn khổ cao cấp dựa trên đăng ký nhưng, cách đây chưa đầy một năm, nó đã được ra mắt dưới dạng khuôn khổ nguồn mở. Sau đó, cộng đồng các nhà phát triển và người dùng Remix bắt đầu phát triển và trở nên phổ biến hơn.
Cả Next.js và Remix đều sử dụng React, vì vậy chúng có thể dựa vào các tính năng như hydrat hóa phía máy khách. Mặt khác, cả hai khung cũng hỗ trợ kết xuất trước HTML từ máy chủ. Tùy thuộc vào dự án chúng tôi đang làm việc, chúng tôi có thể muốn tạo càng nhiều nội dung càng tốt ở phía máy chủ, tránh gửi mã JavaScript và tìm nạp dữ liệu từ máy khách.
Nhưng SSG cũng có thể trở thành vấn đề: bất cứ khi nào chúng ta áp dụng các thay đổi cho mã hoặc nội dung của ứng dụng, chúng ta cần phải chờ quy trình xây dựng để tạo phiên bản mới của các tài sản tĩnh. Điều này có thể trở thành một điểm khó khăn, vì thời gian xây dựng sẽ tăng lên nếu dự án của chúng ta ngày càng lớn hơn. Để giải quyết vấn đề này, nhóm Next.js đã phát triển một tính năng có tên là Tái tạo tĩnh gia tăng (ISR) và ISR theo yêu cầu hoàn toàn mới.
Next.js cũng cung cấp khả năng làm việc với stale-while-revalidate. Bên trong hàm
Nhưng có một hạn chế: thành phần
Remix sử dụng thẻ
Mặc dù các ứng dụng hiện đại dựa vào CDN để phân phối nội dung tĩnh, nhưng mã phía máy chủ được xử lý để tạo nội dung động thường được thực thi trong trung tâm dữ liệu, chạy ở một vị trí cụ thể. Một giải pháp thay thế cho tình huống này là sử dụng chỉ thị bộ nhớ đệm SWR, với cảnh báo cuối cùng sẽ phục vụ nội dung cũ trong khi CDN làm mới tài nguyên.
Nhớ đến vấn đề này, trong những năm gần đây, một khái niệm mới đã ra đời: Điện toán biên. Ý tưởng là làm theo cùng một cách tiếp cận được sử dụng bởi các CDN, sao chép logic máy chủ ở các máy chủ và vị trí khác nhau, thực thi mã động càng gần người dùng càng tốt. Trong khi Remix được định nghĩa là "Edge First", nghĩa là khuôn khổ này được cho là chạy trên Edge ngay từ khi hình thành, Vercel đã ra mắt Edge Functions như một tính năng bổ sung cho ứng dụng được triển khai trên nền tảng này.
Remix cung cấp phần tử
Mặt khác, Next.js dựa vào mã JavaScript để biết cách quản lý trạng thái của ứng dụng, API nào gọi, xác thực lại dữ liệu và cập nhật giao diện của trang web. Khi sử dụng API Routes, chúng ta có thể có các tệp riêng biệt thực thi chức năng phía máy chủ và trả về dữ liệu cho giao diện người dùng của chúng ta.
Như chúng tôi đã nói, và như bạn có thể thấy, Remix có cách biến đổi dữ liệu để cố gắng quay lại những điều cơ bản, gợi nhớ lại những ngày khi PHP là thứ lớn lao.
Với phiên bản mới nhất của Next.js, 12.2, giờ đây bạn có thể chọn Edge Runtime cho toàn bộ dự án Next.js của mình, thay vì sử dụng thời gian chạy Node.js mặc định.
Chúng ta hãy nói về Remix, (một loại) khuôn khổ mới để tạo các dự án JavaScript bằng cách sử dụng kết xuất phía máy chủ. Chúng ta hãy xem qua các tính năng và khái niệm chính của nó và xem những điểm tương đồng và khác biệt với một khuôn khổ JavaScript phổ biến khác: Next.js.
Remix là gì?
Theo trang web chính thức của nó, Remix là một khuôn khổ ngăn xếp đầy đủ edge-first cho phép các nhà phát triển tạo ra trải nghiệm người dùng tuyệt vời tập trung vào các tiêu chuẩn web. Với nó, bạn có thể tạo ứng dụng web của mình bằng React và JavaScript cho cả kết xuất phía máy khách và kết xuất phía máy chủ.Vì được xây dựng trên API Web Fetch, các ứng dụng được tạo bằng Remix có thể chạy ở bất kỳ đâu. Remix sử dụng kết xuất phía máy chủ để thao tác dữ liệu và kết xuất nội dung HTML trên máy chủ, gửi ít JavaScript nhất có thể đến máy khách.
Ban đầu, Remix là một khuôn khổ cao cấp dựa trên đăng ký nhưng, cách đây chưa đầy một năm, nó đã được ra mắt dưới dạng khuôn khổ nguồn mở. Sau đó, cộng đồng các nhà phát triển và người dùng Remix bắt đầu phát triển và trở nên phổ biến hơn.
Các tính năng chính của Remix
Chúng ta hãy cùng nêu bật một số tính năng chính do Remix cung cấp:- Các tuyến đường:
Giống như các khuôn khổ khác, Remix cho phép các nhà phát triển quản lý các tuyến đường khác nhau của các dự án web của họ bằng các tệp JavaScript/TypeScript có chứa các hàm xử lý. Chúng tôi có thể tạo các tuyến đường trong trang web của mình bằng cách tạo các tệp theo hệ thống phân cấp tệp của các dự án, tạo các URL tương tự cho các trang của chúng tôi. Các tuyến phối lại hoạt động bằng tính năng định tuyến một phần do React-Router cung cấp. Với cách tiếp cận này, chúng ta có thể nêu bật những lợi ích sau. - Các thành phần lồng nhau:
Remix cung cấp cho bạn khả năng quản lý các trang và thành phần lồng nhau. Chúng ta có thể tạo một tệp để xử lý một tuyến đường nhất định và, ở cùng cấp độ trong hệ thống tệp, một thư mục có cùng tên. Tất cả các tệp mà chúng ta tạo bên trong thư mục đó sẽ là các thành phần lồng nhau của tuyến đường cha, thay vì các trang khác nhau. - Xử lý lỗi:
Các thành phần lồng nhau mang lại một lợi ích khác: nếu xảy ra lỗi trong khi hiển thị một thành phần nhất định, lỗi đó sẽ không ảnh hưởng đến các phần lồng nhau khác của trang. Vì vậy, chúng ta có thể đóng gói lỗi chỉ trong phần xảy ra lỗi, thay vì nhận được lỗi chung của trang. - Biểu mẫu:
Vì Remix tập trung vào các tiêu chuẩn web, nên nó sử dụng các phương thức gốc (POST
,PUT
,DELETE
,PATCH
) để xử lý biểu mẫu thay vì sử dụng JavaScript cho việc đó. - Bộ tải và Hành động:
Remix cung cấp hai loại hàm khác nhau để tạo nội dung động phía máy chủ. Các hàmbộ tải
được sử dụng để xử lý các yêu cầu HTTPGET
trong máy chủ, chủ yếu được sử dụng để lấy dữ liệu từ các nguồn khác nhau. Các hàmaction
theo dõi các yêu cầuPOST
,PUT
,DELETE
vàPATCH
, tập trung vào thao tác và sửa đổi dữ liệu.
Sự khác biệt giữa Remix và Next.js là gì?
Nếu chúng ta xem xét nhanh, Next.js và Remix có vẻ như chúng đang theo đuổi cùng một mục tiêu — và có lẽ là đúng như vậy. Nhưng nếu chúng ta phân tích các tính năng và cách tiếp cận mà chúng cung cấp, chúng ta sẽ xác định được điểm tương đồng và khác biệt, và chúng ta có thể nghĩ về các tình huống được giải quyết theo cách phù hợp hơn với một trong hai khuôn khổ này hơn là khuôn khổ kia.Dựa trên React
Cả hai khuôn khổ đều được tạo trên React, nhưng Remix cố gắng tách mình khỏi nó. Chúng ta có thể thấy rằng Remix cung cấp các cấp độ trừu tượng cao hơn. Ngoài ra, các thành viên khác nhau của cộng đồng Remix đã làm việc trên các triển khai khác nhau bằng cách sử dụng các khuôn khổ khác, như Vue.js, Angular và Svelte. Next.js phụ thuộc vào React và hiện tại không có kế hoạch thay đổi điều này.Kết xuất phía máy chủ
Bên cạnh các tính năng đã đề cập ở trên, chúng ta có thể thấy rằng cả Remix và Next.js đều cung cấp kết xuất phía máy chủ (SSR) để tạo đánh dấu và nội dung của các trang của chúng tôi từ máy chủ web trước khi gửi đến máy khách.Cả Next.js và Remix đều sử dụng React, vì vậy chúng có thể dựa vào các tính năng như hydrat hóa phía máy khách. Mặt khác, cả hai khung cũng hỗ trợ kết xuất trước HTML từ máy chủ. Tùy thuộc vào dự án chúng tôi đang làm việc, chúng tôi có thể muốn tạo càng nhiều nội dung càng tốt ở phía máy chủ, tránh gửi mã JavaScript và tìm nạp dữ liệu từ máy khách.
Tạo trang web tĩnh
Mặt khác, Next.js cung cấp khả năng tạo trước các trang và nội dung tĩnh tại thời điểm xây dựng, bằng cách sử dụng tạo trang web tĩnh (SSG), trong khi Remix thì không. Tùy thuộc vào loại trang chúng tôi muốn tạo, tính năng này là thứ có thể mang lại lợi ích lớn. Với SSG, chúng ta có thể lấy dữ liệu và hiển thị các trang tại thời điểm xây dựng, có các trang tĩnh trước khi người dùng truy cập trang web của chúng ta, mà không cần phải chờ nội dung được tạo.Nhưng SSG cũng có thể trở thành vấn đề: bất cứ khi nào chúng ta áp dụng các thay đổi cho mã hoặc nội dung của ứng dụng, chúng ta cần phải chờ quy trình xây dựng để tạo phiên bản mới của các tài sản tĩnh. Điều này có thể trở thành một điểm khó khăn, vì thời gian xây dựng sẽ tăng lên nếu dự án của chúng ta ngày càng lớn hơn. Để giải quyết vấn đề này, nhóm Next.js đã phát triển một tính năng có tên là Tái tạo tĩnh gia tăng (ISR) và ISR theo yêu cầu hoàn toàn mới.
Stale While Revalidate
Để phục vụ nội dung nhanh nhất có thể, Remix dựa vào chỉ thị bộ nhớ đệm stale-while-revalidate (SWR). Thay vì tạo trước nội dung tĩnh, nó sẽ chuẩn bị bộ đệm khi ứng dụng có lưu lượng truy cập. Các trang và tài liệu được phục vụ từ bộ đệm, trong khi chúng xác thực lại ở chế độ nền cho khách truy cập tiếp theo.Next.js cũng cung cấp khả năng làm việc với stale-while-revalidate. Bên trong hàm
getServerSideProps
, bạn có thể sử dụng stale-while-revalidate tiêu đề điều khiển bộ đệm.Điều hướng phía máy khách
Một trong những tính năng được Next.js sử dụng để cung cấp khả năng điều hướng mượt mà cho người dùng là tìm nạp trước. Chúng ta có thể sử dụng thành phần
[*]
để khiến trang web của mình tải trước trang mà
chuyển hướng đến khi phần tử xuất hiện trong khung nhìn. Nếu chúng ta truy cập trang chủ của một trang web và thấy liên kết "Liên hệ" trên trang, Next.js sẽ tải xuống và tìm nạp nội dung liên quan đến trang liên hệ. Vì vậy, khi chúng ta nhấp vào liên kết, chúng ta không phải đợi trang được tải xuống.Nhưng có một hạn chế: thành phần
Link
chỉ cung cấp tính năng tìm nạp trước cho các trang được xây dựng trước bằng cách sử dụng tạo trang tĩnh (SSG). Nếu chúng ta có liên kết đến các trang được tạo động, tính năng này sẽ không được kích hoạt.Remix sử dụng thẻ
HTML (thay vì bộ nhớ đệm như thành phần Link
Next.js), vì vậy chúng ta có thể tìm nạp trước không chỉ các liên kết mà thực sự là bất kỳ trang nào. Trong trường hợp chúng ta muốn triển khai một cái gì đó tương tự bằng Next.js, có thể sử dụng thành phần next/head
và thêm thẻ prefetch
.Edge First
Khi chúng ta đang truy xuất dữ liệu và hiển thị nội dung từ máy chủ, chúng ta cũng phải đánh giá xem máy chủ thực thi mã cách xa người dùng gửi yêu cầu HTTP bao nhiêu. Nếu máy chủ chính của tôi nằm ở Brazil và người dùng đang truy cập trang web của tôi từ Trung Quốc, quá trình tải trang sẽ chậm hơn của tôi, nếu tôi truy cập cùng một trang từ Argentina. Điều này liên quan đến khoảng cách địa lý mà yêu cầu HTTP phải di chuyển đến máy chủ gần hơn để đánh giá và thực thi mã.Mặc dù các ứng dụng hiện đại dựa vào CDN để phân phối nội dung tĩnh, nhưng mã phía máy chủ được xử lý để tạo nội dung động thường được thực thi trong trung tâm dữ liệu, chạy ở một vị trí cụ thể. Một giải pháp thay thế cho tình huống này là sử dụng chỉ thị bộ nhớ đệm SWR, với cảnh báo cuối cùng sẽ phục vụ nội dung cũ trong khi CDN làm mới tài nguyên.
Nhớ đến vấn đề này, trong những năm gần đây, một khái niệm mới đã ra đời: Điện toán biên. Ý tưởng là làm theo cùng một cách tiếp cận được sử dụng bởi các CDN, sao chép logic máy chủ ở các máy chủ và vị trí khác nhau, thực thi mã động càng gần người dùng càng tốt. Trong khi Remix được định nghĩa là "Edge First", nghĩa là khuôn khổ này được cho là chạy trên Edge ngay từ khi hình thành, Vercel đã ra mắt Edge Functions như một tính năng bổ sung cho ứng dụng được triển khai trên nền tảng này.
Mã phía máy chủ
Khi mô tả các tính năng chính của Remix, chúng tôi đã nói rằng khuôn khổ này sử dụng các phương thức HTTP gốc để quản lý biểu mẫu với sự trợ giúp của các hàmaction
và loader
. Một biểu mẫu, một máy chủ, một yêu cầu POST
vận chuyển dữ liệu được tuần tự hóa của biểu mẫu đến máy chủ, một hành động phía máy chủ, một trang mới là kết quả của yêu cầu của chúng tôi. Quay lại với các tiêu chuẩn web.Remix cung cấp phần tử
, một phiên bản được tối ưu hóa của biểu mẫu HTML. Với phần tử này và các hàm action
, chúng ta có thể có mã máy khách và mã máy chủ liên quan đến các tuyến đường của mình trong cùng một tệp. Remix sẽ biết cách quản lý giao diện người dùng của các trang của chúng ta và hành vi phía máy chủ được đính kèm vào các yêu cầu. Không có ngữ cảnh, không có quản lý trạng thái.Mặt khác, Next.js dựa vào mã JavaScript để biết cách quản lý trạng thái của ứng dụng, API nào gọi, xác thực lại dữ liệu và cập nhật giao diện của trang web. Khi sử dụng API Routes, chúng ta có thể có các tệp riêng biệt thực thi chức năng phía máy chủ và trả về dữ liệu cho giao diện người dùng của chúng ta.
Như chúng tôi đã nói, và như bạn có thể thấy, Remix có cách biến đổi dữ liệu để cố gắng quay lại những điều cơ bản, gợi nhớ lại những ngày khi PHP là thứ lớn lao.
Phụ thuộc vào Node.js
Như chúng tôi đã nói trước đó, Remix dựa trên Web Fetch API, thay vì phụ thuộc vào Node.js. Điều đó cho chúng ta khả năng chạy các ứng dụng Remix không chỉ trên các máy chủ Node.js (như Vercel hoặc Netlify) mà còn trên các loại nền tảng khác (như Cloudflare Workers hoặc Deno Deploy mới).Với phiên bản mới nhất của Next.js, 12.2, giờ đây bạn có thể chọn Edge Runtime cho toàn bộ dự án Next.js của mình, thay vì sử dụng thời gian chạy Node.js mặc định.
Kết luận
Remix đã trở thành mã nguồn mở cách đây không lâu, nhưng nó đã có một cộng đồng rất tích cực hợp tác và tạo ra các dự án theo các tiêu chuẩn web. Khung này có một tương lai đầy hứa hẹn. Hãy cùng xem nó phát triển như thế nào, những tính năng nào được thêm vào, những dự án liên quan nào được tạo ra để cải thiện trải nghiệm của nhà phát triển và những tình huống nào khác mà nó cố gắng giải quyết.Đọc thêm
- “Remix Routes Demystified,” Átila Fassina
- “Dynamic Data-Fetching In An Authenticated Next.js App,” Caleb Olojo
- “How To Maintenance A Large Next.js Application,” Nirmalya Ghosh
- “Localizing Your Next.js App,” Átila Fassina