Feed mein bees items bilkul perfect lagte hain. Scroll bilkul smooth hota hai. Aapka client khush hota hai. Phir aap ise production mein ship karte hain, data aata hai, aur achanak aap do hazar rows ko dekh rahe hote hain. UI atakne lagta hai. Memory barhti jati hai jab tak ke OS ise band na kar de. Mayoosi mein, kuch developers sab kuch ScrollView mein wrap kar dete hain aur kaam khatam samajhte hain. Wo faisla aam taur par ek masle ke hal ke badle teen naye bugs paida karta hai.

Lists performance ka wo bottleneck hain jo ye tay karta hai ke users aapki React Native app ko kaise mehsoos karte hain. Agar aap inhe sahi tarah istemal karein to app native mehsoos hoti hai. Agar galat istemal karein to sab se khoobsurat screen bhi bojh ban jati hai. Iski asal wajah aam taur par us component aur us kaam ke darmiyan farq hota hai jo aap JavaScript aur UI threads se karwane ki koshish kar rahe hote hain. React Native do tracks par chalta hai. Aapka logic JS thread par hota hai jabke painting native UI thread par hoti hai. Jab aap ek bari list ko ghalat tarah se render karte hain, to dono threads layout calculations, re-renders, aur memory allocations mein doobne lagte hain. Iska natija dropped frames, blank flashes, aur aakhir-kar crash ki surat mein nikalta hai.

Sahi Tool ka Intekhab Karein

List component ka intekhab ek soch samajh kar kiya gaya architectural faisla hona chahiye, na ke sirf ek reflex.

ScrollView sab se sada option hai. Ye aapko jo bhi child dete hain, un sab ko foran memory mein mount kar deta hai, aur poora dher native scroll engine ko thama deta hai. Ye bilkul wahi hai jo aapko chote aur fixed content ke liye chahiye hota hai, jaise ke settings screen, login form, ya das sections wala koi static product detail page. Ye predictable hai aur isay style karna asaan hai. Masla ye hai ke is mein virtualization nahi hoti. Agar aap isay do hazar items dete hain, to ye farmabardar ki tarah do hazar native views bana dega. Bari ya dynamic data sets ke liye ScrollView istemal na karein. Isay ek framed poster ki tarah samjhein, library shelf ki tarah nahi.

FlatList lambi aur ek jaisi feeds ke liye behtareen tool hai. Ye content ko virtualize karta hai, jis ka matlab hai ke ye sirf unhi rows ko mount karta hai jo is waqt visible hain ya viewport ke qareeb hain. Jab user scroll karta hai, FlatList un cells ko unmount kar deta hai jo screen se bahar nikal jate hain aur unhein naye aane wale data ke liye recycle kar leta hai. Is se memory barabar rehti hai chahe aapka array kitna hi bara kyun na ho jaye. Agar aap social timeline, notification center, ya ek jaisi cards ka koi musalsal scroll hone wala collection bana rahe hain, to FlatList default taur par sahi intekhab hai.

SectionList organization ke ehsas ke sath FlatList hai. Isay tab istemal karein jab aapka data groups mein aata ho, jaise ke alphabetically sorted address book, date ke hisab se banta hua workout log, ya mahine ke hisab se organized invoice list. Ye sticky section headers render karta hai aur grouping logic ko aapke liye sambhalta hai. Is ke andar ye wahi virtualization engine istemal karta hai jo FlatList karta hai, is liye aapko wahi memory ke faide milte hain aur sath mein titled partitions ki structure bhi milti hai.

FlashList tab kaam aata hai jab aapko device se har ek frame nikalne ki zaroorat ho. RecyclerListView ecosystem par mabni, ye FlatList ke muqable mein views ko zyada tezi se recycle karta hai aur mid-range hardware par bhi sixty frames per second barkarar rakhne ka hadaf rakhta hai. Agar aap high-volume chat interface, tez scroll velocity wala product catalog, ya koi aisi screen bana rahe hain jahan smoothness ek muqabla karne wala advantage hai, to FlashList extra dependency ke liye qabil-e-amal hai. Ye har screen ke liye zaroori nahi hai, lekin un feeds ke liye jo core experience ko define karti hain, performance ka farq wazeh hota hai.

