useMemo และ useCallback เพื่อประสิทธิภาพ
จดจำผลการคำนวณที่ใช้เวลานานด้วย useMemo และจดจำการอ้างอิงฟังก์ชันที่คงที่ด้วย useCallback เพื่อป้องกันการเรนเดอร์ซ้ำของคอมโพเนนต์ลูกโดยไม่จำเป็น
useMemo และ useCallback เพื่อประสิทธิภาพ เป็นบทเรียน Frontend Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Frontend Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน
พฤติกรรมเริ่มต้นของ React
โดยค่าเริ่มต้น React จะเรนเดอร์คอมโพเนนต์ใหม่ทุกครั้งที่สถานะของคอมโพเนนต์หรือคอมโพเนนต์แม่เรนเดอร์ใหม่ คอมโพเนนต์ลูกก็จะเรนเดอร์ใหม่เช่นกัน แม้พร็อพจะไม่เปลี่ยน สำหรับคอมโพเนนต์ส่วนใหญ่ นี่ไม่ใช่ปัญหา เพราะ React ทำงานได้รวดเร็ว
useMemo — จดจำค่าที่คำนวณใช้ทรัพยากรมาก
useMemo(fn, deps) แคชผลลัพธ์ของการคำนวณ ฟังก์ชันจะทำงานเฉพาะเมื่อการพึ่งพาเปลี่ยน ใช้สำหรับการคำนวณที่ใช้ทรัพยากรมากและไม่คุ้มค่าที่จะทำซ้ำในการเรนเดอร์ทุกครั้ง
const expensiveResult = useMemo(() => {
return items.filter(item => item.category === category).sort((a, b) => a.price - b.price);
}, [items, category]);
// Only recalculates when items or category changesuseCallback — จดจำฟังก์ชัน
useCallback(fn, deps) จะคืนค่าฟังก์ชันที่จดจำไว้และคงการอ้างอิงเดิมไว้ เว้นแต่การพึ่งพาจะเปลี่ยน ใช้เมื่อต้องส่งฟังก์ชันเรียกกลับให้คอมโพเนนต์ที่ซ้อนกันหลายชั้นหรือคอมโพเนนต์ที่จดจำไว้
const handleDelete = useCallback((id: string) => {
setItems(prev => prev.filter(item => item.id !== id));
}, []); // stable reference — empty deps because only setItems is used
<ItemList items={items} onDelete={handleDelete} />React.memo — ข้ามการเรนเดอร์ใหม่
React.memo(Component) ครอบคอมโพเนนต์ไว้ เพื่อให้คอมโพเนนต์เรนเดอร์ใหม่เฉพาะเมื่อพร็อพเปลี่ยน (เปรียบเทียบแบบตื้น) ใช้ร่วมกับ useCallback เพื่อให้พร็อพฟังก์ชันเรียกกลับมีการอ้างอิงที่คงที่
const MemoItem = React.memo(function Item({ text, onDelete }: ItemProps) {
console.log('Item rendered:', text); // only logs when props change
return <li>{text} <button onClick={onDelete}>×</button></li>;
});
// onDelete must be stable (from useCallback) for memo to helpเมื่อไม่ควรปรับประสิทธิภาพ (NOT)
การปรับประสิทธิภาพเร็วเกินไปเป็นกับดัก useMemo และ useCallback มีต้นทุน ทั้งการสร้างคลอเชอร์และการเปรียบเทียบการพึ่งพา สำหรับการทำงานที่มีต้นทุนต่ำ เช่น การกรองรายการ 10 รายการ ต้นทุนส่วนเกินอาจมากกว่าประโยชน์ ควรปรับประสิทธิภาพเมื่อวัดแล้วพบปัญหาด้านประสิทธิภาพจริง
วัดประสิทธิภาพก่อนปรับปรุง
ใช้ตัวสร้างโปรไฟล์ของ React DevTools เพื่อวัดเวลาเรนเดอร์จริงก่อนเพิ่มการจดจำ ตัวสร้างโปรไฟล์จะแสดงว่าคอมโพเนนต์ใดใช้เวลานานที่สุดและเรนเดอร์กี่ครั้ง แก้ไขจากหลักฐาน ไม่ใช่จากการคาดเดา
useMemo สำหรับการอ้างอิงที่คงที่
useMemo ยังมีประโยชน์สำหรับทำให้การอ้างอิงคงที่ ไม่ใช่เพื่อเพิ่มประสิทธิภาพของการคำนวณโดยตรง แต่เพื่อป้องกันไม่ให้การจดจำหรือเอฟเฟกต์ปลายทางทำงานซ้ำโดยไม่จำเป็น
// Without useMemo, this creates a new array every render:
const config = useMemo(() => ({ endpoint: '/api', timeout: 5000 }), []);
// Without memoization, useEffect would re-run on every render:
useEffect(() => { initSDK(config); }, [config]);การพึ่งพาของ useCallback
useCallback ใช้กฎการพึ่งพาเดียวกับ useEffect ให้ใส่ตัวแปรทุกตัวจากขอบเขตภายนอกที่ฟังก์ชันเรียกกลับใช้ ตัวตั้งค่าสถานะ (จาก useState) มีความคงที่เสมอ จึงไม่จำเป็นต้องใส่ไว้ในการพึ่งพา
ความสัมพันธ์ระหว่าง useMemo กับ useCallback
useCallback(fn, deps) เทียบเท่ากับ useMemo(() => fn, deps) ทั้งสองใช้กลไกเดียวกัน โดย useCallback เป็นเพียงรูปแบบย่อสำหรับการจดจำฟังก์ชันโดยเฉพาะ
การจดจำรายการในลิสต์
รูปแบบที่ใช้กันทั่วไปคือ จดจำคอมโพเนนต์รายการเมื่อลิสต์มีขนาดใหญ่และเรนเดอร์ใหม่บ่อย ส่งฟังก์ชันเรียกกลับที่คงที่จาก useCallback เพื่อไม่ให้การจดจำหมดประโยชน์
const MemoRow = React.memo(Row);
const handleEdit = useCallback((id) => edit(id), []);
const handleDel = useCallback((id) => remove(id), []);
{rows.map(row => (
<MemoRow key={row.id} row={row} onEdit={handleEdit} onDelete={handleDel} />
))}การจดจำค่าของบริบท
จดจำค่าที่ส่งให้ผู้ให้บริการบริบท เพื่อป้องกันไม่ให้ผู้ใช้บริบททั้งหมดเรนเดอร์ใหม่ทุกครั้งที่คอมโพเนนต์แม่ของผู้ให้บริการเรนเดอร์ใหม่
const value = useMemo(() => ({ user, login, logout }), [user]);ตรวจสอบความเข้าใจ
จุดประสงค์ของ useCallback คืออะไร
ทบทวน: useMemo และ useCallback
useMemo แคชค่าที่คำนวณและใช้ทรัพยากรมาก useCallback แคชการอ้างอิงฟังก์ชัน React.memo ข้ามการเรนเดอร์ใหม่เมื่อพร็อพไม่เปลี่ยนในการเปรียบเทียบแบบตื้น ใช้ทั้งสามอย่างร่วมกันเพื่อเพิ่มประสิทธิภาพระดับคอมโพเนนต์ วัดประสิทธิภาพก่อน เพราะการจดจำเร็วเกินไปเพิ่มความซับซ้อนโดยไม่ก่อประโยชน์ การอ้างอิงที่คงที่ช่วยป้องกันไม่ให้เอฟเฟกต์และการจดจำปลายทางทำงานซ้ำ
เรียนรู้ HTML ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 41
- บทเรียน
- 163
คำถามที่พบบ่อย
บทเรียน “useMemo และ useCallback เพื่อประสิทธิภาพ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “useMemo และ useCallback เพื่อประสิทธิภาพ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Frontend Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “useMemo และ useCallback เพื่อประสิทธิภาพ”
จดจำผลการคำนวณที่ใช้เวลานานด้วย useMemo และจดจำการอ้างอิงฟังก์ชันที่คงที่ด้วย useCallback เพื่อป้องกันการเรนเดอร์ซ้ำของคอมโพเนนต์ลูกโดยไม่จำเป็น คุณปฏิบัติ Frontend Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Frontend Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Frontend Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “useMemo และ useCallback เพื่อประสิทธิภาพ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Frontend Academy นี้ได้ไหม
ได้ บทเรียน Frontend Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- useContext สำหรับสถานะส่วนกลาง
- useReducer สำหรับสถานะที่ซับซ้อน
- useMemo และ useCallback เพื่อประสิทธิภาพ
- Custom Hooks: แยกตรรกะที่นำกลับมาใช้ซ้ำได้