پرفورمنس در ری اکت: چطور اپلیکیشن ری اکتی خودمونو سریع تر کنیم؟
تاحالا شده یه سایت رو باز کنی و حس کنی لود شدنش داره سالها طول میکشه!؟🚶♀️🤦♂️ این تجربه واقعاً ضدحال بزرگیه. تو دنیای امروز که سرعت حرف اول رو میزنه، یه اپلیکیشن کند، مثل یه در بستست که هیچکی نمیخواد ازش عبور کنه!
به همین دلیل، بهینه سازی پرفورمنس تو اپلیکیشن های ری اکتی خیلی خیلی مهمه!
پس بیاید تمام اصول افزایش پرفورمنس در ری اکت رو یکبار دیگه مرور کنیم 🙂
استفاده از ابزارهای آنالیز پرفورمنس
قبل از هر چیزی، باید بدونیم اپیکیشن فعلی ما تو چه وضعیتی هست و اگر مشکلی داره، اون مشکلها دقیقا چی هستن و تو چه صفحاتی وجود دارن.
برای اینکار ما باید از یکسری ابزار استفاده کنیم.
چند ابزار خوب و کاربردی برای این کار وجود داره تا متوجه بشیم اپیکیشن و صفحات ما چه مشکلی دارن:
- React DevTools: این ابزار بهت نشون میده کدوم کامپوننت ها دارن زیاد رندر میشن. اینجوری میتونی دقیقاً همون بخش های مشکل دار رو پیدا کنی.
- Google Lighthouse: یه ابزار خیلی قوی که توی مرورگر کروم قابل دسترسه و میتونه وضعیت کلی اپلیکیشنت رو از نظر پرفورمنس، دسترس پذیری و سئو بررسی کنه.
- Web Vitals: این یکی مخصوص اندازه گیری شاخص های اصلی پرفورمنس مثل LCP، FID و CLS هست.
راهکارهای بهبود پرفورمنس در ری اکت
1. بهینه سازی رندر کامپوننت ها
هر بار که یه کامپوننت رندر میشه، کلی از منابع سیستم مصرف میشه. اگه بتونی رندرهای غیرضروری رو حذف کنی، پرفورمنس اپت خیلی بهتر میشه.
React.memo: این ابزار جلوی رندر دوباره کامپوننت هایی که تغییر نکردن رو میگیره.
اگه این ابزار رو بلد نیستید پیشنهاد میکنم مقاله آموزش memo در ری اکت رو مطالعه کنید.
به این شکل میتونیم از React.memo استفاده کنیم :
const MyComponent = React.memo(({ data }) => {
return {data};
});
2. استفاده از هوک های بهینه ساز
useMemo
: برای جلوگیری از محاسبات سنگین غیرضروری توی هر رندر ازش استفاده میکنیم.
اگه با این هوک قدرتمند آشنا نیستید، بنظرم آموزش هوک useMemo رو مطالعه کنید.
از این هوک بصورت زیر باید استفاده کنیم:
const calculatedValue = useMemo(() => heavyCalculation(data), [data]);
useCallback
: برای جلوگیری از ایجاد تابع های جدید در هر رندر از این هوک استفاده میکنیم.
اگه به این هوک مسلط نیستید بنظرم آموزش هوک useCallback رو مطالعه کنین.
شکل کلی استفاده از این هوک بصورت زیر هست:
const handleClick = useCallback(() => {
console.log('Clicked');
}, []);
مدیریت صحیح State
- بهتره که State ها رو تا حد امکان در سطح لوکال کامپوننت نگه داریم. وقتی State رو تو Context یا Redux ذخیره میکنی، میتونه باعث رندرهای غیرضروری بشه.
3. کد اسپلیتینگ و بارگذاری تنبل
کد اسپلیتینگ بهت کمک میکنه بخش هایی از اپلیکیشن رو فقط زمانی بارگذاری کنی که بهشون نیاز داری. تو ری اکت این کار خیلی راحته:
const LazyComponent = React.lazy(() => import('./LazyComponent'));
function App() {
return (
Loading...
4. نمایش لیست های طولانی با Virtualization
وقتی یه لیست خیلی طولانی داری، نمایش تمام آیتمها میتونه منابع زیادی مصرف کنه. اینجا Virtualization به کمکت میاد:
- از کتابخونههایی مثل React-Window یا React-Virtualized استفاده کن.
5. مدیریت تصاویر
- همیشه تصاویر رو فشرده کن و از فرمتهایی مثل WebP استفاده کن.
- با تکنیک Lazy Loading، فقط تصاویری که کاربر میبینه رو بارگذاری کن. ( بارگذاری تنبل در ری اکت )
6. کاهش تعداد و حجم فایل های جاوااسکریپت
- ماژول های غیرضروری رو حذف کن.
- از ابزارهایی مثل Webpack برای حذف کد های اضافی استفاده کن.
7. Debounce و Throttle رویداد ها
اگه رویداد هایی مثل اسکرول یا تایپ زیاد اتفاق میوفته، میتونی با استفاده از Debounce یا Throttle، اونا رو مدیریت کنی:
const debounce = (func, delay) => {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => func(...args), delay);
};
};
اشتباهات رایج در بهینهسازی
- استفاده بی رویه از هوک ها بدون درک کاملشون.
- Context API رو برای مدیریت Stateهای بزرگ به کار بردن.
- اضافه کردن کتابخونه های سنگین مثل lodash برای کارهای ساده.
نتیجهگیری
بهینه سازی پرفورمنس تو ری اکت کار سختی نیست، ولی نیاز به دقت داره. اگه ابزارهای آنالیز رو استفاده کنی و راهکارهای بالا رو قدم به قدم پیاده سازی کنی، مطمئناً اپلیکیشنت سریعتر و بهتر میشه.
هرکدوم از این تکنیک ها خودشون کلی جزئیات دارن که تو فِرانت اِندی راجب هرکدومشون یه مقاله جامع و تخصصی تر نوشتیم. پیشنهاد میکنم مقاله جامع هرتکنیک رو مطالعه کنید تا با درک بهتر هر تکنیک، بتونید نهایت استتفاده رو ازشون ببرید 🖤
با استفاده از React DevTools میتونی ببینی کدوم کامپوننت ها رندر شدن. یه تب به اسم “Profiler” داره که نشون میده چه مقدار زمان برای رندر هر کامپوننت صرف شده.
React.memo
باعث میشه یه کامپوننت فقط وقتی رندر بشه که propsهاش تغییر کرده باشن. اینطوری از رندرهای غیرضروری جلوگیری میکنه.
useMemo
برای به خاطر سپردن مقادیر محاسبه شده استفاده میشه.useCallback
برای جلوگیری از ساختن تابع جدید در هر رندر استفاده میشه.
بله، اگه Context API رو برای مدیریت مقادیر زیاد یا پیچیده استفاده کنی، میتونه باعث رندرهای غیرضروری بشه. برای پروژه های بزرگ بهتره از Redux یا Zustand استفاده کنی.
Lazy loading بهت اجازه میده که فقط وقتی یه کامپوننت نیاز بود، اونو بارگذاری کنی. این کار حجم اولیه جاوااسکریپت صفحه رو کاهش میده.
- از کداسپلیتینگ استفاده کن.
- ماژولهای غیرضروری رو حذف کن.
- کتابخونههای سبک تر جایگزین کن (مثلاً استفاده از Lodash-es به جای کل Lodash).
از Virtualization استفاده کن. کتابخونه هایی مثل React-Window یا React-Virtualized بهت کمک میکنن فقط آیتم هایی که روی صفحه دیده میشن رو رندر کنی.
- از
React.memo
استفاده کن. - هوک های
useMemo
وuseCallback
رو به درستی به کار ببر. - Stateها رو به کوچک ترین محدوده ممکن محدود کن.
بله، تصاویر حجیم سرعت لود اولیه رو کاهش میدن. تصاویر رو فشرده کن و از فرمت هایی مثل WebP استفاده کن.
بله، Server-Side Rendering باعث میشه محتوای صفحه سریعتر لود بشه، مخصوصاً برای سئو و تجربه کاربر مفیده.
اگه هوک ها رو بی دلیل یا اشتباه استفاده کنی (مثلاً useEffect
با وابستگی های نادرست )، میتونه به رندرهای غیرضروری منجر بشه.
با استفاده از React.lazy
و Suspense
میتونی کداسپلیتینگ انجام بدی. اینطوری بخشهایی از کد فقط زمانی که لازم باشه بارگذاری میشن.
استفاده بیش ازحد از Inline Styles میتونه باعث ایجاد مشکلات پرفورمنسی بشه، چون این استایل ها توی هر رندر دوباره ساخته میشن. بهتره از فایل های CSS یا کتابخونههای CSS-in-JS استفاده کنی.
کتابخونه های سنگین حجم جاوااسکریپت رو افزایش میدن و باعث کند شدن زمان بارگذاری اولیه اپلیکیشن میشن.
Virtual DOM همیشه بخشی از ری اکته و انتخابی تو این مورد نداریم. ولی بهینه سازی تغییرات DOM، مثل استفاده از key
مناسب توی لیست ها، به پرفورمنس کمک میکنه.
هر بار که هر State تغییر میکنه، کامپوننت رندر میشه. برای جلوگیری از رندرهای غیرضروری، بهتره Stateها رو کوچک و محدود نگه داری.
- Debounce: یه عملیات رو فقط بعد از یه تأخیر مشخص اجرا میکنه (مثلاً تایپ کردن).
- Throttle: عملیات رو توی یه بازه زمانی محدود میکنه (مثلاً اسکرول).
بله، اگه وابستگی ها رو اشتباه مشخص کنی، ممکنه باعث اجرای مکرر و غیرضروری useEffect
بشه.
این تکنیک ها باعث میشن منابع و داده هایی که احتمالاً کاربر در آینده نیاز داره، از قبل بارگذاری بشن. اینطوری تجربه کاربری روان تر میشه.
بله، useRef
میتونه به ذخیره مقادیر بدون رندر مجدد کمک کنه. برای ذخیره مقادیر غیرمتغیر خیلی مفیده.
درباره احمد احمدنژاد
من یه برنامه نویس و توسعه دهنده وب هستم که عاشق دنیای صفر و یکم❤️
نوشتههای بیشتر از احمد احمدنژاد
دیدگاهتان را بنویسید