ഒരു ഫീഡിൽ ഇരുപത് ഐറ്റങ്ങൾ ഉണ്ടെങ്കിൽ അത് പെർഫെക്റ്റ് ആയി തോന്നും. സ്ക്രോളിംഗ് വളരെ സ്മൂത്ത് ആയിരിക്കും. നിങ്ങളുടെ ക്ലയന്റ് സന്തോഷവാനായിരിക്കും. എന്നാൽ നിങ്ങൾ അത് പ്രൊഡക്ഷനിലേക്ക് എത്തിക്കുമ്പോൾ, ഡാറ്റ വരുന്നു, പെട്ടെന്ന് നിങ്ങൾ രണ്ടായിരം വരികൾക്ക് മുന്നിൽ നിൽക്കുന്നു. UI തടസ്സപ്പെടാൻ തുടങ്ങുന്നു. മെമ്മറി ഉപയോഗം കൂടുകയും ഒടുവിൽ OS ആപ്പ് നിർബന്ധപൂർവ്വം അവസാനിപ്പിക്കുകയും ചെയ്യുന്നു. നിരാശരായി ചില ഡെവലപ്പർമാർ എല്ലാം ഒരു ScrollView-യിൽ പൊതിഞ്ഞ് പ്രശ്നം തീർക്കാൻ ശ്രമിക്കുന്നു. എന്നാൽ ആ തീരുമാനം ഒരു പ്രശ്നം പരിഹരിക്കുമ്പോൾ മൂന്ന് പുതിയ ബഗുകൾക്ക് കാരണമാകും.

നിങ്ങളുടെ React Native ആപ്പിനെ ഉപയോക്താക്കൾ എങ്ങനെ കാണുന്നു എന്ന് നിശ്ചയിക്കുന്ന പെർഫോമൻസ് തടസ്സങ്ങളാണ് ലിസ്റ്റുകൾ. അവ ശരിയായി ചെയ്താൽ ആപ്പ് ഒരു നേറ്റീവ് ആപ്പ് പോലെ തോന്നും. തെറ്റായി ചെയ്താൽ ഏറ്റവും മനോഹരമായ സ്ക്രീൻ പോലും ഉപയോഗിക്കാൻ പ്രയാസമുള്ളതായി മാറും. ഇതിന്റെ പ്രധാന കാരണം നിങ്ങൾ തിരഞ്ഞെടുത്ത കോംപോണന്റും, JavaScript, UI threads എന്നിവയ്ക്ക് നിങ്ങൾ നൽകുന്ന ജോലിയും തമ്മിലുള്ള പൊരുത്തക്കേടാണ്. React Native രണ്ട് ട്രാക്കുകളിലാണ് പ്രവർത്തിക്കുന്നത്. നിങ്ങളുടെ ലോജിക് JS thread-ലും, വിഷ്വൽ കാര്യങ്ങൾ (painting) native UI thread-ലുമാണ് നടക്കുന്നത്. നിങ്ങൾ ഒരു വലിയ ലിസ്റ്റ് തെറ്റായ രീതിയിൽ റെൻഡർ ചെയ്യുമ്പോൾ, ലേഔട്ട് കാൽക്കുലേഷനുകൾ, റീ-റെൻഡറുകൾ, മെമ്മറി അലോക്കേഷനുകൾ എന്നിവയിൽ രണ്ട് ത്രെഡുകളും കുടുങ്ങും. ഇതിന്റെ ഫലമായി ഫ്രെയിമുകൾ നഷ്ടപ്പെടുകയും (dropped frames), സ്ക്രീൻ വെളുത്ത് വരികയും, ഒടുവിൽ ആപ്പ് ക്രാഷ് ആകുകയും ചെയ്യുന്നു.

ശരിയായ ടൂൾ തിരഞ്ഞെടുക്കുക

ഒരു ലിസ്റ്റ് കോംപോണന്റ് തിരഞ്ഞെടുക്കുന്നത് ഒരു ആർക്കിടെക്ചറൽ തീരുമാനമായിരിക്കണം, വെറുമൊരു ശീലമായിരിക്കരുത്.

