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

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

Bạn sẽ học được gì?

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ối ưu hoá tính năng này để tăng tốc độ và cách tuỳ chỉnh tính năng này sao 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/:

Ảnh chụp màn hình 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 sử dụng thành phần <Link>, tương tự như cách bạn sử 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 nhấp vào đườ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 để hiển thị trang.

Khi bạn tải một trang có một vài đường liên kết, rất có thể khi bạn nhấ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 thao tác điều hướng đến các trang mới nhanh hơn.

Trong ứng dụng mẫu dưới đây, 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. Sau đó, nhấn vào biểu tượng Màn hình toàn cảnh toàn màn hình.

  1. Nhấn tổ hợp phím `Ctrl+Shift+J` (hoặc `Command+Option+J` trên máy Mac) để mở DevTools.
  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 sẽ cho thấy margherita.js cũng được tải xuống:

Thẻ Mạng trong Công cụ của Chrome 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ự động tìm nạp trước

Next.js chỉ tải trước các đường liên kết xuất hiện trong khung nhìn và sử dụng Intersection Observer API để phát hiện các đường liên kết đó. Chế độ này cũng tắt tính năng tìm nạp trước khi kết nối mạng bị chậm hoặc khi người dùng bật Save-Data. Dựa trên các bước kiểm tra này, Next.js sẽ chèn động các 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 đó, trình duyệt sẽ không tải xuống 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ải trước không cần thiết

Để tránh tải nội dung không cần thiết, bạn có thể tắt tính năng tìm nạp trước cho các trang hiếm khi 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<Link> đến 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 trong DevTools cho biết margherita.js đã được tải xuống nhưng pineapple-pizza.js thì không:

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

Tìm nạp trước bằng tính nă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 để định tuyến. Next.js giúp bạn dễ dàng thực hiện việc này bằng API bộ định tuyến có trong next/router. Nếu muốn làm gì đó (ví dụ: gửi biểu mẫu) trước khi chuyển đến một tuyến mới, bạn có thể xác định việc đó 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ải trước vào các thành phần đó. Để triển khai tính năng tải 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 mẫu này:

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

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ẽ được thực hiện 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ẽ điều hướng đến tuyến 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 mẫu 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ẻ Network (Mạng) sẽ cho biết margherita.js đã được tải xuống và pineapple-pizza.js chưa được tải xuống:

Thẻ Mạng trong Công cụ của Chrome 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, Console sẽ ghi lại "Having fun with Next.js" (Tận hưởng Next.js) và chuyển đến tuyến 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;Chúc bạn vui vẻ với Next.js&quot;.

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 điều hướng đến các trang mới 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ải 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ải trước cho các trang hiếm khi được truy cập.