0Pricing
React Academy · บทเรียน

การลด INP: การเพิ่มประสิทธิภาพตัวจัดการอีเวนต์

หน่วงตัวจัดการที่ทำงานหนัก ใช้ scheduler.yield() และหลีกเลี่ยงงานที่ใช้เวลานานจนบล็อกเธรดหลัก

การลด INP: การเพิ่มประสิทธิภาพตัวจัดการอีเวนต์ เป็นบทเรียน React Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

INP คืออะไร

INP หรือการโต้ตอบจนถึงการวาดครั้งถัดไป ใช้วัดความหน่วงตั้งแต่การโต้ตอบของผู้ใช้ เช่น การคลิก การแตะ หรือการกดแป้น จนถึงเวลาที่ browser วาดผลลัพธ์ การมีค่า INP มากกว่า 200ms จะทำให้รู้สึกว่าการตอบสนองช้า

เหตุใดเหตุการณ์ของ React จึงอาจช้า

ตัวจัดการเหตุการณ์ของ React ที่ทำงานมากเกินไปแบบพร้อมกันจะขัดขวางเธรดหลัก browser ไม่สามารถวาดผลลัพธ์ได้จนกว่างาน JS จะเสร็จสิ้น ทำให้ INP สูง

การหน่วงอินพุตที่พิมพ์

หน่วงการทำงานที่ใช้ทรัพยากรมาก เช่น การเรียก API ค้นหาและการคำนวณที่ซับซ้อน ซึ่งถูกเรียกจากการกดแป้น การอัปเดตสถานะ React ทุกครั้งที่กดแป้นทำได้ตามปกติ แต่ควรหน่วงงานที่ใช้ทรัพยากรมาก

import { useDeferredValue, useState } from 'react';

function SearchPage() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query); // defers re-render of slow parts

  return (
    <>
      <input value={query} onChange={e => setQuery(e.target.value)} />
      <SearchResults query={deferredQuery} /> {/* re-renders with lower priority */}
    </>
  );
}

การใช้ useTransition กับการอัปเดตที่ไม่เร่งด่วน

ครอบการอัปเดตสถานะที่ช้าด้วย startTransition เพื่อระบุว่าไม่ใช่งานเร่งด่วน React จะเลื่อนการทำงานเหล่านี้ ทำให้อินพุตยังตอบสนองได้ดี

const [isPending, startTransition] = useTransition();

function handleFilter(value) {
  setInputValue(value); // urgent — update input immediately
  startTransition(() => {
    setFilteredList(expensiveFilter(value)); // non-urgent — can be interrupted
  });
}

การย้ายงานหนักออกจากเธรดหลัก

ใช้ตัวทำงานเว็บสำหรับงานที่ใช้ CPU อย่างหนัก เช่น การแยกวิเคราะห์ชุดข้อมูลขนาดใหญ่และการประมวลผลรูปภาพ เธรดหลักจะยังตอบสนองได้ขณะที่ตัวทำงานคำนวณ

const worker = new Worker(new URL('./heavy-worker.js', import.meta.url));

function processData(data) {
  return new Promise(resolve => {
    worker.postMessage(data);
    worker.onmessage = e => resolve(e.data);
  });
}

// In component:
const handleClick = async () => {
  const result = await processData(largeDataset); // doesn't block main thread
  setResult(result);
};

การหลีกเลี่ยงงานที่ใช้เวลานาน

งานที่ใช้เวลานาน (>50ms) จะขัดขวางเธรดหลักและทำให้ INP สูงขึ้น แบ่งงานเหล่านี้ด้วย setTimeout, scheduler.yield() หรือ requestIdleCallback

async function processInChunks(items) {
  const CHUNK_SIZE = 100;
  for (let i = 0; i < items.length; i += CHUNK_SIZE) {
    const chunk = items.slice(i, i + CHUNK_SIZE);
    processChunk(chunk);
    await new Promise(r => setTimeout(r, 0)); // yield to browser between chunks
  }
}

scheduler.yield() (API สมัยใหม่)

scheduler.yield() คืนการควบคุมให้ลูปเหตุการณ์ของ browser ทำให้การโต้ตอบของผู้ใช้ที่รออยู่ได้รับการประมวลผลก่อนที่โค้ดของคุณจะทำงานต่อ

