ISR (Incremental Static Regeneration) trong NextJS


Ngoài SSR, CSR và SSG còn một cách render nữa mà NextJS support, đó là ISR.


Khi xây dựng các ứng dụng web hiện đại, nâng cao hiệu suất và trải nghiệm người dùng là những yếu tố quan trọng luôn cần xem xét, Trang web tải chậm có thể dẫn đến trải nghiệm người dùng kém và ảnh hưởng đến việc thu hút và giữ chân người dùng. Nếu bạn đang dùng NextJS hãy xem thử tính năng Incremental Static Regeneration - ISR, tính năng cực kì mạnh mẽ sẽ giúp bạn cải tiến việc tạo những trang tĩnh bằng cách cho phép cập nhật trang (Regeneration) theo yêu cầu mà không cần triển khai lại toàn bộ từ đầu.


ISR là gì?


Incremental: gia tăng + Static: trang tĩnh + Regeneration: tái tạo = Tái tạo gia tăng trang tĩnh (J4F)

ISR là một cách tối ưu hóa dựa trên SSG (Static Site Generation), Với SSG, NextJS tạo các trang tĩnh khi triển khai, tạo sẵn các file HTML cho mỗi trang, và khi có request thì chỉ cần trả file HTML mà không cần chạy code gì thêm, đảm bảo tải trang nhanh chóng và thân thiện cho SEO.

Tuy nhiên, vấn đề của các trang HTML tĩnh có thể trở nên lỗi thời khi dữ liệu cơ bản có sự thay đổi. Nếu tạo lại toàn bộ trang để lấy dữ liệu cập nhật mới hơn có thể không phù hợp, đặc biệt là đối với các trang có nội dung thay đổi thường xuyên, chắc bạn không muốn phải deploy hàng ngày đâu nhỉ. Vậy nên ISR xuất hiện để giúp chúng ta.

ISR cho phép chúng ta xác định các trang cụ thể cần cập nhật "định kỳ" mà không cần deploy lại toàn bộ trang. Bạn có thể đặt thời gian "revalidate" (tính bằng giây) cho mỗi trang, chỉ định thời gian NextJS nên kiểm tra cập nhật. Khi có một request mới tới trang được ISR NextJS sẽ lấy trang đã được tạo trước từ bộ nhớ cache và trả về cho người dùng. Và đồng thời nó lên lịch tái tạo nền cho trang đó dựa trên khoảng thời gian được xác định. Có nghĩa là:

  • if (current_time - last_request_time < revalidate)
  • trả về static HTML trong cache
  • current_time = last_request_time
  • else
  • regenerate HTML
  • current_time = last_request_time



Cách ISR Hoạt Động

  1. Initial Static Generation: Trong quá trình triển khai, NextJS tạo trang tĩnh như thông thường, tuân thủ nguyên tắc của SSR
  2. First User Request: Khi người dùng truy cập vào một trang có ISR, NextJS phục vụ tệp HTML đã được tạo trước từ cache.
  3. Background Regeneration: Sau khi yêu cầu ban đầu hoàn thành, NextJS lên lịch tái tạo nền cho trang. Tuy nhiên, nếu có người dùng khác request cùng một trang trước khi khoảng thời gian "revalidate" hết, trang cũ vẫn được phục vụ từ cache.
  4. Subsequent User Requests: Khi đến lượt tái tạo nền, NextJS kiểm tra cập nhật bằng cách lấy dữ liệu mới nhất. Trang sau đó được tái tạo nền và phiên bản mới được lưu trong cache.
  5. Fresh Data on Next Request: Trong request tiếp theo sau khi tái tạo, trang được phục vụ với dữ liệu mới nhất.


Lợi ích của ISR

  • Cập Nhật Thời Gian Thực: ISR cho phép trang phản ánh các thay đổi dữ liệu thời gian thực mà không cần xây dựng lại toàn bộ trang, cung cấp trải nghiệm người dùng động.
  • Phục Vụ Nội Dung Nhanh Hơn: Bằng cách phục vụ các trang HTML tĩnh, thời gian tải lần đầu được giảm đáng kể, đảm bảo việc phục vụ nội dung nhanh chóng.
  • Thân Thiện với SEO: Trang HTML tĩnh cải thiện hạng SEO bằng cách cung cấp nội dung có thể được truy vấn bởi các công cụ tìm kiếm.
  • Hiệu Quả Chi Phí: Với ISR, bạn có thể tiết kiệm tài nguyên và giảm tải máy chủ, tạo ra phương pháp tiết kiệm chi phí.
  • Dễ Dàng Mở Rộng: ISR hoạt động mượt mà với các cập nhật liên tục, làm cho nó dễ dàng mở rộng cho các trang web có nội dung thay đổi thường xuyên.


Cách cài đặt ISR

Để kích hoạt ISR cho một trang cụ thể, bạn cần sử dụng hàm getStaticProps với tùy chọn "revalidate". Giá trị revalidate xác định tần suất NextJS nên kiểm tra cập nhật và tái tạo trang. ISR là nâng cao của SSR, vậy nên với những trang có "dynamic router" cần có getStaticPaths nhé.


function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}
 
// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation is enabled and a new request comes in
export async function getStaticProps() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()
 
  return {
    props: {
      posts,
    },
    // Next.js will attempt to re-generate the page:
    // - When a request comes in
    // - At most once every 10 seconds
    revalidate: 10, // In seconds
  }
}
 
// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// the path has not been generated.
export async function getStaticPaths() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()
 
  // Get the paths we want to pre-render based on posts
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))
 
  // We'll pre-render only these paths at build time.
  // { fallback: 'blocking' } will server-render pages
  // on-demand if the path doesn't exist.
  return { paths, fallback: 'blocking' }
}
 
export default Blog        


Kết Luận


"Tái tạo gia tăng trang tĩnh" (ISR) trong NextJS là một công cụ quan trọng để tối ưu hóa việc tạo các trang tĩnh. Bằng cách cung cấp cập nhật thời gian thực và trang tải nhanh chóng, ISR cải thiện trải nghiệm người dùng trong khi vẫn giữ được lợi ích về SEO. Áp dụng ISR trong các dự án NextJS của bạn giúp tạo ra ứng dụng web có hiệu suất cao, mạnh mẽ và mượt mà. Trang bạn đang đọc này mình cũng đã enable ISR. Hãy để lại bình luận vả góp ý ở cuối trang nhé!


Thanks for reading!