ScrollView ആണ് ഏറ്റവും ലളിതമായ ഓപ്ഷൻ. നിങ്ങൾ നൽകുന്ന ഓരോ ചൈൽഡ് എലമെന്റും ഇത് ഉടൻ തന്നെ മെമ്മറിയിൽ ലോഡ് ചെയ്യുകയും മുഴുവൻ ലിസ്റ്റും നേറ്റീവ് സ്ക്രോൾ എഞ്ചിന് കൈമാറുകയും ചെയ്യുന്നു. സെറ്റിംഗ്സ് സ്ക്രീൻ, ലോഗിൻ ഫോം അല്ലെങ്കിൽ പത്ത് സെക്ഷനുകളുള്ള ഒരു സ്റ്റാറ്റിക് പ്രൊഡക്റ്റ് ഡീറ്റെയിൽ പേജ് പോലുള്ള ചെറിയ ഉള്ളടക്കങ്ങൾക്ക് ഇത് അനുയോജ്യമാണ്. ഇത് പ്രവചിക്കാവുന്നതും സ്റ്റൈൽ ചെയ്യാൻ എളുപ്പവുമാണ്. ഇതിലെ പ്രശ്നം ഇതിൽ വിർച്വലൈസേഷൻ (virtualization) ഇല്ല എന്നതാണ്. നിങ്ങൾ രണ്ടായിരം ഐറ്റങ്ങൾ നൽകിയാൽ, അത് രണ്ടായിരം നേറ്റീവ് വ്യൂകൾ നിർമ്മിക്കും. വലിയതോ ഡൈനാമിക് ആയതോ ആയ ഡാറ്റാ സെറ്റുകൾക്കായി ScrollView ഉപയോഗിക്കരുത്. ഇതിനെ ഒരു ലൈബ്രറി ഷെൽഫിന് പകരം ഒരു ഫ്രെയിം ചെയ്ത പോസ്റ്റർ പോലെ കരുതുക.

FlatList ആണ് നീളമുള്ളതും ഒരേപോലെയുള്ളതുമായ ഫീഡുകൾക്ക് ഏറ്റവും അനുയോജ്യം. ഇത് കണ്ടന്റ് വിർച്വലൈസ് ചെയ്യുന്നു, അതായത് നിലവിൽ സ്ക്രീനിൽ കാണുന്നതോ അല്ലെങ്കിൽ സ്ക്രീനിന് അടുത്തുള്ളതോ ആയ വരികൾ മാത്രമേ ഇത് മെമ്മറിയിൽ ലോഡ് ചെയ്യുകയുള്ളൂ. ഉപയോക്താവ് സ്ക്രോൾ ചെയ്യുമ്പോൾ, സ്ക്രീനിൽ നിന്ന് പുറത്തുപോകുന്ന സെല്ലുകളെ FlatList അൺമൗണ്ട് ചെയ്യുകയും പുതിയ ഡാറ്റയ്ക്കായി അവ വീണ്ടും ഉപയോഗിക്കുകയും (recycle) ചെയ്യുന്നു. ഇത് നിങ്ങളുടെ അറേ എത്ര വലുതായാലും മെമ്മറി ഉപയോഗം ഒരുപോലെ നിലനിർത്തുന്നു. നിങ്ങൾ ഒരു സോഷ്യൽ ടൈംലൈൻ, നോട്ടിഫിക്കേഷൻ സെന്റർ അല്ലെങ്കിൽ സമാനമായ കാർഡുകളുടെ ഒരു ശേഖരം എന്നിവയാണ് നിർമ്മിക്കുന്നതെങ്കിൽ, FlatList ആണ് ശരിയായ തിരഞ്ഞെടുപ്പ്.

SectionList എന്നത് ഓർഗനൈസ്ഡ് ആയ ഒരു FlatList ആണ്. അക്ഷരമാലാക്രമത്തിൽ ക്രമീകരിച്ച അഡ്രസ് ബുക്ക്, തീയതി അനുസരിച്ചുള്ള വർക്ക്ഔട്ട് ലോഗ് അല്ലെങ്കിൽ മാസം അനുസരിച്ചുള്ള ഇൻവോയ്സ് ലിസ്റ്റ് എന്നിങ്ങനെ ഗ്രൂപ്പുകളായി വരുന്ന ഡാറ്റയ്ക്ക് ഇത് ഉപയോഗിക്കാം. ഇത് സ്റ്റിക്കി സെക്ഷൻ ഹെഡറുകൾ റെൻഡർ ചെയ്യുകയും ഗ്രൂപ്പിംഗ് ലോജിക് കൈകാര്യം ചെയ്യുകയും ചെയ്യുന്നു. ഇതിന്റെ പിന്നിൽ FlatList-ന്റെ അതേ വിർച്വലൈസേഷൻ എഞ്ചിൻ തന്നെയാണ് ഉപയോഗിക്കുന്നത്, അതിനാൽ സമാനമായ മെമ്മറി ലാഭത്തോടൊപ്പം മികച്ച ഘടനയും നിങ്ങൾക്ക് ലഭിക്കുന്നു.

