วิธีเพิ่มความเร็วให้แอป Next.js ด้วยกลยุทธ์การแยกโค้ดและการโหลดอัจฉริยะ
สิ่งที่คุณจะได้เรียนรู้
โพสต์นี้จะอธิบายโค้ดประเภทต่างๆ การแยกและวิธีใช้ การนำเข้าแบบไดนามิกเพื่อให้แอป Next.js ของคุณเร็วขึ้น
การแยกโค้ดตามเส้นทางและตามคอมโพเนนต์
โดยค่าเริ่มต้น Next.js จะแบ่ง JavaScript ออกเป็นส่วนย่อยๆ สำหรับแต่ละเส้นทาง เมื่อผู้ใช้โหลดแอปพลิเคชัน Next.js จะส่งเฉพาะโค้ดที่จำเป็นสำหรับ เส้นทางเริ่มต้น เมื่อผู้ใช้ไปยังส่วนต่างๆ ของแอปพลิเคชัน ระบบจะดึงข้อมูลชิ้นส่วน ที่เชื่อมโยงกับเส้นทางอื่นๆ การแยกโค้ดแบบตามเส้นทางช่วยลด จำนวนสคริปต์ที่ต้องแยกวิเคราะห์และคอมไพล์ในครั้งเดียว ซึ่งทำให้ โหลดหน้าเว็บได้เร็วขึ้น
แม้ว่าการแยกโค้ดตามเส้นทางเป็นค่าเริ่มต้นที่ดีแล้ว คุณยังสามารถเพิ่มประสิทธิภาพ กระบวนการโหลดด้วยการแยกโค้ดในระดับคอมโพเนนต์ หากคุณมี คอมโพเนนต์ในแอปของคุณ คุณควรแบ่งองค์ประกอบออกเป็นส่วนย่อยๆ วิธีนี้จะทำให้คอมโพเนนต์ขนาดใหญ่ที่ไม่สำคัญหรือแสดงในบางรายการเท่านั้น การโต้ตอบของผู้ใช้ (เช่น การคลิกปุ่ม) อาจเป็นแบบ Lazy Loading
Next.js รองรับไดนามิก import()
ซึ่งจะช่วยให้คุณนำเข้าโมดูล JavaScript (รวมถึงคอมโพเนนต์ React) ได้
แบบไดนามิก และโหลดการนำเข้าแต่ละรายการเป็นกลุ่มแยกกัน ซึ่งจะให้
การแยกโค้ดระดับคอมโพเนนต์และช่วยให้คุณสามารถควบคุมการโหลดทรัพยากร
ให้ผู้ใช้ดาวน์โหลดโค้ดที่จำเป็นสำหรับบางส่วนของเว็บไซต์ที่
ที่ผู้ใช้กำลังดูอยู่ ใน Next.js คอมโพเนนต์เหล่านี้จะแสดงผลฝั่งเซิร์ฟเวอร์
(SSR)
โดยค่าเริ่มต้น
การทํางานของการนําเข้าแบบไดนามิก
โพสต์นี้มีตัวอย่างแอปหลายๆ เวอร์ชันที่ประกอบด้วย ได้ด้วยปุ่มเดียว เมื่อคลิกที่ปุ่ม คุณจะเห็นลูกสุนัขน่ารักๆ อาส เมื่อคุณไปยังส่วนต่างๆ ของแอปแต่ละเวอร์ชัน คุณจะเห็นว่าการนำเข้าแบบไดนามิกเป็นอย่างไร ต่างจากคงที่ นำเข้า และวิธีทำงานกับพวกเขา
ในแอปเวอร์ชันแรก ลูกสุนัขจะอยู่ที่ components/Puppy.js
ถึง
แสดงลูกสุนัขในหน้าเว็บ แอปนำเข้าคอมโพเนนต์ Puppy
ใน
index.js
ที่มีข้อความนำเข้าแบบคงที่ ให้ทำดังนี้
import Puppy from "../components/Puppy";
หากต้องการดูว่า Next.js รวมแอปเข้าด้วยกันอย่างไร ให้ตรวจสอบการติดตามเครือข่ายในเครื่องมือสำหรับนักพัฒนาเว็บ
หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกด เต็มหน้าจอ
กด "Control+Shift+J" (หรือ "Command+Option+J" ใน Mac) เพื่อเปิดเครื่องมือสำหรับนักพัฒนาเว็บ
คลิกแท็บเครือข่าย
เลือกช่องทำเครื่องหมายปิดใช้แคช
โหลดหน้าเว็บซ้ำ
เมื่อคุณโหลดหน้าเว็บ โค้ดที่จำเป็นทั้งหมด รวมถึง Puppy.js
คอมโพเนนต์ ถูกรวมกลุ่มใน index.js
:
เมื่อคุณกดปุ่มคลิกฉัน จะมีเพียงคำขอไฟล์ JPEG ลูกสุนัขเท่านั้น ที่เพิ่มลงในแท็บเครือข่ายแล้ว ให้ทำดังนี้
ข้อเสียของวิธีนี้ก็คือ แม้ว่าผู้ใช้จะไม่คลิกปุ่มเพื่อ
เห็นลูกสุนัขจะต้องโหลดคอมโพเนนต์ Puppy
เนื่องจากมีองค์ประกอบอยู่ใน
index.js
ในตัวอย่างเล็กๆ นี้ นั่นไม่ใช่เรื่องใหญ่ แต่เป็นเรื่องของชีวิตจริง
แอปพลิเคชันส่วนใหญ่มักมีการปรับปรุงครั้งใหญ่ให้โหลด
คอมโพเนนต์ขนาดใหญ่ก็ต่อเมื่อ
ตามความจำเป็น
คราวนี้มาดูแอปเวอร์ชันที่ 2 ซึ่งมีการนำเข้าแบบคงที่
แทนที่ด้วยการนำเข้าแบบไดนามิก Next.js มี next/dynamic
ซึ่งทำให้
สามารถใช้การนำเข้าแบบไดนามิกสำหรับคอมโพเนนต์ใดๆ ใน "ถัดไป" ได้ดังนี้
import Puppy from "../components/Puppy";
import dynamic from "next/dynamic";
// ...
const Puppy = dynamic(import("../components/Puppy"));
ทำตามขั้นตอนจากตัวอย่างแรกเพื่อตรวจสอบการติดตามเครือข่าย
เมื่อคุณโหลดแอปเป็นครั้งแรก ระบบจะดาวน์โหลดเฉพาะ index.js
เท่านั้น เวลานี้
เล็กลง 0.5 KB (ลดลงจาก 37.9 KB เป็น 37.4 KB) เพราะว่า
ไม่รวมโค้ดสำหรับคอมโพเนนต์ Puppy
:
ตอนนี้คอมโพเนนต์ Puppy
ได้รวมอยู่ในกลุ่มแยกต่างหาก ซึ่งก็คือ 1.js
แล้ว ซึ่งจะโหลดขึ้นมาเท่านั้น
เมื่อคุณกดปุ่ม
ในการใช้งานจริง คอมโพเนนต์มักมาก ใหญ่ขึ้น และการโหลดแบบ Lazy Loading สามารถตัดเพย์โหลด JavaScript เริ่มต้นได้หลายร้อยกิโลไบต์
การนําเข้าแบบไดนามิกที่มีสัญญาณบอกสถานะการโหลดที่กําหนดเอง
เมื่อโหลดทรัพยากรแบบ Lazy Loading คุณควรใส่สัญญาณบอกสถานะการโหลดด้วย
ในกรณีที่เกิดความล่าช้า ใน Next.js คุณสามารถทำได้โดยการระบุ
อาร์กิวเมนต์เพิ่มเติมไปยังฟังก์ชัน dynamic()
:
const Puppy = dynamic(() => import("../components/Puppy"), {
loading: () => <p>Loading...</p>
});
หากต้องการดูการทำงานของตัวบอกการโหลด ให้จำลองการเชื่อมต่อเครือข่ายที่ช้าใน เครื่องมือสำหรับนักพัฒนาเว็บ:
หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกด เต็มหน้าจอ
กด "Control+Shift+J" (หรือ "Command+Option+J" ใน Mac) เพื่อเปิดเครื่องมือสำหรับนักพัฒนาเว็บ
คลิกแท็บเครือข่าย
เลือกช่องทำเครื่องหมายปิดใช้แคช
ในรายการแบบเลื่อนลงการควบคุม ให้เลือก 3G ที่รวดเร็ว
กดปุ่มคลิกฉัน
ตอนนี้เมื่อคุณคลิกปุ่ม จะใช้เวลาสักครู่ในการโหลดคอมโพเนนต์และแอป จะแสดงปุ่ม "กำลังโหลด..." ในระหว่างนี้
การนำเข้าแบบไดนามิกที่ไม่มี SSR
หากต้องการแสดงผลคอมโพเนนต์เฉพาะบนฝั่งไคลเอ็นต์ (เช่น แชท
ใหม่) ก็ทำได้โดยตั้งค่าตัวเลือก ssr
เป็น false
const Puppy = dynamic(() => import("../components/Puppy"), {
ssr: false,
});
บทสรุป
Next.js จะให้โค้ดระดับคอมโพเนนต์ที่รองรับการนำเข้าแบบไดนามิก การแยก ซึ่งสามารถลดเพย์โหลด JavaScript และปรับปรุงแอปพลิเคชัน ความเร็วในการโหลด คอมโพเนนต์ทั้งหมดจะมีการแสดงผลฝั่งเซิร์ฟเวอร์โดยค่าเริ่มต้น และคุณสามารถ ให้ปิดใช้งานตัวเลือกนี้เมื่อจำเป็น