Tìm nạp trước tuyến đường trong Next.js

Cách Next.js tăng tốc quá trình điều hướng bằng tính năng tìm nạp trước tuyến đường và cách tuỳ chỉnh tính năng này.

Trong bài đăng này, bạn sẽ tìm hiểu cách hoạt động của tính năng định tuyến trong Next.js, cách tính năng này được tối ưu hoá về tốc độ và cách tuỳ chỉnh tính năng này cho phù hợp nhất với nhu cầu của bạn.

Trong Next.js, bạn không cần thiết lập định tuyến theo cách thủ công. Next.js sử dụng tính năng định tuyến dựa trên hệ thống tệp, cho phép bạn chỉ cần tạo các tệp và thư mục bên trong thư mục ./pages/:

Thư mục pages chứa 3 tệp: index.js, margherita.js và pineapple-pizza.js.

Để liên kết đến các trang khác nhau, hãy dùng thành phần <Link>, tương tự như cách bạn dùng phần tử <a> cũ:

<Link href="/margherita">
  <a>Margherita</a>
</Link>

Khi bạn sử dụng thành phần <Link> để điều hướng, Next.js sẽ làm thêm một chút cho bạn. Thông thường, một trang sẽ được tải xuống khi bạn truy cập vào một đường liên kết đến trang đó, nhưng Next.js sẽ tự động tìm nạp trước JavaScript cần thiết để kết xuất trang.

Khi bạn tải một trang có một vài đường liên kết, có thể là khi bạn truy cập vào một đường liên kết, thành phần đằng sau đường liên kết đó đã được tìm nạp. Điều này giúp cải thiện khả năng phản hồi của ứng dụng bằng cách giúp việc chuyển đến các trang mới diễn ra nhanh hơn.

Trong ứng dụng ví dụ, trang index.js liên kết đến margherita.js bằng <Link>:

Sử dụng Công cụ của Chrome cho nhà phát triển để xác minh rằng margherita.js được tìm nạp trước: 1. Để xem trước trang web, hãy nhấn vào Xem ứng dụng, rồi nhấn vào Toàn màn hình toàn màn hình.

  1. Mở Công cụ cho nhà phát triển của Chrome.
  2. Nhấp vào thẻ Mạng.
  3. Chọn hộp đánh dấu Tắt bộ nhớ đệm.
  4. Tải lại trang.

Khi bạn tải index.js, thẻ Mạng cho thấy margherita.js cũng được tải xuống:

Thẻ Mạng của Công cụ cho nhà phát triển, trong đó margherita.js được làm nổi bật.

Cách hoạt động của tính năng tìm nạp trước tự động

Next.js chỉ tìm nạp trước những đường liên kết xuất hiện trong khung hiển thị và sử dụng Intersection Observer API để phát hiện các đường liên kết đó. Thao tác này cũng sẽ tắt tính năng tìm nạp trước khi kết nối mạng chậm hoặc khi người dùng đã bật chế độ Save-Data. Dựa trên các quy trình kiểm tra này, Next.js sẽ tự động chèn thẻ <link rel="preload"> để tải các thành phần xuống cho các thao tác điều hướng tiếp theo.

Next.js chỉ tìm nạp JavaScript chứ không thực thi JavaScript. Bằng cách đó, trang sẽ không tải xuống bất kỳ nội dung bổ sung nào mà trang được tìm nạp trước có thể yêu cầu cho đến khi bạn truy cập vào đường liên kết.

Tránh tìm nạp trước không cần thiết

Để tránh tải nội dung không cần thiết xuống, bạn có thể tắt tính năng tìm nạp trước cho các trang hiếm khi được truy cập bằng cách đặt thuộc tính prefetch trên <Link> thành false:

<Link href="/pineapple-pizza" prefetch={false}>
  <a>Pineapple pizza</a>
</Link>

Trong ứng dụng ví dụ thứ hai này, trang index.js có một <Link> thành pineapple-pizza.js với prefetch được đặt thành false:

Để kiểm tra hoạt động mạng, hãy làm theo các bước trong ví dụ đầu tiên. Khi bạn tải index.js, thẻ Mạng của Công cụ cho nhà phát triển cho thấy margherita.js đã được tải xuống, nhưng pineapple-pizza.js thì không:

Thẻ Mạng của Công cụ cho nhà phát triển, trong đó margherita.js được làm nổi bật.

Tìm nạp trước bằng định tuyến tuỳ chỉnh

Thành phần <Link> phù hợp với hầu hết các trường hợp sử dụng, nhưng bạn cũng có thể tạo thành phần của riêng mình để thực hiện định tuyến. Next.js giúp bạn thực hiện việc này dễ dàng hơn bằng API bộ định tuyến có trong next/router. Nếu muốn làm điều gì đó (ví dụ: gửi biểu mẫu) trước khi chuyển đến một tuyến đường mới, bạn có thể xác định điều đó trong mã định tuyến tuỳ chỉnh.

Khi sử dụng các thành phần tuỳ chỉnh để định tuyến, bạn cũng có thể thêm tính năng tìm nạp trước vào các thành phần đó. Để triển khai tính năng tìm nạp trước trong mã định tuyến, hãy sử dụng phương thức prefetch từ useRouter.

Hãy xem components/MyLink.js trong ứng dụng minh hoạ này:

Việc tìm nạp trước được thực hiện bên trong hook useEffect. Nếu bạn đặt thuộc tính prefetch trên một <MyLink> thành true, thì tuyến đường được chỉ định trong thuộc tính href sẽ được tìm nạp trước khi <MyLink> đó được kết xuất:

useEffect(() => {
    if (prefetch) router.prefetch(href)
});

Khi bạn nhấp vào đường liên kết, quá trình định tuyến sẽ diễn ra trong handleClick. Một thông báo sẽ được ghi vào bảng điều khiển và phương thức push sẽ chuyển đến tuyến đường mới được chỉ định trong href:

const handleClick = e => {
    e.preventDefault();
    console.log("Having fun with Next.js.");
    router.push(href);
};

Trong ứng dụng ví dụ này, trang index.js<MyLink> đến margherita.jspineapple-pizza.js. Thuộc tính prefetch được đặt thành true trên /margherita và thành false trên /pineapple-pizza.

<MyLink href="/margherita" title="Margherita" prefetch={true} />
<MyLink href="/pineapple-pizza"  title="Pineapple pizza" prefetch={false} />

Khi bạn tải index.js, thẻ Mạng cho thấy rằng margherita.js đã được tải xuống và pineapple-pizza.js thì chưa:

Thẻ Mạng của Công cụ cho nhà phát triển, trong đó margherita.js được làm nổi bật.

Khi bạn nhấp vào một trong hai đường liên kết này, Bảng điều khiển sẽ ghi nhật ký "Having fun with Next.js" (Vui vẻ với Next.js) và chuyển đến tuyến đường mới:

Bảng điều khiển Công cụ cho nhà phát triển hiển thị thông báo &quot;Having fun with Next.js.&quot; (Vui vẻ với Next.js.)

Kết luận

Khi bạn sử dụng <Link>, Next.js sẽ tự động tìm nạp trước JavaScript cần thiết để hiển thị trang được liên kết, giúp việc chuyển đến các trang mới diễn ra nhanh hơn. Nếu đang sử dụng tính năng định tuyến tuỳ chỉnh, bạn có thể sử dụng API bộ định tuyến Next.js để tự triển khai tính năng tìm nạp trước. Tránh tải nội dung xuống không cần thiết bằng cách tắt tính năng tìm nạp trước cho những trang hiếm khi được truy cập.