روش بهینه سازی Flatlist در React Native

فلت لیست ها در React Native عملا یک نقش اساسی رو بازی می کنند و معمولا پیاده سازی های infinite scrolling باید با استفاده از این کامپوننت صورت بگیره چون بر خلاف ScrollView که تمامی آیتم های رنده شده رو چه داخل ViewPort باشند چه نباشند رو داخل رم نگه میداره FlatList که از خانواده Virtualizedlist ها هست زمانی که از آیتم رندر شده از ViewPort خارج بشه عملا از داخل رم پاک می شه.

خب تا اینجایی که می بینیم FlatList خیلی خفنه اما! اینجا یه اما خیلی ترسناک هست و اونم اینه که Flatlist شما بهینه نوشته نشه عملا خیلی کندی و لگ کاربر شما حس می کنه یا توی اسکرول های سریع معمولا صفحه سفید رو میبینه که خیلی چیز قشنگی نیست :)

خب حالا ما میخوایم با هم یکم Flatlist رو بهینه تر بنویسیم .

خب اولین گام اینه که برای فرزنده های ساخته شده از لایف سایکل shouldcomponentupdate یا به جای ساختن فرزندان با استفاده از React.Component از React.PureComponent استفاده کنیم مطمئنم اگه اولین مرحله رو رعایت کنیم قطعا خیلی از مشکلات حل میشن .

class Test extends React.PureComponent {
    ...
}

و هم اکنون میریم سراغ مرحله بعدی می تونیم داخل Flatlist مون از removeClippedSubviews که در اصل میاد هنگامی که آیتم مورد نظر از ViewPort حذف میشه به صورت کامل پاکش می کنه و دفعه بعد برای نمایشش دوباره از اول رندرش می کنه خب اینکه خیلی خفنه می تونیم همیشه استفاده کنیم اینجاست که به یک عدد نه! بر میخوریم متاسفانه طبقه گفته خود فیسبوک این یکم باگ داره هنوز که نیاز داره فیکس بشه ولی خب پیشنهاد من اینکه برای اندروید استفاده کنید .به صورت زیر

removeClippedSubviews={Platform.OS == 'ios' ? false : true}

سومین مرحله ی ما در اصل استفاده از کامپوننت های ساده تر و عکس های کش شده و بهینه شده برای موبایل هست برای اینکه عکس های سریع تر لود بشن میتونیم از پکیج زیر استفاده کنیم که خیلی خفنه و سرعت لود عکس های کش رو خیلی افزایش میده .

https://github.com/DylanVann/react-native-fast-image

حالا میایم سراغ مرحله ی آخر اگر هنوز هم مشکل داری تو Flatlist خودت که من بعید میدونم آخرین ترفند ما میتونه استفاده از getItemLayout باشه که عملا از البته زمانی به دردتون میخوره که اندازه تمامی کامپوننت های توی Flatlist مون هم اندازه باشن . داخل فلت لیست به صورت پیش فرض و پویا برای هر آیتم اندازه محاسبه میشه که خود این مورد باعث کند شدنش میشه با استفاده از getItemLayout ما خودمون محاسبه رو به عهده می گیریم.

  getItemLayout = (data, index) => ({
     length: height, //height of our View
     offset: height* index,  //position of item in Flatlist
     index // index of item
   })
 

راستی یادمون نره که از keyExtractor هم استفاده کنیم چون اگه نکنیم اینکارو همه کامپوننت ها هر بار از ViewPort خارج میشن و میخوان برگردن به ViewPort دوباره رندر میشن به جای اینکه از cache بیان.

امیدوارم Flatlist هاتون همیشه بی باگ و سریع باشه.