กำหนดเส้นทางการดึงข้อมูลล่วงหน้าใน Next.js

วิธีที่ Next.js เร่งความเร็วในการไปยังส่วนต่างๆ ด้วยการโหลดเส้นทางล่วงหน้า และวิธีปรับแต่ง

สิ่งที่คุณจะได้เรียนรู้

ในโพสต์นี้ คุณจะได้เรียนรู้วิธีการทำงานของการกำหนดเส้นทางใน Next.js, การเพิ่มประสิทธิภาพเพื่อความเร็ว และวิธีปรับแต่งให้เหมาะกับความต้องการของคุณมากที่สุด

ใน Next.js คุณไม่จำเป็นต้องตั้งค่าการกำหนดเส้นทางด้วยตนเอง Next.js ใช้การกำหนดเส้นทางตามระบบไฟล์ ซึ่งช่วยให้คุณสร้างไฟล์และโฟลเดอร์ในไดเรกทอรี ./pages/ ได้ดังนี้

ภาพหน้าจอของไดเรกทอรีหน้าเว็บที่มี 3 ไฟล์ ได้แก่ index.js, margherita.js และ pineapple-pizza.js

หากต้องการลิงก์ไปยังหน้าต่างๆ ให้ใช้คอมโพเนนต์ <Link> โดยทำคล้ายกับการใช้องค์ประกอบ <a> แบบเก่า ดังนี้

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

เมื่อคุณใช้คอมโพเนนต์ <Link> เพื่อการนําทาง Next.js จะทํางานให้คุณมากกว่าเดิมเล็กน้อย โดยปกติแล้ว ระบบจะดาวน์โหลดหน้าเว็บเมื่อคุณไปยังหน้านั้นผ่านลิงก์ แต่ Next.js จะโหลด JavaScript ที่จำเป็นในการแสดงผลหน้าเว็บล่วงหน้าโดยอัตโนมัติ

เมื่อคุณโหลดหน้าเว็บที่มีลิงก์เพียงไม่กี่ลิงก์ เป็นไปได้ว่าเมื่อคุณติดตามลิงก์ ระบบจะดึงข้อมูลคอมโพเนนต์ที่อยู่เบื้องหลังลิงก์นั้นไปแล้ว ซึ่งจะช่วยปรับปรุงการตอบสนองของแอปพลิเคชันโดยการทําให้ไปยังหน้าใหม่ได้เร็วขึ้น

ในแอปตัวอย่างด้านล่าง หน้า index.js ลิงก์ไปยัง margherita.js ด้วย <Link> ดังนี้

ใช้เครื่องมือสำหรับนักพัฒนาเว็บใน Chrome เพื่อยืนยันว่ามีการเรียกข้อมูล margherita.js ล่วงหน้าแล้ว โดยทำดังนี้ 1. หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกดเต็มหน้าจอ เต็มหน้าจอ

  1. กดแป้น Control+Shift+J (หรือ Command+Option+J ใน Mac) เพื่อเปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์
  2. คลิกแท็บเครือข่าย

  3. เลือกช่องทำเครื่องหมายปิดใช้แคช

  4. โหลดหน้าเว็บซ้ำ

เมื่อโหลด index.js แท็บเครือข่ายจะแสดงว่า margherita.js ได้รับการดาวน์โหลดด้วย

แท็บเครือข่ายของเครื่องมือสําหรับนักพัฒนาเว็บที่ไฮไลต์ margherita.js

วิธีการทำงานของการโหลดล่วงหน้าอัตโนมัติ

Next.js จะโหลดล่วงหน้าเฉพาะลิงก์ที่ปรากฏในวิวพอร์ต และใช้ Intersection Observer API เพื่อตรวจหาลิงก์เหล่านั้น นอกจากนี้ ยังปิดใช้การอ่านล่วงหน้าเมื่อการเชื่อมต่อเครือข่ายช้า หรือเมื่อผู้ใช้เปิดSave-Dataไว้ จากการตรวจสอบเหล่านี้ Next.js จะแทรกแท็ก <link rel="preload"> แบบไดนามิกเพื่อดาวน์โหลดคอมโพเนนต์สำหรับการนําทางในภายหลัง

Next.js จะดึงข้อมูล JavaScript เท่านั้น แต่จะไม่ได้เรียกใช้ วิธีนี้จะทำให้ไม่ต้องดาวน์โหลดเนื้อหาเพิ่มเติมที่หน้าเว็บที่โหลดล่วงหน้าอาจขอจนกว่าคุณจะเข้าชมลิงก์

หลีกเลี่ยงการอ่านล่วงหน้าที่ไม่จำเป็น

