Optimizing Lists (RecyclerView/UITableView/ListView) in Mobile App

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Optimizing Lists (RecyclerView/UITableView/ListView) in Mobile App
Medium
~2-3 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Optimizing Mobile App Lists (RecyclerView/UITableView/ListView)

UITableView jerks on fast scroll — and almost always the cause isn't "slow hardware" but synchronous JPEG decoding on main thread in cellForRowAt. Prefetch fires too late, cell already requested, and while image decodes — frame skips. On iPhone SE 2nd gen with modest memory this reproduces stably where on Pro isn't noticed at all.

Real Stutter Causes

Most common Android story: RecyclerView with LinearLayoutManager and hundreds of elements where onBindViewHolder executes Picasso.get().load(url).into(imageView) without explicit placeholder and without canceling previous request via tag. On fast scroll requests accumulate, old ones aren't canceled, UI thread periodically blocks from callbacks. Switch to Glide with RequestManager bound to lifecycle and preload() in onScrollStateChanged solves it without logic changes.

Analogous iOS situation: SDWebImage without SDWebImageAvoidAutoSetImage applies image on main thread immediately after loading regardless of visibility. Add sd_setImageWithURL:placeholderImage:options:SDWebImageAvoidAutoSetImage and apply in completion only if indexPath == self.tableView.indexPathForCell(cell) — stuttering disappears.

Second most common — heavy cell height calculations. UITableView.automaticDimension convenient, but with complex layout with multiple UILabel runs full systemLayoutSizeFitting on each visible cell. Height cache via [IndexPath: CGFloat] and recalc only on data change solves problem.

On Jetpack Compose LazyColumn without key {} can't correctly reuse composable when data changes — submitList with changed elements rerenders all visible cells instead of changed ones.

What We Do Specifically

Android RecyclerView:

  • setHasFixedSize(true) if RecyclerView size doesn't change on data update
  • setItemViewCacheSize(20) to increase offscreen cell cache
  • RecycledViewPool.setMaxRecycledViews(type, count) with multiple RecyclerView of same cell type — pool sharing
  • AsyncListDiffer or ListAdapter with DiffUtil.ItemCallback — diff on background thread mandatory for any dynamic list
  • Prefetch via LinearLayoutManager.setInitialPrefetchItemCount() for nested horizontal lists

iOS UITableView / UICollectionView:

  • prefetchDataSource — decode and cache data before cellForRowAt
  • estimatedRowHeight with real value (not 44 for 120-height cells) — wrong estimatedRowHeight causes scroll jumps
  • prepareForReuse() — must cancel all async operations: imageLoadTask?.cancel()
  • Offscreen rendering cells via UIGraphicsImageRenderer for static content (avatars, overlaid icons)

Flutter LazyColumn (ListView.builder):

  • itemExtent — if all items same height, specifying fixed itemExtent removes need to measure each
  • cacheExtent — increase to 500–1000 pixels for preloading outside viewport
  • AutomaticKeepAliveClientMixin — preserves cell state when scrolling back

Case with Nested Lists

Horizontal RecyclerView inside vertical — common Netflix-like interface pattern. Typical mistake: each horizontal RecyclerView creates own RecycledViewPool. On vertical scroll, horizontal ones recycle with children, and on returning cell's state (scroll position) is lost.

Solution: extract RecycledViewPool at activity level and pass to each horizontal RecyclerView via setRecycledViewPool(). Save LinearLayoutManager.onSaveInstanceState() in ViewModel by position key. Result — smooth scroll and position preservation on vertical list scroll.

Timelines

Audit and optimization of one problem list — 2–4 days. Systematic work on all lists in app — 1–2 weeks.