เรียนรู้วิธีการใช้ React lazy loading และการแบ่งโค้ดคอมโพเนนต์เพื่อเพิ่มประสิทธิภาพแอปพลิเคชัน ประสบการณ์ผู้ใช้ และลดเวลาโหลดเริ่มต้นอย่างเห็นได้ชัด
React Lazy Loading: เพิ่มประสิทธิภาพด้วยการแบ่งโค้ดคอมโพเนนต์ (Component Code Splitting)
ในวงการการพัฒนาเว็บปัจจุบัน ประสิทธิภาพเป็นสิ่งสำคัญที่สุด ผู้ใช้คาดหวังเวลาในการโหลดที่รวดเร็วและการโต้ตอบที่ราบรื่น JavaScript bundle ขนาดใหญ่ โดยเฉพาะในแอปพลิเคชัน React ที่ซับซ้อน อาจส่งผลกระทบอย่างมากต่อเวลาในการโหลดเริ่มต้นและประสบการณ์โดยรวมของผู้ใช้ หนึ่งในเทคนิคที่ทรงพลังในการจัดการปัญหานี้คือ lazy loading โดยเฉพาะอย่างยิ่งการแบ่งโค้ดคอมโพเนนต์ (component code splitting) บทความนี้จะให้คำแนะนำที่ครอบคลุมเพื่อทำความเข้าใจและนำ React lazy loading ไปใช้งานโดยใช้ React.lazy
และ Suspense
Lazy Loading และ Code Splitting คืออะไร?
Lazy loading หรือที่เรียกว่า on-demand loading เป็นเทคนิคที่เลื่อนการโหลดทรัพยากร (ในกรณีของเราคือ React components) ออกไปจนกว่าจะมีความจำเป็นต้องใช้ แทนที่จะโหลดโค้ดทั้งหมดของแอปพลิเคชันในครั้งเดียว จะมีการโหลดเฉพาะส่วนที่จำเป็นในตอนเริ่มต้น และโค้ดส่วนที่เหลือจะถูกโหลดแบบอะซิงโครนัสเมื่อผู้ใช้ไปยังเส้นทาง (route) ที่ระบุหรือโต้ตอบกับคอมโพเนนต์บางอย่าง สิ่งนี้ช่วยลดขนาด bundle เริ่มต้นได้อย่างมากและปรับปรุงเวลาที่ผู้ใช้สามารถเริ่มโต้ตอบกับหน้าเว็บได้ (time to interactive - TTI)
Code splitting คือกระบวนการแบ่งโค้ดของแอปพลิเคชันออกเป็นส่วนย่อยๆ (bundles) ที่จัดการได้ง่ายขึ้น bundle เหล่านี้สามารถโหลดได้อย่างอิสระและตามความต้องการ React lazy loading ใช้ประโยชน์จาก code splitting เพื่อโหลดคอมโพเนนต์เมื่อจำเป็นเท่านั้น
ประโยชน์ของ Lazy Loading และ Code Splitting
- ปรับปรุงเวลาในการโหลดเริ่มต้น: การลดขนาด bundle เริ่มต้นทำให้เบราว์เซอร์ดาวน์โหลดและประมวลผล JavaScript น้อยลงในตอนแรก ส่งผลให้หน้าเว็บโหลดเร็วขึ้น ซึ่งสำคัญอย่างยิ่งสำหรับผู้ใช้ที่มีการเชื่อมต่ออินเทอร์เน็ตที่ช้าหรือใช้อุปกรณ์ที่มีประสิทธิภาพต่ำ
- เพิ่มประสบการณ์ผู้ใช้ที่ดีขึ้น: เวลาในการโหลดที่เร็วขึ้นนำไปสู่ประสบการณ์ผู้ใช้ที่ตอบสนองและน่าพึงพอใจยิ่งขึ้น ช่วยลดอัตราการออกจากหน้าเว็บ (bounce rates) และเพิ่มการมีส่วนร่วมของผู้ใช้
- ลดการใช้ทรัพยากร: การโหลดเฉพาะโค้ดที่จำเป็นช่วยลดการใช้หน่วยความจำของแอปพลิเคชัน ซึ่งเป็นประโยชน์อย่างยิ่งสำหรับอุปกรณ์พกพา
- SEO ที่ดีขึ้น: เครื่องมือค้นหาชื่นชอบเว็บไซต์ที่มีเวลาโหลดเร็ว ซึ่งอาจช่วยปรับปรุงอันดับเว็บไซต์ของคุณในผลการค้นหาได้
การนำ React Lazy Loading ไปใช้งานด้วย React.lazy
และ Suspense
React มีกลไกในตัวสำหรับการทำ lazy loading คอมโพเนนต์โดยใช้ React.lazy
และ Suspense
โดย React.lazy
ช่วยให้คุณสามารถ import คอมโพเนนต์แบบไดนามิกได้ ในขณะที่ Suspense
เป็นวิธีในการแสดง UI สำรอง (fallback UI) ในขณะที่คอมโพเนนต์กำลังโหลด
ขั้นตอนที่ 1: การทำ Dynamic Imports ด้วย React.lazy
React.lazy
รับฟังก์ชันที่เรียกใช้ import()
ซึ่ง import()
เป็น dynamic import ที่จะคืนค่าเป็น Promise ซึ่งจะ resolve เป็นโมดูลที่ประกอบด้วยคอมโพเนนต์ที่คุณต้องการทำ lazy load
import React, { lazy, Suspense } from 'react';
const MyComponent = lazy(() => import('./MyComponent'));
ในตัวอย่างนี้ MyComponent
จะยังไม่ถูกโหลดจนกว่าจะถูก render คำสั่ง import('./MyComponent')
จะทำการ import คอมโพเนนต์จากไฟล์ ./MyComponent
แบบไดนามิก โปรดทราบว่า path ที่ระบุเป็นแบบสัมพัทธ์กับไฟล์ปัจจุบัน
ขั้นตอนที่ 2: การใช้ Suspense
เพื่อจัดการสถานะการโหลด
เนื่องจากการทำ lazy loading เกี่ยวข้องกับการโหลดคอมโพเนนต์แบบอะซิงโครนัส คุณจึงต้องมีวิธีจัดการสถานะการโหลดและแสดง UI สำรองในขณะที่กำลังดึงคอมโพเนนต์ นี่คือจุดที่ Suspense
เข้ามามีบทบาท Suspense
เป็นคอมโพเนนต์ของ React ที่ช่วยให้คุณ "พัก" การ render ของ children ของมันไว้จนกว่าจะพร้อม โดยจะรับ prop ชื่อ fallback
ซึ่งระบุ UI ที่จะแสดงในขณะที่ children กำลังโหลด
import React, { lazy, Suspense } from 'react';
const MyComponent = lazy(() => import('./MyComponent'));
function App() {
return (
Loading...
ในตัวอย่างนี้ คอมโพเนนต์ Suspense
จะห่อหุ้ม MyComponent
ไว้ ในขณะที่ MyComponent
กำลังโหลด fallback
prop (
) จะถูกแสดงผล และเมื่อ MyComponent
โหลดเสร็จสิ้น มันจะเข้ามาแทนที่ UI สำรองนั้น
ตัวอย่าง: การทำ Lazy Loading กับ Route ในแอปพลิเคชัน React Router
Lazy loading มีประโยชน์อย่างยิ่งสำหรับ route ในแอปพลิเคชัน React Router คุณสามารถทำ lazy load ทั้งหน้าหรือบางส่วนของแอปพลิเคชันได้ ซึ่งช่วยปรับปรุงเวลาโหลดเริ่มต้นของเว็บไซต์ของคุณ
import React, { lazy, Suspense } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));
const Contact = lazy(() => import('./pages/Contact'));
function App() {
return (
Loading...