Performance Kharab Karne Wale Aam Asbab

Jab list sust hone lage to teen aam mashkook asbab hote hain.

Ek sath bohat zyada React trees ko mount karna sab se bara nuksan hai. Jab har row ek complex component tree hoti hai, to shuruati render JS thread ko itni der tak block kar sakta hai ke ek khali safaid screen ya ek bura sa delayed first paint nazar aaye. User app kholta hai aur intezar karta hai. Shuruati load ke baad bhi, bhari rows scroll initialization ko sust kar deti hain kyunke pehle kuch frames setup ke kaam mein kharch ho jate hain.

Har frame par bohat zyada kaam scroll ke dauran jhatkon (stuttering) ki surat mein nazar aata hai. Animations ko smooth rakhne ke liye aapke paas har frame ke liye taqreeban solah milliseconds ka budget hota hai. Agar ek row component mehngi calculations karta hai, on the fly dates parse karta hai, ya render ke andar gehre object comparisons karta hai, to aap apna budget khatam kar dete hain. UI thread frames drop kar deta hai aur user ko jhatka mehsoos hota hai.

Ziyada memory ka istemal ek khamosh qatil hai. Har native view RAM leta hai. Bare unoptimized images, har card par drop shadows, ya nested touchables shamil karein to footprint barh jata hai. iOS par system baghair kisi warning ke aapki app ko terminate kar sakta hai. Android par user lag ko barhte hue dekhta hai jab tak ke app istemal ke qabil na rahe.

Optimization Checklist

چھوٹی مگر حکمت عملی پر مبنی عادات ایک ایسی لسٹ میں فرق پیدا کرتی ہیں جو محض کام کرتی ہے اور اس میں جو انتہائی تیزی سے چلتی ہے۔

مستحکم keys کا استعمال کریں۔ اپنے ڈیٹا سیٹ سے ہمیشہ ایک حقیقی شناختی نمبر (identifier) کو key prop میں پاس کریں۔ کبھی بھی array index کا استعمال نہ کریں۔ اگر آپ کی لسٹ میں آئٹمز کی ترتیب بدلتی ہے، فلٹر ہوتے ہیں، یا نئے آئٹمز شامل ہوتے ہیں، تو index پر مبنی key React کو دھوکہ دے دیتی ہے کہ وہ غلط ڈیٹا کو غلط ری سائیکل شدہ (recycled) component کے ساتھ جوڑ دے۔ یہ غلطی غیر ضروری unmounts، state mismatches، اور مسلسل re-renders کا باعث بنتی ہے۔ ایک درست ID React کو بالکل صحیح طور پر بتاتی ہے کہ کون سی row کہاں منتقل ہوئی ہے۔

rows کو memoize کریں۔ اپنے row component کو React.memo میں لپیٹ دیں (wrap کریں) تاکہ وہ صرف اس وقت re-render ہو جب اس کے props واقعی تبدیل ہوں۔ اس حفاظتی تدبیر کے بغیر، parent state میں کوئی بھی تبدیلی ہر نظر آنے والی row کے render pass کا باعث بن سکتی ہے، چاہے ان کا ڈیٹا ایک جیسا ہی کیوں نہ ہو۔ ایک لمبی اور تیزی سے بدلتی ہوئی لسٹ میں، یہ ضائع شدہ سائیکلز (cycles) بہت جلد بڑھ جاتے ہیں۔

renderItem کو مستحکم رکھیں۔ ہر parent render پر renderItem prop کے اندر براہ راست نیا فنکشن بنانے سے گریز کریں۔ ایک inline arrow function جیسے کہ renderItem={({ item }) => <Row data={item} />} ہر بار parent کے اپ ڈیٹ ہونے پر ایک نیا reference تخلیق کرتا ہے۔ FlatList اسے تبدیل شدہ prop سمجھتا ہے اور بلا ضرورت row کو ری سائیکل کر دیتا ہے۔ render function کو component سے باہر ڈیفائن کریں یا اسے useCallback کے ساتھ memoize کریں تاکہ reference مستحکم رہے۔

