فارسی

یاد بگیرید که چگونه دسته‌بندی خودکار React به‌روزرسانی‌های متعدد State را بهینه می‌کند، عملکرد برنامه را بهبود می‌بخشد و از رندرهای مجدد غیرضروری جلوگیری می‌کند.

دسته‌بندی خودکار در React: بهینه‌سازی به‌روزرسانی‌های State برای بهبود عملکرد

عملکرد React برای ایجاد رابط‌های کاربری روان و پاسخگو حیاتی است. یکی از ویژگی‌های کلیدی که برای بهبود عملکرد معرفی شده، دسته‌بندی خودکار (automatic batching) است. این تکنیک بهینه‌سازی به طور خودکار چندین به‌روزرسانی state را در یک رندر مجدد گروه‌بندی می‌کند که منجر به افزایش قابل توجه عملکرد می‌شود. این موضوع به ویژه در برنامه‌های پیچیده با تغییرات مکرر state اهمیت دارد.

دسته‌بندی خودکار در React چیست؟

دسته‌بندی (Batching) در زمینه React، فرآیند گروه‌بندی چندین به‌روزرسانی state در یک به‌روزرسانی واحد است. قبل از React 18، دسته‌بندی فقط برای به‌روزرسانی‌هایی اعمال می‌شد که در داخل event handlerهای React رخ می‌دادند. به‌روزرسانی‌های خارج از event handlerها، مانند موارد داخل setTimeout، promiseها یا event handlerهای نیتیو، دسته‌بندی نمی‌شدند. این امر می‌توانست منجر به رندرهای مجدد غیرضروری و گلوگاه‌های عملکردی شود.

React 18 ویژگی دسته‌بندی خودکار را معرفی کرد که این بهینه‌سازی را به تمام به‌روزرسانی‌های state، صرف‌نظر از محل وقوع آن‌ها، گسترش می‌دهد. این بدان معناست که چه به‌روزرسانی‌های state شما در داخل یک event handler در React، یک callback در setTimeout یا در نتیجه یک promise اتفاق بیفتد، React به طور خودکار آن‌ها را در یک رندر مجدد دسته‌بندی می‌کند.

چرا دسته‌بندی خودکار مهم است؟

دسته‌بندی خودکار چندین مزیت کلیدی را فراهم می‌کند:

دسته‌بندی خودکار چگونه کار می‌کند؟

React با به تأخیر انداختن اجرای به‌روزرسانی‌های state تا پایان زمینه اجرایی فعلی، به دسته‌بندی خودکار دست می‌یابد. این کار به React اجازه می‌دهد تا تمام به‌روزرسانی‌های state را که در آن زمینه رخ داده‌اند، جمع‌آوری کرده و آن‌ها را در یک به‌روزرسانی واحد دسته‌بندی کند.

این مثال ساده شده را در نظر بگیرید:

function ExampleComponent() {
  const [count1, setCount1] = useState(0);
  const [count2, setCount2] = useState(0);

  function handleClick() {
    setTimeout(() => {
      setCount1(count1 + 1);
      setCount2(count2 + 1);
    }, 0);
  }

  return (
    <div>
      <p>Count 1: {count1}</p>
      <p>Count 2: {count2}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
}

قبل از React 18، کلیک کردن روی دکمه باعث دو بار رندر مجدد می‌شد: یکی برای setCount1 و دیگری برای setCount2. با دسته‌بندی خودکار در React 18، هر دو به‌روزرسانی state با هم دسته‌بندی می‌شوند و در نتیجه تنها یک رندر مجدد اتفاق می‌افتد.

نمونه‌هایی از عملکرد دسته‌بندی خودکار

۱. به‌روزرسانی‌های ناهمزمان (Asynchronous)

عملیات ناهمزمان، مانند دریافت داده از یک API، اغلب شامل به‌روزرسانی state پس از اتمام عملیات است. دسته‌بندی خودکار تضمین می‌کند که این به‌روزرسانی‌های state با هم دسته‌بندی شوند، حتی اگر در داخل callback ناهمزمان رخ دهند.

function DataFetchingComponent() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch('https://api.example.com/data');
        const jsonData = await response.json();
        setData(jsonData);
        setLoading(false);
      } catch (error) {
        console.error('Error fetching data:', error);
        setLoading(false);
      }
    }

    fetchData();
  }, []);

  if (loading) {
    return <p>Loading...</p>;
  }

  return <div>Data: {JSON.stringify(data)}</div>;
}

در این مثال، setData و setLoading هر دو در داخل تابع ناهمزمان fetchData فراخوانی می‌شوند. React این به‌روزرسانی‌ها را با هم دسته‌بندی می‌کند که منجر به یک رندر مجدد واحد پس از دریافت داده‌ها و به‌روزرسانی وضعیت بارگذاری می‌شود.

۲. Promiseها

مشابه به‌روزرسانی‌های ناهمزمان، promiseها اغلب شامل به‌روزرسانی state هنگام resolve یا reject شدن promise هستند. دسته‌بندی خودکار تضمین می‌کند که این به‌روزرسانی‌های state نیز با هم دسته‌بندی شوند.

