۸ روش برای بهبود اپلیکیشن ری اکت – راهنمای کاربردی
![۸ روش برای بهبود اپلیکیشن ری اکت – راهنمای کاربردی](https://blog.faradars.org/wp-content/uploads/2020/03/8Ways-to-Bolster-Your-React-Apps-150x150.jpg)
![۸ روش برای بهبود اپلیکیشن ری اکت – راهنمای کاربردی](https://blog.faradars.org/wp-content/uploads/2020/03/8Ways-to-Bolster-Your-React-Apps.jpg)
برخی اوقات در زمان ساخت اپلیکیشنهای راکت ممکن است برخی فرصتها برای بهبود اپلیکیشن خود را از دست بدهیم، زیرا زمانی که اپلیکیشن سریع کار میکند، به اشتباه تصور میکنیم که نقصی ندارد. در چنین موقعیتهایی ممکن است تصور کنیم که چون خروجی پروژه برای ما نرمال به نظر میرسد، کاربران نیز چنین وضعیتی درباره آن خواهند داشت. زمانی که ذهن این طرز فکر را پیش بگیرد، ممکن است موضوعاتی که میتوان کد را برای دریافت نتیجه بهتر بهبود بخشید را نادیده بگیرد. در این راهنما با 8 روش برای بهبود اپلیکیشن ری اکت آشنا خواهیم شد.
1. موجودیتها را حفظ کنید
نخستین روشی که برای ارتقای کیفیت اپلیکیشن ریاکت وجود دارد، توجه به «موجودیتها» (Identities) است. باید به خاطر داشته باشید که میتوانید متغیرها و تابعها را درون React.useMemo قرار دهید تا به آنها امکان خاطرسپاری خودشان را بدهید. بدین ترتیب ریاکت آنها را برای رندرهای آتی حفظ میکند.
در غیر این صورت اگر آنها را به حافظه نسپارید، ارجاعشان در رندرهای آتی از بین میرود. بدین ترتیب هزینه سربار مضاعفی در نتیجه عملیات غیر ضروری ایجاد میشود. برای نمونه فرض کنید میخواهیم یک قلاب سفارشی بسازیم که فهرستی از urls به عنوان آرگومان میگیرد به طوری که میتواند آنها را در یک آرایه از promise-ها تجمیع کند که با Promise.all به صورت resolved درمیآیند.
نتایج درون حالت درج میشوند و به محض پایان، به کامپوننت App ارسال میشوند. این Promise-ها روی آرایه urls نگاشت میشوند که شامل چهار URL مختلف است که باید واکشی شوند:
وظیفه ما این است که دادهها را از لینکها واکشی کنیم به این ترتیب به صورت ایدهآل تنها چهار درخواست باید ارسال شوند. اما اگر نگاهی به زبانه Network درون مرورگر کروم بیندازیم میبینیم که در عمل هشت درخواست فرستاده میشوند. دلیل این وضعیت آن است که آرگومان urls موجودیت خود را مانند قبل حفظ نمیکند، زیرا زمانی که App رندر مجدد میشود، هر بار یک وهله جدید از آرایه میسازد و از این رو ریاکت با آن مانند یک مقدار تغییریافته رفتار میکند.
برنامههای رایانهای گاهی اوقات فکر میکنند که هوشمندی بیشتری از ما دارند و چنین رفتاری در پیش میگیرند. برای رفع این مشکل میتوانیم از React.useMemo استفاده کنیم، به طوری که تا وقتی آرایه شامل url-ها تغییری نیافته است، آرایه promise-ها خودش را در هر بار رندر، مجدداً محاسبه نمیکند. بدین ترتیب کد خود را با بهکارگیری این مفهوم به صورت زیر بازسازی میکنیم:
اکنون اگر کد فوق را اجرا کنیم، متوجه میشویم که همچنان هشت درخواست ارسال میشوند. دلیل این وضعیت آن است که گرچه ارائه urls را حفظ کردهایم، اما همچنان باید متغیرهای promises را نیز درون قلاب ذخیره کنیم، زیرا آنها نیز هر زمان که قلاب اجرا میشوند وهلهای از خود میسازند:
به این ترتیب کد باید اکنون در هر بار اجرا تنها چهار درخواست ارسال کند:
2. ادغام props در فرزندان
گاهی اوقات ممکن است با موقعیتی مواجه شویم که باید یک prop قبل از رندر با فرزندان ادغام شود. ریاکت امکان دیدن props-های هر عنصر خودش و عناصر دیگر را فراهم ساخته است و برای نمونه key آن را عرضه میکند. میتوان عنصر فرزند را درون یک کامپوننت جدید قرار دارد و props-های جدید را از آنجا تزریق کرد و یا میتوان prop-های جدید را با استفاده از متد ادغام کرد.
برای نمونه فرض کنید یک کامپوننت App داریم که از یک قلاب useModal استفاده میکند و برخی ابزارهای کارآمد برای مدیریت مدلها به وسیله ارائه کنترلهایی مانند open, close و opened در اختیار ما قرار میدهد. میخواهیم این prop را به کامپوننت VisibilityControl ارسال کنیم، زیرا باید کارکردهای بیشتری را پیش از ارسال دادههای modal به فرزندان ارائه کنیم:
VisibilityControl مطمئن میشود که پیش از صادر کردن اجازه استفاده نرمال فرزندان از opened، مقدار activated به صورت true در آمده است. اگر این وضعیت در مسیر امن استفاده شود، VisibilityControl کارکرد جلوگیری از کاربران غیرفعال شده از دسترسی به محتوای امن را فراهم میسازد.
3. ترکیب ردیوسرها برای ساخت یک ردیوسر بزرگ
این بهینهسازی در مواردی به کار میآید که لازم باشد دو یا چند Reducer در اپلیکیشن با هم ترکیب شوند تا یک ردیوسر بزرگتر تشکیل دهند. این رویکرد مشابه طرز کار combineReducers در React-Redux است. فرض کنید میخواهیم یک اپلیکیشن میکروسرویس بزرگ بسازیم و از ابتدا در نظر گرفتهایم هر بخش در اپلیکیشن مسئول «چارچوب/حالت» (context/state) خودش باشد.
اما در ادامه به این نتیجه میرسیم که حالتهای مختلف باید در یک حالت بزرگتر ادغام شوند تا بتوانیم همه آنها را در محیط یکسانی مدیریت کنیم. بدین ترتیب فایلهای authReducer.js, ownersReducer.js و frogsReducer.js را داریم که باید با هم ترکیب شوند:
- فایل authReducer.js
- فایل ownersReducer.js
- فایل frogsReducer.js
آنها را در فایل اصلی خود ایمپورت میکنیم و ساختار حالت را به صورت زیر تعریف مینماییم:
- فایل App.js
سپس میتوانیم با قلابها به صورت معمول کار کنیم، dispatch را فراخوانی کنیم، type تطبیق یافته را ارسال کنیم و آرگومانها را به ردیوسر اختصاصی یافته بفرستیم. مهمترین بخش که باید توجه کنیم، rootReducer است:
4. Sentry برای گزارش خطا
زمانی که از Sentry در اپلیکیشنهای ریاکت استفاده میکنیم، مزیت زیادی تولید میکند. داشتن گزارشهای تفصیلی در مورد خطاهای ارسالی به یک مکان مرکزی که به صورت یکباره تحلیل شوند، ابزاری بسیار مهم محسوب میشود.
ابتدا Sentry را با دستور زیر نصب کنید:
npm install @sentry/browser
سپس آن را برای اپلیکیشن ریاکت تنظیم کنید و وارد وبسایت Sentry.io شوید. پس از آن که حساب کاربری خود را ساختید، میتوانید گزارشهای خطا را در داشبورد پروژهتان مشاهده و تحلیل کنید.
این گزارشها کاملاً دقیق و تفصیلی هستند، بنابراین میتوانید از حجم بالای اطلاعاتی که به رفع خطاها کمک میکند مانند دانستن دستگاه کاربر، نوع مرورگر، URL که در آن خطا رخ داده است، نشانی IP کاربر، ردگیری پشته خطا، مدیریت شدن یا نشدن خطا، نام تابع، سورس کد، فهرست مفیدی از مسیرها که رد اقدامات شبکه منجر به خطا را نشان میدهد، هدرها و موارد زیاد دیگر استفاده کنید.
در تصویر زیر نمایی از داشبورد آن را ملاحظه میکنید:
چندین عضو تیم میتوانند روی موارد مختلف توضیح بنویسند تا یک محیط مناسب برای کار تیمی ایجاد کنند.
5. از axios روی window.fetch استفاده کنید
اگر اهمیتی به کاربران مرورگر اینترنت اکسپلورر نمیدهید، میتوانید از window.fetch در اپلیکیشن ریاکت استفاده نکنید، زیرا هیچ کدام از مرورگرها غیر از اینترنت اکسپلورر از window.fetch استفاده نمیکنند، مگر این که polyfill عرضه کنید.
Axios (+) برای پشتیبانی از اینترنت اکسپلورر عالی است، اما کارکردهای سنتی که عرضه میکند نیز قابل توجه است. مثلاً با استفاده از آن میتوان درخواستها را در میانه راه لغو کرد. این در عمل روی هر وب اپلیکیشن اعمال میشود و خاص ریاکت نیست.
دلیل این که در این فهرست به این مورد اشاره می کیم آن است که امروزه به طور معمول window.fetch در اپلیکیشنهای ریاکت مورد استفاده قرار میگیرد. از آنجا که اپلیکیشنهای ریاکت از مراحل transpiling/compiling عبور میکنند، بسته به ابزارهایی که پیکربندی میشوند، ممکن است تصور شود که window.fetch نیز transpile میشود.
6. در زمان کار با گرههای DOM از ارجاع Callback به جای ارجاع شیء استفاده کنید
با این که React.useRef در زمینه الصاق و کنترل ارجاعها به یک گره DOM جدید محسوب میشود، اما همواره بهترین گزینه نیست. برخی اوقات میخواهیم کنترل بیشتری روی گره DOM داشته باشیم تا بتوانیم کارکرد اضافهای عرضه کنیم.
برای نمونه مستندات ریاکت (+) موقعیتی را توصیف میکنند که باید از یک ارجاع callback برای مطمئن شدن از این واقعیت استفاده کنیم که وقتی تغییراتی در مقدار ref کنونی ایجاد میشود، یک کامپوننت خارجی همچنان میتواند از بهروزرسانیها مطلع شود. این مزیتی است که ارجاعهای Callback نسبت به useRef دارند.
Material-ui از این مفهوم قدرتمند استفاده میکند تا کارکردهای اضافی را از طریق ماژولهای کامپوننت عرضه کند. مهمترین بخش در این مورد آن است که این رفتار به صورت طبیعی موجب پاکسازی میشود.
7. قلاب useWhyDidYouUpdate
این یک قلاب سفارشی است و تغییراتی که در زمان رندر مجدد کامپوننتها رخ میدهد، عرضه میکند. برخی اوقات زمانی که یک memoizer مانند کامپوننت مرتبه بالای React.memo کافی نیست، میتوانید از این قلاب سفارشی برای یافتن prop-هایی که باید به حافظه سپرده شوند بهره بگیرید.
شیوه استفاده از آن نیز چنین است:
8. تابعهای مرتبه بالا
یکی از بزرگترین مزایای تابعهای مرتبه بالا این است که وقتی به صورت صحیحی استفاده شوند، زمان زیادی از شما و تیمتان صرفهجویی میکنند. برای نمونه میتوان از React-Toastify (+) برای نمایش نوتیفیکیشنها بهره گرفت. از آن میتوان در هر جا استفاده کرد. به علاوه امکان اجرای سریع تصمیمهای UX را فراهم میسازد.
اگر نیاز به مدیریت یک خطا باشد، کافی است یک نوتیفیکیشن Toast نمایش دهید. با این حال شاید متوجه شوید که وقتی اپلیکیشن بزرگتر میشود، و سطح پیچیدگی بالاتر میرود، نوتیفیکیشنهای Toast بیش از حد زیاد میشوند.
این موضوع به خودی خود اشکالی ندارد، اما روشی برای جلوگیری از تکرار وجود ندارد. این بدان معنی است که برخی نوتیفیکیشنهای Toast چندین بار روی صفحه ظاهر میشوند و حتی برخی دقیقاً مانند موارد قبل خود هستند.
بنابراین در نهایت باید از یک API کمک گرفت که این کتابخانه برای کمک به حذف نوتیفیکیشنهای فعال از طریق id با استفاده از ()toast.dismiss ارائه کرده است. برای توضیح بیشتر این بخش بهتر است ابتدا یک فایل را نشان دهیم که Toast-ها را از آنجا ایمپورت میکنیم:
میدانیم که این کد چندان خوب نیست، اما در ادامه آن را اصلاح میکنیم. این کدی است که در کامپوننت مجزا داریم تا بررسی کنیم آیا Toast قبلی پیشتر روی صفحه بوده است یا نه و اگر چنین باشد، تلاش میکنیم تا آن را حذف کنیم و Toast جدید را نمایش دهیم.
این کد به خوبی کار میکند اما toast-های دیگری در سراسر اپلیکیشن داریم که باید به همین روش اصلاح شوند. بدن ترتیب باید به هر فایل که یک نوتیفیکیشن toast نمایش میدهد برویم و موارد تکراری را حذف کنیم.
زمانی که در این عصر صحبت از سر زدن به تکتک فایلها و اصلاح آنها میشود باید متوجه شویم که یک جای کار میلنگد. بنابراین فایل util/toast.js را بررسی میکنیم و آن را طوری بازنویسی میکنیم که مشکل ما را حل کند. فایل پس از اصلاح به صورت زیر درمیآید:
- فایل src/util/toast.js
به این ترتیب به جای این که به تکتک فایلها برویم، سادهترین راهحل این بود که یک تابع مرتبه بالا بسازیم. با این کار میتوانیم نقشها را معکوس کنیم به طوری که به جای جستجو به دنبال فایلها، toast-ها به تابع مرتبه بالا هدایت شوند. به این صورت کدهای موجود در فایلها ویرایش یا تغییر نمییابند. کارکرد آنها همچنان به طور معمول است و امکان حذف این Toast-های تکراری را بدون این که کد غیر ضروری بنویسیم پیدا میکنیم. این امر موجب صرفهجویی در زمان میشود. به این ترتیب به پایان این مقاله میرسیم. امیدواریم از مطالعه این راهنمای کاربردی در مورد ترفندهای بهبود اپلیکیشنهای ریاکت لذت برده باشید.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- ۱۰ نکته و ترفند برای بهبود برنامه نویسی React — راهنمای کاربردی
- هشت ترفند مفید برای توسعه اپلیکیشن های React — راهنمای کاربردی
- طراحی احراز هویت مقدماتی با React — به زبان ساده
==