FlashList ഉപയോഗിക്കുന്നത് ഉപകരണത്തിന്റെ പരമാവധി പെർഫോമൻസ് വേണമെന്നുണ്ടെങ്കിൽ ആണ്. RecyclerListView എക്കോസിസ്റ്റത്തിന് മുകളിൽ നിർമ്മിച്ച ഇത്, FlatList-നേക്കാൾ വേഗത്തിൽ വ്യൂകളെ റീസൈക്കിൾ ചെയ്യുന്നു. മിഡ്-റേഞ്ച് ഹാർഡ്‌വെയറിലും സെക്കൻഡിൽ അറുപത് ഫ്രെയിമുകൾ (60 FPS) നിലനിർത്താൻ ഇത് ലക്ഷ്യമിടുന്നു. നിങ്ങൾ ഒരു ഹൈ-വോളിയം ചാറ്റ് ഇന്റർഫേസ്, വേഗത്തിൽ സ്ക്രോൾ ചെയ്യാവുന്ന ഒരു പ്രൊഡക്റ്റ് കാറ്റലോഗ് അല്ലെങ്കിൽ സ്മൂത്ത്‌നെസ്സ് വളരെ പ്രധാനപ്പെട്ട ഏതെങ്കിലും സ്ക്രീൻ എന്നിവ നിർമ്മിക്കുകയാണെങ്കിൽ, FlashList ഉപയോഗിക്കുന്നത് ഗുണകരമാണ്. എല്ലാ സ്ക്രീനുകൾക്കും ഇത് ആവശ്യമില്ല, എന്നാൽ ആപ്പിന്റെ പ്രധാന അനുഭവം നൽകുന്ന ഫീഡുകൾക്ക് ഇതിന്റെ പെർഫോമൻസ് വ്യത്യാസം വ്യക്തമായി കാണാൻ സാധിക്കും.

സാധാരണയായി പെർഫോമൻസ് കുറയ്ക്കുന്ന ഘടകങ്ങൾ

ഒരു ലിസ്റ്റ് സാവധാനത്തിലാകുമ്പോൾ പ്രധാനമായും മൂന്ന് കാരണങ്ങളുണ്ടാകാം.

ഒരേസമയം ഒരുപാട് React trees മൗണ്ട് ചെയ്യുന്നത് ഏറ്റവും വലിയ പരാജയമാണ്. ഓരോ വരിയും സങ്കീർണ്ണമായ ഒരു കോംപോണന്റ് ട്രീ ആണെങ്കിൽ, ആദ്യത്തെ റെൻഡറിംഗ് സമയത്ത് JS thread ബ്ലോക്ക് ആകുകയും സ്ക്രീൻ വെളുത്ത നിറത്തിൽ നിൽക്കുകയോ അല്ലെങ്കിൽ റെൻഡറിംഗ് വൈകുകയോ ചെയ്യാം. ഉപയോക്താവ് ആപ്പ് തുറന്ന് കാത്തിരിക്കേണ്ടി വരുന്നു. ആദ്യ ലോഡിന് ശേഷവും, ഭാരമേറിയ വരികൾ കാരണം സ്ക്രോളിംഗ് തുടങ്ങാൻ താമസം നേരിടുന്നു, കാരണം ആദ്യത്തെ കുറച്ച് ഫ്രെയിമുകൾ സെറ്റപ്പ് ജോലികൾക്കായി ഉപയോഗിക്കപ്പെടുന്നു.

ഓരോ ഫ്രെയിമിലും അമിതമായ ജോലി ചെയ്യുന്നത് സ്ക്രോളിംഗ് സമയത്ത് തടസ്സങ്ങൾ (stuttering) ഉണ്ടാക്കുന്നു. ആനിമേഷനുകൾ സ്മൂത്ത് ആയി നിലനിർത്താൻ ഒരു ഫ്രെയിമിന് ഏകദേശം പതിനാറ് മില്ലിസെക്കൻഡ് മാത്രമേ സമയം ലഭിക്കൂ. ഒരു വരിയിലെ കോംപോണന്റ് കഠിനമായ കണക്കുകൂട്ടലുകൾ നടത്തുകയോ, ഡേറ്റുകൾ പാഴ്സ് ചെയ്യുകയോ, റെൻഡറിംഗിനുള്ളിൽ ഡീപ്പ് ഒബ്ജക്റ്റ് കമ്പാരിസൺ നടത്തുകയോ ചെയ്താൽ ആ സമയം നിങ്ങൾ ഉപയോഗിച്ചു തീർക്കും. ഇത് UI thread ഫ്രെയിമുകൾ നഷ്ടപ്പെടുത്തുകയും ഉപയോക്താവിന് സ്ക്രോളിംഗ് തടസ്സപ്പെടുന്നത് അനുഭവപ്പെടുകയും ചെയ്യുന്നു.