async function longTask() {
  for (const item of largeList) {
    processItem(item);
    if (/* every N items */) {
      await scheduler.yield(); // let browser handle pending clicks/inputs
    }
  }
}

การหลีกเลี่ยงเค้าโครงแบบพร้อมกันในตัวจัดการ

การอ่านคุณสมบัติเค้าโครง (offsetWidth, getBoundingClientRect()) บังคับให้คำนวณเค้าโครงใหม่แบบพร้อมกัน จัดกลุ่มการอ่านก่อนการเขียนเพื่อหลีกเลี่ยงการคำนวณเค้าโครงซ้ำไปมา

// Bad — forces layout recalculation on each iteration:
items.forEach(item => {
  const height = item.offsetHeight; // READ — forces layout
  item.style.height = height * 2 + 'px'; // WRITE — dirties layout
});

// Good — batch reads, then writes:
const heights = items.map(item => item.offsetHeight); // all reads
heights.forEach((h, i) => items[i].style.height = h * 2 + 'px'); // all writes

Actions ของ React 19 สำหรับ INP แบบอะซิงโครนัส

Actions ของ React 19 จัดการการเปลี่ยนแปลงข้อมูลแบบอะซิงโครนัสโดยไม่ขัดขวาง UI สถานะที่กำลังดำเนินการจะอัปเดตแยกต่างหาก ทำให้หน้ายังคงโต้ตอบได้

function LikeButton({ postId }) {
  const [optimistic, setOptimistic] = useOptimistic(false);

  async function handleLike() {
    setOptimistic(true);
    await likePost(postId); // async — doesn't block
  }

  return <button onClick={handleLike}>{optimistic ? 'Liked' : 'Like'}</button>;
}

ข้อควรระวังของการมอบหมายเหตุการณ์

React ใช้การมอบหมายเหตุการณ์สังเคราะห์ โดยผูกตัวรับฟังเพียงตัวเดียวไว้ที่ราก หลีกเลี่ยงการผูกตัวรับฟัง DOM แยกกันหลายร้อยตัวใน useEffect และใช้อีเวนต์สังเคราะห์ของ React กับองค์ประกอบ JSX แทน

การวัด INP ใน DevTools

ใช้แผง Performance ของ Chrome DevTools เพื่อบันทึกการโต้ตอบและตรวจสอบงานที่ใช้เวลานาน มองหารายการ 'การโต้ตอบ' ในไทม์ไลน์ แล้วขยายรายการเพื่อค้นหาการประเมินสคริปต์ที่ขัดขวางการทำงาน

ตรวจสอบความเข้าใจ

ฮุก React ใดใช้ระบุว่าการอัปเดตสถานะไม่เร่งด่วน เพื่อให้การโต้ตอบของผู้ใช้สามารถขัดจังหวะได้

สรุปทบทวน

ลด INP ด้วยการหน่วงงานที่ใช้ทรัพยากรมาก ใช้ startTransition กับการอัปเดตที่ไม่เร่งด่วน ย้ายงานที่ใช้ CPU ไปยังตัวทำงานเว็บ และแบ่งงานที่ใช้เวลานานด้วย scheduler.yield() จัดกลุ่มการอ่าน DOM ก่อนการเขียน เพื่อหลีกเลี่ยงการคำนวณเค้าโครงซ้ำไปมา

คำถามที่พบบ่อย

บทเรียน “การลด INP: การเพิ่มประสิทธิภาพตัวจัดการอีเวนต์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การลด INP: การเพิ่มประสิทธิภาพตัวจัดการอีเวนต์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การลด INP: การเพิ่มประสิทธิภาพตัวจัดการอีเวนต์”

หน่วงตัวจัดการที่ทำงานหนัก ใช้ scheduler.yield() และหลีกเลี่ยงงานที่ใช้เวลานานจนบล็อกเธรดหลัก คุณปฏิบัติ React Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การลด INP: การเพิ่มประสิทธิภาพตัวจัดการอีเวนต์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน React Academy นี้ได้ไหม

ได้ บทเรียน React Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

  1. การวัด Core Web Vitals ในแอป React
  2. การวิเคราะห์บันเดิลและกลยุทธ์การแยกโค้ด
  3. การเพิ่มประสิทธิภาพรูปภาพและฟอนต์ใน React
  4. การลด INP: การเพิ่มประสิทธิภาพตัวจัดการอีเวนต์
← กลับไปที่ React Academy