Frontend Academy · บทเรียน

useMemo และ useCallback เพื่อประสิทธิภาพ

จดจำผลการคำนวณที่ใช้เวลานานด้วย useMemo และจดจำการอ้างอิงฟังก์ชันที่คงที่ด้วย useCallback เพื่อป้องกันการเรนเดอร์ซ้ำของคอมโพเนนต์ลูกโดยไม่จำเป็น

บทเรียน 3 จาก 413 ขั้นตอน

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 changes

useCallback — จดจำฟังก์ชัน

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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. useContext สำหรับสถานะส่วนกลาง
  2. useReducer สำหรับสถานะที่ซับซ้อน
  3. useMemo และ useCallback เพื่อประสิทธิภาพ
  4. Custom Hooks: แยกตรรกะที่นำกลับมาใช้ซ้ำได้
← กลับไปที่ Frontend Academy