function PromiseComponent() {
  const [result, setResult] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    const myPromise = new Promise((resolve, reject) => {
      setTimeout(() => {
        const success = Math.random() > 0.5;
        if (success) {
          resolve('Promise resolved!');
        } else {
          reject('Promise rejected!');
        }
      }, 1000);
    });

    myPromise
      .then((value) => {
        setResult(value);
        setError(null);
      })
      .catch((err) => {
        setError(err);
        setResult(null);
      });
  }, []);

  if (error) {
    return <p>Error: {error}</p>;
  }

  if (result) {
    return <p>Result: {result}</p>;
  }

  return <p>Loading...</p>;
}

در این حالت، یا setResult و setError(null) در صورت موفقیت فراخوانی می‌شوند، یا setError و setResult(null) در صورت شکست. در هر صورت، دسته‌بندی خودکار این‌ها را در یک رندر مجدد واحد ترکیب می‌کند.

۳. Event Handlerهای نیتیو

گاهی اوقات، ممکن است نیاز داشته باشید به جای event handlerهای ترکیبی (synthetic) React، از event handlerهای نیتیو (مانند addEventListener) استفاده کنید. دسته‌بندی خودکار در این موارد نیز کار می‌کند.

function NativeEventHandlerComponent() {
  const [scrollPosition, setScrollPosition] = useState(0);

  useEffect(() => {
    function handleScroll() {
      setScrollPosition(window.scrollY);
    }

    window.addEventListener('scroll', handleScroll);

    return () => {
      window.removeEventListener('scroll', handleScroll);
    };
  }, []);

  return <p>Scroll Position: {scrollPosition}</p>;
}

با وجود اینکه setScrollPosition در داخل یک event handler نیتیو فراخوانی می‌شود، React همچنان به‌روزرسانی‌ها را با هم دسته‌بندی می‌کند و از رندرهای مجدد بیش از حد هنگام اسکرول کاربر جلوگیری می‌کند.

انصراف از دسته‌بندی خودکار

در موارد نادر، ممکن است بخواهید از دسته‌بندی خودکار انصراف دهید. به عنوان مثال، ممکن است بخواهید یک به‌روزرسانی همزمان را برای اطمینان از به‌روزرسانی فوری UI اعمال کنید. React برای این منظور API به نام flushSync را فراهم کرده است.

توجه: استفاده از flushSync باید به ندرت انجام شود، زیرا می‌تواند بر عملکرد تأثیر منفی بگذارد. به طور کلی بهتر است تا حد امکان به دسته‌بندی خودکار تکیه کنید.

import { flushSync } from 'react-dom';

function ExampleComponent() {
  const [count, setCount] = useState(0);

  function handleClick() {
    flushSync(() => {
      setCount(count + 1);
    });
  }

  return (<button onClick={handleClick}>Increment</button>);
}

در این مثال، flushSync React را مجبور می‌کند تا بلافاصله state را به‌روزرسانی کرده و کامپوننت را مجدداً رندر کند و دسته‌بندی خودکار را دور بزند.

بهترین روش‌ها برای بهینه‌سازی به‌روزرسانی‌های State

در حالی که دسته‌بندی خودکار بهبودهای عملکردی قابل توجهی را ارائه می‌دهد، همچنان مهم است که از بهترین روش‌ها برای بهینه‌سازی به‌روزرسانی‌های state پیروی کنید:

دسته‌بندی خودکار و ملاحظات جهانی

دسته‌بندی خودکار، به عنوان یک بهینه‌سازی عملکردی اصلی در React، صرف‌نظر از مکان کاربر، سرعت شبکه یا دستگاه، به طور کلی برای برنامه‌ها مفید است. با این حال، تأثیر آن در سناریوهایی با سرعت اینترنت پایین‌تر یا دستگاه‌های با قدرت کمتر می‌تواند محسوس‌تر باشد. برای مخاطبان بین‌المللی، این نکات را در نظر بگیرید:

نتیجه‌گیری

دسته‌بندی خودکار در React یک تکنیک بهینه‌سازی قدرتمند است که می‌تواند عملکرد برنامه‌های React شما را به طور قابل توجهی بهبود بخشد. با گروه‌بندی خودکار چندین به‌روزرسانی state در یک رندر مجدد واحد، سربار رندرینگ را کاهش می‌دهد، از وضعیت‌های ناسازگار جلوگیری می‌کند و به تجربه‌ی کاربری روان‌تر و پاسخگوتر منجر می‌شود. با درک نحوه عملکرد دسته‌بندی خودکار و پیروی از بهترین روش‌ها برای بهینه‌سازی به‌روزرسانی‌های state، می‌توانید برنامه‌های React با عملکرد بالا بسازید که تجربه‌ی کاربری عالی را برای کاربران در سراسر جهان فراهم می‌کنند. استفاده از ابزارهایی مانند React DevTools به اصلاح و بهینه‌سازی بیشتر پروفایل‌های عملکردی برنامه شما در محیط‌های مختلف جهانی کمک می‌کند.