۶ روش آسان برای سرعت بخشیدن به اپلیکیشن های React Native


در این مقاله برخی از نکاتی که برای سرعت بخشیدن به اجرای اپلیکیشن react native و رسیدن به نرخهای فریم (FPS) بالا نیاز است را بررسی میکنیم.
1. استفاده از PureComponent یا shouldComponentUpdate
PureComponent در React پیش از بهروزرسانی کامپوننت مقایسهای سطحی از props و state صورت میدهد. این قابلیت باعث میشود که کامپوننت تنها در صورتی مجدداً رندر شود که تغییراتی در props یا state ایجاد شده باشد.
متد چرخه عمر shouldComponentUpdate به طور منظم اجرا میشود تا کامپوننتهای ناخالص React با بازگشت مقدار false در سناریوهای خاص رندر مجدد را لغو کنند.
دو قطعه کد زیر مفاهیم فوق را به صورت عملی نشان میدهند:
class MyComponent extends React.PureComponent { // } class MyComponent extends React.Component { // shouldComponentUpdate(nextProps, nextState) { if(this.props.firstProp === nextProps. firstProp && this.props.secondProp === nextProps.secondProp) { return false; } return true } // }
هر دو نمونه از کد فوق میتوانند به کاهش رندرهای بیهوده کمک کنند. مثال اول از پیادهسازی منطق shouldComponentUpdate استفاده میکند. مثال دوم امکان داشتن کنترل بیشتری را ایجاد میکند. در این حالت میتوان state را در کامپوننت تعیین کرد و در صورتی که تغییر یافته باشد، رندر مجدد صورت بگیرد. روش کار به صورت زیر است:
class MyComponent extends React.Component { shouldComponentUpdate(nextProps, nextState) { if(this.state.isLoading === nextState. isLoading) { return false; } return true } }
2. استفاده از خصوصت کلید روی آیتمهای لیست
لیست پراستفادهترین چیز در هر اپلیکیشن است. اگر برای هر آیتم لیست، کلید یکتایی تعریف نکنید، react هنگامی که آیتمی به لیست اضافه یا از آن حذف شود، همه آیتمها را مجدداً رندر میگیرد. داشتن یک کلید یکتا روی هر آیتم لیست باعث صرفهجویی در رندر مجدد react میشود.
class MyComponent extends React.PureComponent { render() { return this.props.data.map((item, i) => { return <Text key={item.id}>{item.title}</Text> }); } }
3. اتصال زودهنگام و عدم ایجاد تابعها درون رندر
بدین منظور باید به روش زیر عمل کنید:
class MyComponent extends React.PureComponent { constructor(props) { super(props); this.doWork = this.doWork.bind(this); } doWork() { // doing some work here. // this.props.dispatch.... } render() { return <Text onPress={this.doWork}>Do Some Work</Text> } }
کارهای زیر نباید درون رندر صورت بگیرد.
<Text onPress={ () => this.doWork() }>Do Some Work</Text>
یا
<Text onPress={ this.doWork.bind(this) }>Do Some Work</Text>
چون رندر به صورت مکرر فراخوانی میشود و هر بار هم دو کار فوق تکرار میشوند و تابع جدیدی ایجاد میشود.
اگر میخواهید آرگومانها را به تابع doWork ارسال کنید، ممکن است لازم باشد یک کامپوننت فرزند ایجاد کرده و آن را به صورت یک prop به تابع ارسال کنید.
<child arg1={arg1}></child>
و در کامپوننت فرزند:
doWork() { console.log(this.props.arg1); } render() { return <Text onPress={this.doWork}>Do Some Work</Text> }
اگر ایجاد کامپوننت نوعی سربار محسوب میشود، در این صورت همواره دستاورد عملکردی اندکی وجود خواهد داشت. میتوان از یک closure مانند زیر استفاده کرد. این تابعی است که قرار است در هر بار رندر مجدد ایجاد شود.
doWork = (param) => () => { console.log(param) } <Text onPress={this.doWork(someVarParam)}Do Some Work With Args</Text>
در چنین مواردی باید بین میزان خوانایی و عملکرد تعادلی برقرار کنید.
4. عدم بهروزرسانی state یا انتخاب اعمال در componentWillUpdate
متد چرخه عمر componentWillUpdate برای آمادهسازی یک بهروزرسانی استفاده میشود و نه اجرای یک بهروزرسانی دیگر. اگر میخواهید یک state تعیین کنید باید این کار را در componentWillReceiveProps انجام دهید. همچنین componentDidUpdate برای انتخاب هر یک از اعمال redux نسبت به componentWillReceiveProps ترجیح دارد.
5. استفاده از VirtualizedList ،FlatList و SectionList برای مجموعه دادههای بزرگ
بر اساس مستندات React native میدانیم که VirtualizedList, FlatList و SectionList رابطهای ارجح برای رندر کردن لیستها هستند، چون از حافظه کمتری استفاده میکنند. بنابراین اگر لیستی با صدها ردیف دارید، همه آنها تا زمانی که اسکرول نکردهاید، روی صفحه بارگذاری نمیشوند.
6. استفاده از Perf monitor برای مشاهده FPS
بخش developer tools را باز کرده و perf monitor را فعال کنید. اینک هر زمان که شروع به تعامل بکنید، به بخشهای مختلف بروید یا روی اپلیکیشن اسکرول بکنید، میتوانید نرخ فریمهای از دست رفته را مشاهده کنید. در اغلب موارد این فریمهای از دست رفته در نخ (thread) جاوا اسکریپت هستند و نه نخ UI. از این رو باید به دنبال ریشه مشکل بود، یعنی جایی که نرخ فریم از دست میرود. ممکن است تعیین حالت یا انتخاب اعمال redux در مکان نامناسبی صورت میگیرد. یا این که کارهای همگام زیادی روی نخ جاوا اسکریپت صورت میگیرند.
اگر این مطلب برایتان مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای طراحی و برنامه نویسی وب
- بهینهسازی کدهای جاوا اسکریپت در سال ۲۰۱۸
- مجموعه آموزشهای برنامهنویسی
- آموزش مقدماتی فریمورک React Native برای طراحی نرم افزارهای اندروید و iOS با زبان جاوااسکریپت
- چگونه با React Native اپلیکیشن اندرویدی بنویسیم؟ — به زبان ساده
- مقایسه Swift و React-Native از فریمورکهای ساخت اپلیکیشن در iOS
==
سلام
ممنون از مطلب و آموزش تون … یه سئوال ؟
برای نکته شماره 5 شما در مورد فلت لیست : میشه اینجور برداشت کرد که نیازی به load more برای فلت لیست نیست ؟ و دیگه نیازی به پیاده سازی نداره و اسکرول همین کار رو میکنه . البته صرفنظر از خواندن مثلا ده رکورد از دیتابیس . میشه مثلا هزار رکورد رو دریافت کرد و با اسکرول خودش نمایش بده
ممنونم