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