جہاں ممکن ہو getItemLayout کا استعمال کریں۔ اگر آپ کی rows کی اونچائی (height) مقررہ یا قابلِ پیش گوئی ہے، تو FlatList کو بالکل صحیح طور پر بتائیں۔ یہ prop لسٹ کو مہنگے native measurement calls کو چھوڑنے کی اجازت دیتا ہے۔ Mount ہونے کے بعد ہر سیل (cell) کی پیمائش کرنے کے بجائے، لسٹ ریاضیاتی طور پر پوزیشن کا حساب لگا لیتی ہے۔ اس کا فرق خاص طور پر ان لسٹوں میں واضح ہوتا ہے جن میں سینکڑوں یا ہزاروں آئٹمز ہوں، جہاں onLayout کی مسلسل سرگرمی JS thread کو مفلوج کر سکتی ہے۔

تصاویر کو بھرپور طریقے سے Optimize کریں۔ غیر محدود (unbounded) تصاویر لسٹ کے لیے زہر کے समान ہیں۔ ہمیشہ واضح width اور height سیٹ کریں تاکہ تصویر کے decode ہونے سے پہلے native layer جگہ محفوظ کر لے۔ ریموٹ تصاویر کے لیے، Expo Image جیسی caching library یا اس کے مساوی کوئی ایسی لائبریری استعمال کریں جو memory caching، disk persistence، اور format optimization کو سنبھال سکے۔ ڈیفالٹ React Native Image component پروٹوٹائپس کے لیے تو ٹھیک ہے، لیکن پروڈکشن فیڈز کے لیے memory اور loading states پر زیادہ کنٹرول کی ضرورت ہوتی ہے۔

Scroll containers کو ایک دوسرے کے اندر رکھنے (nesting) سے گریز کریں۔ کبھی بھی ایک vertical FlatList کو vertical ScrollView کے اندر نہ رکھیں۔ Parent ScrollView تمام scroll events کو خود سنبھال لیتا ہے اور child FlatList کی اپنے viewport کی پیمائش کرنے کی صلاحیت کو متاثر کرتا ہے۔ Virtualization کام کرنا چھوڑ دیتی ہے کیونکہ FlatList کو اب یہ معلوم نہیں رہتا کہ کون سی rows نظر آنی چاہئیں۔ نتیجہ یہ نکلتا ہے کہ ہر row ہر حال میں mount ہو جاتی ہے، جس سے virtualization کا پورا مقصد ہی ختم ہو جاتا ہے۔ اگر آپ کو لسٹ کے اوپر ہیڈر چاہیے، تو FlatList کے اپنے ListHeaderComponent prop کا استعمال کریں۔ اگر آپ کو پیچیدہ sticky behavior چاہیے، تو مناسب header configuration کے ساتھ SectionList یا FlashList استعمال کریں۔

سنہری اصول

اگر مواد (content) کم اور محدود ہے، تو اسے ScrollView کے سپرد کر دیں۔ اگر مواد صارف کے تیار کردہ ڈیٹا یا ریموٹ pagination کے ساتھ بڑھتا ہے، تو virtualized list استعمال کریں۔ جب لسٹ ایپ کا مرکزی حصہ ہو اور صارفین ایک وقت میں کئی منٹ تک اسکرول کریں، تو FlashList کا انتخاب کریں۔

یہاں ایک آخری حقیقت ہے جسے بھول جانا آسان ہے۔ سادہ (boring) rows تیزی سے اسکرول ہوتی ہیں۔ آپ کا row component جتنا ہلکا ہوگا، آپ کی لسٹ اتنی ہی ہموار (smooth) ہوگی۔ انفرادی row سے nested navigations، بھاری computations، اور غیر ضروری animations کو ختم کر دیں۔ Markup کو سادہ (flat)، logic کو ہلکا (thin)، اور تصاویر کو درست سائز کا رکھیں۔ ایک لسٹ کا زندہ رہنا یا ختم ہو جانا اس بات پر منحصر ہے کہ وہ کتنا بوجھ (weight) رینڈر کر رہی ہے۔ ہر row کو ہلکا (cheap) بنائیں، اور لسٹ بہترین ممکنہ طریقے سے اعلیٰ معیار (expensive) کی محسوس ہوگی۔