หากต้องการหลีกเลี่ยงการดาวน์โหลดเนื้อหาที่ไม่จำเป็น คุณสามารถปิดใช้การโหลดล่วงหน้าสำหรับหน้าที่เข้าชมนานๆ ครั้งได้โดยตั้งค่าพร็อพเพอร์ตี้ prefetch ใน <Link> เป็น false ดังนี้

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

ในแอปตัวอย่างที่ 2 นี้ หน้า index.js มี <Link> ไปยัง pineapple-pizza.js โดยตั้งค่า prefetch เป็น false

หากต้องการตรวจสอบกิจกรรมเครือข่าย ให้ทำตามขั้นตอนจากตัวอย่างแรก เมื่อคุณโหลด index.js แท็บเครือข่ายของเครื่องมือสําหรับนักพัฒนาเว็บจะแสดงว่ามีการดาวน์โหลด margherita.js แต่ไม่ได้ดาวน์โหลด pineapple-pizza.js

แท็บเครือข่ายของเครื่องมือสําหรับนักพัฒนาเว็บที่ไฮไลต์ margherita.js

การเรียกข้อมูลล่วงหน้าด้วยการกำหนดเส้นทางที่กำหนดเอง

คอมโพเนนต์ <Link> เหมาะสำหรับกรณีการใช้งานส่วนใหญ่ แต่คุณก็สร้างคอมโพเนนต์ของคุณเองเพื่อกำหนดเส้นทางได้เช่นกัน Next.js ช่วยให้คุณดำเนินการนี้ได้ง่ายขึ้นด้วย Route API ที่มีให้ใช้งานใน next/router หากต้องการดําเนินการบางอย่าง (เช่น ส่งแบบฟอร์ม) ก่อนไปยังเส้นทางใหม่ คุณสามารถกําหนดการดำเนินการนั้นในโค้ดการกำหนดเส้นทางที่กําหนดเอง

เมื่อใช้คอมโพเนนต์ที่กําหนดเองสำหรับการกำหนดเส้นทาง คุณจะเพิ่มการจําล่วงหน้าลงในคอมโพเนนต์เหล่านั้นได้ด้วย หากต้องการใช้การเรียกข้อมูลล่วงหน้าในโค้ดการกำหนดเส้นทาง ให้ใช้เมธอด prefetch จาก useRouter

ลองดู components/MyLink.js ในแอปตัวอย่างนี้

การเรียกข้อมูลล่วงหน้าจะดำเนินการภายในฮุก useEffect หากตั้งค่าพร็อพเพอร์ตี้ prefetch ใน <MyLink> เป็น true ระบบจะดึงข้อมูลเส้นทางที่ระบุไว้ในพร็อพเพอร์ตี้ href ล่วงหน้าเมื่อแสดงผล <MyLink> นั้น

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

เมื่อคลิกลิงก์ ระบบจะกำหนดเส้นทางใน handleClick ระบบจะบันทึกข้อความลงในคอนโซล และเมธอด push จะไปยังเส้นทางใหม่ที่ระบุใน href

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

ในตัวอย่างนี้ หน้า index.js มี <MyLink> ไปยัง margherita.js และ pineapple-pizza.js พร็อพเพอร์ตี้ prefetch มีการตั้งค่าเป็น true ในวันที่ /margherita และตั้งค่าเป็น false ในวันที่ /pineapple-pizza

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

เมื่อคุณโหลด index.js แท็บเครือข่ายจะแสดงว่า margherita.js มีการดาวน์โหลดแล้ว แต่ pineapple-pizza.js ไม่มีการดาวน์โหลด

แท็บเครือข่ายของเครื่องมือสําหรับนักพัฒนาเว็บที่ไฮไลต์ margherita.js

เมื่อคลิกลิงก์ใดลิงก์หนึ่ง คอนโซลจะบันทึก "สนุกกับ Next.js" และไปยังเส้นทางใหม่

คอนโซลเครื่องมือสำหรับนักพัฒนาเว็บแสดงข้อความ &quot;สนุกกับ Next.js&quot;

บทสรุป

เมื่อคุณใช้ <Link> ทาง Next.js จะดึงข้อมูล JavaScript ล่วงหน้าโดยอัตโนมัติที่จําเป็นต่อการแสดงผลหน้าเว็บที่ลิงก์ ซึ่งทําให้ไปยังหน้าใหม่ได้เร็วขึ้น หากใช้การกำหนดเส้นทางที่กำหนดเอง คุณสามารถใช้ Next.js router API เพื่อติดตั้งใช้งานการเรียกข้อมูลล่วงหน้าด้วยตนเอง หลีกเลี่ยงการดาวน์โหลดเนื้อหาโดยไม่จำเป็นด้วยการปิดใช้การโหลดล่วงหน้าสำหรับหน้าที่เข้าชมนานๆ ครั้ง