അമിതമായ മെമ്മറി ഉപയോഗം ഒരു നിശബ്ദ കൊലയാളിയാണ്. ഓരോ നേറ്റീവ് വ്യൂവിനും RAM ആവശ്യമാണ്. വലിയ ചിത്രങ്ങൾ, ഓരോ കാർഡിലും ഡ്രോപ്പ് ഷാഡോകൾ, അല്ലെങ്കിൽ നെസ്റ്റഡ് ടച്ചബിളുകൾ എന്നിവ ചേർക്കുമ്പോൾ മെമ്മറി ഉപയോഗം കുത്തനെ കൂടുന്നു. iOS-ൽ സിസ്റ്റം മുന്നറിയിപ്പില്ലാതെ നിങ്ങളുടെ ആപ്പ് അവസാനിപ്പിച്ചേക്കാം. ആൻഡ്രോയിഡിൽ ആപ്പ് ഉപയോഗിക്കാൻ കഴിയാത്ത അവസ്ഥ വരുന്നത് വരെ ലാഗ് കൂടുന്നത് ഉപയോക്താവിന് കാണേണ്ടി വരും.

ഒപ്റ്റിമൈസേഷൻ ചെക്ക്‌ലിസ്റ്റ്

വെറുമൊരു ലിസ്റ്റ് എന്നതിലുപരി അതിവേഗത്തിൽ പ്രവർത്തിക്കുന്ന ഒരു ലിസ്റ്റ് ഉണ്ടാക്കിയെടുക്കാൻ ചില ചെറിയ തന്ത്രപരമായ ശീലങ്ങൾ ആവശ്യമാണ്.

സ്ഥിരമായ (stable) keys ഉപയോഗിക്കുക. നിങ്ങളുടെ ഡാറ്റാ സെറ്റിൽ നിന്നുള്ള യഥാർത്ഥ ഐഡന്റിഫയർ (identifier) എപ്പോഴും key പ്രോപ്പിലേക്ക് നൽകുക. ഒരിക്കലും array index ഉപയോഗിക്കരുത്. ലിസ്റ്റിലെ ഐറ്റങ്ങൾ പുനഃക്രമീകരിക്കുകയോ (reorder), ഫിൽട്ടർ ചെയ്യുകയോ അല്ലെങ്കിൽ പുതിയവ ചേർക്കുകയോ ചെയ്യുമ്പോൾ, ഇൻഡക്സ് അടിസ്ഥാനമാക്കിയുള്ള കീ ഉപയോഗിക്കുന്നത് തെറ്റായ ഡാറ്റ തെറ്റായ കമ്പോണന്റുമായി ബന്ധിപ്പിക്കാൻ React-നെ പ്രേരിപ്പിക്കും. ഈ തെറ്റ് അനാവശ്യമായ unmounts, state mismatches, കൂടാതെ തുടർച്ചയായ re-renders എന്നിവയ്ക്ക് കാരണമാകും. കൃത്യമായ ഒരു ID ഉപയോഗിക്കുന്നതിലൂടെ ഏത് വരി (row) എങ്ങോട്ടാണ് മാറിയതെന്ന് React-ന് കൃത്യമായി മനസ്സിലാക്കാൻ സാധിക്കും.

Rows memoize ചെയ്യുക. നിങ്ങളുടെ row കമ്പോണന്റിനെ React.memo ഉപയോഗിച്ച് റാപ്പ് ചെയ്യുക, അങ്ങനെ അതിന്റെ props മാറുന്ന സമയത്ത് മാത്രം അത് re-render ആകുന്നു എന്ന് ഉറപ്പാക്കാം. ഈ മുൻകരുതൽ ഇല്ലെങ്കിൽ, ഡാറ്റാ ഒന്നുതന്നെയാണെങ്കിൽ പോലും, പാരന്റ് സ്റ്റേറ്റ് (parent state) അപ്ഡേറ്റ് ചെയ്യപ്പെടുമ്പോൾ എല്ലാ വരികളും വീണ്ടും render ചെയ്യപ്പെടാൻ സാധ്യതയുണ്ട്. നീളമേറിയ ലിസ്റ്റുകളിൽ ഇത്തരം അനാവശ്യമായ പ്രക്രിയകൾ പെട്ടെന്ന് പെർഫോമൻസിനെ ബാധിക്കും.

renderItem സ്ഥിരമായി നിലനിർത്തുക. ഓരോ തവണ പാരന്റ് റെൻഡർ ചെയ്യുമ്പോഴും renderItem പ്രോപ്പിനുള്ളിൽ പുതിയൊരു ഫംഗ്ഷൻ നിർവചിക്കുന്നത് ഒഴിവാക്കുക. renderItem={({ item }) => <Row data={item} />} പോലുള്ള ഒരു inline arrow function ഉപയോഗിക്കുന്നത് പാരന്റ് അപ്ഡേറ്റ് ചെയ്യുമ്പോഴെല്ലാം പുതിയൊരു റെഫറൻസ് (reference) സൃഷ്ടിക്കും. ഇത് മാറ്റം വന്ന ഒരു പ്രോപ്പ് ആയി FlatList കണക്കാക്കുകയും അനാവശ്യമായി വരികൾ റീസൈക്കിൾ ചെയ്യുകയും ചെയ്യും. അതിനാൽ, render ഫംഗ്ഷൻ കമ്പോണന്റിന് പുറത്ത് നിർവചിക്കുകയോ അല്ലെങ്കിൽ റെഫറൻസ് സ്ഥിരമായിരിക്കാൻ useCallback ഉപയോഗിച്ച് memoize ചെയ്യുകയോ ചെയ്യുക.

സാധ്യമാകുമ്പോഴെല്ലാം getItemLayout ഉപയോഗിക്കുക. നിങ്ങളുടെ വരികൾക്ക് (rows) നിശ്ചിത ഉയരം (fixed height) ഉണ്ടെങ്കിൽ അത് FlatList-നെ കൃത്യമായി അറിയിക്കുക. ഈ പ്രോപ്പ് ഉപയോഗിക്കുന്നതിലൂടെ വിലകൂടിയ native measurement calls ഒഴിവാക്കാൻ സാധിക്കും. ഓരോ സെല്ലും മൗണ്ട് ചെയ്ത ശേഷം അളക്കുന്നതിന് പകരം, ലിസ്റ്റ് ഗണിതശാസ്ത്രപരമായി (mathematically) അതിന്റെ സ്ഥാനം കണക്കാക്കുന്നു. നൂറുകണക്കിന് അല്ലെങ്കിൽ ആയിരക്കണക്കിന് ഐറ്റങ്ങളുള്ള ലിസ്റ്റുകളിൽ ഇത് വലിയ വ്യത്യാസം ഉണ്ടാക്കും; കാരണം onLayout വഴിയുള്ള നിരന്തരമായ കോളുകൾ JS thread-നെ സ്ലോ ആക്കിയേക്കാം.

ചിത്രങ്ങൾ (images) കാര്യക്ഷമമായി ഒപ്റ്റിമൈസ് ചെയ്യുക. കൃത്യമായ അളവില്ലാത്ത ചിത്രങ്ങൾ ലിസ്റ്റിന്റെ വേഗത കുറയ്ക്കും. ഇമേജ് ഡീകോഡ് ചെയ്യുന്നതിന് മുമ്പ് തന്നെ സ്പേസ് റിസർവ് ചെയ്യാൻ പാകത്തിൽ എപ്പോഴും കൃത്യമായ width, height എന്നിവ നൽകുക. റിമോട്ട് ഇമേജുകൾക്കായി, മെമ്മറി കാഷിംഗ് (memory caching), ഡിസ്ക് പെർസിസ്റ്റൻസ് (disk persistence), ഫോർമാറ്റ് ഒപ്റ്റിമൈസേഷൻ എന്നിവ കൈകാര്യം ചെയ്യുന്ന Expo Image പോലുള്ള ഒരു കാഷിംഗ് ലൈബ്രറി ഉപയോഗിക്കുക. പ്രോട്ടോടൈപ്പുകൾക്ക് സാധാരണ React Native Image കമ്പോണന്റ് മതിയാകും, എന്നാൽ പ്രൊഡക്ഷൻ ആപ്പുകളിൽ മെമ്മറിയും ലോഡിംഗ് സ്റ്റേറ്റും നിയന്ത്രിക്കാൻ കൂടുതൽ കൺട്രോൾ ആവശ്യമാണ്.

Scroll containers ഒന്നിനുള്ളിൽ ഒന്നായി ഉപയോഗിക്കുന്നത് ഒഴിവാക്കുക. ഒരു വെർട്ടിക്കൽ FlatList ഒരിക്കലും ഒരു വെർട്ടിക്കൽ ScrollView-യ്ക്കുള്ളിൽ വെക്കരുത്. പാരന്റ് ScrollView എല്ലാ സ്ക്രോൾ ഇവന്റുകളും ഏറ്റെടുക്കുന്നതിനാൽ, ചൈൽഡ് FlatList-ന് അതിന്റെ വ്യൂപോർട്ട് (viewport) അളക്കാൻ സാധിക്കാതെ വരും. ഇത് Virtualization പ്രക്രിയയെ തടസ്സപ്പെടുത്തുന്നു, കാരണം ഏത് വരികളാണ് കാണിക്കേണ്ടതെന്ന് FlatList-ന് മനസ്സിലാക്കാൻ കഴിയില്ല. ഇതിന്റെ ഫലമായി എല്ലാ വരികളും മൗണ്ട് ചെയ്യപ്പെടുകയും Virtualization എന്ന ലക്ഷ്യം തന്നെ ഇല്ലാതാവുകയും ചെയ്യുന്നു. ലിസ്റ്റിന് മുകളിൽ ഒരു ഹെഡർ വേണമെങ്കിൽ FlatList-ന്റെ തന്നെ ListHeaderComponent പ്രോപ്പ് ഉപയോഗിക്കുക. സങ്കീർണ്ണമായ sticky behavior ആവശ്യമാണെങ്കിൽ, അനുയോജ്യമായ ഹെഡർ കോൺഫിഗറേഷനോടെയുള്ള SectionList അല്ലെങ്കിൽ FlashList ഉപയോഗിക്കുക.

സുവർണ്ണ നിയമം

ഉള്ളടക്കം കുറവാണെങ്കിൽ ScrollView ഉപയോഗിക്കാം. എന്നാൽ ഉപയോക്താക്കൾ നൽകുന്ന ഡാറ്റയോ അല്ലെങ്കിൽ റിമോട്ട് പേജിനേഷനോ (remote pagination) വഴി ഉള്ളടക്കം കൂടുന്നുണ്ടെങ്കിൽ ഒരു virtualized list ഉപയോഗിക്കുക. ലിസ്റ്റ് ആണ് ആപ്പിന്റെ പ്രധാന ഭാഗമെന്നും ഉപയോക്താക്കൾ ദീർഘനേരം സ്ക്രോൾ ചെയ്യുമെന്നും ഉണ്ടെങ്കിൽ FlashList ഉപയോഗിക്കുക.

മറന്നുപോകാൻ എളുപ്പമുള്ള ഒരു അവസാന സത്യം ഇതാണ്: ലളിതമായ വരികൾ (boring rows) വേഗത്തിൽ സ്ക്രോൾ ചെയ്യും. നിങ്ങളുടെ row കമ്പോണന്റ് എത്രത്തോളം ലളിതമാണോ, അത്രത്തോളം ലിസ്റ്റ് സുഗമമായിരിക്കും. ഓരോ വരിയിൽ നിന്നും അനാവശ്യമായ नेവിഗേഷനുകൾ (navigations), കനത്ത കണക്കുകൂട്ടലുകൾ (heavy computations), അനാവശ്യമായ ആനിമേഷനുകൾ എന്നിവ ഒഴിവാക്കുക. മാർക്കപ്പ് ലളിതമായും (flat markup), ലോജിക് കുറഞ്ഞ രീതിയിലും (thin logic), ചിത്രങ്ങൾ കൃത്യമായ അളവിലും സൂക്ഷിക്കുക. ഒരു ലിസ്റ്റിന്റെ നിലനിൽപ്പ് അത് റെൻഡർ ചെയ്യുന്ന കാര്യങ്ങളുടെ ആകെ ഭാരത്തെ ആശ്രയിച്ചിരിക്കും. ഓരോ വരിയും ഭാരം കുറഞ്ഞതാക്കുക (cheap), അപ്പോൾ ലിസ്റ്റ് മികച്ച രീതിയിൽ പ്രവർത്തിക്കും.