Tricks for improving iPhone UITableView scrolling performance?
Asked Answered
B

5

89

I have a uitableview that loads fairly large images in each cell and the cell heights vary depending on the size of the image. Scrolling performance is decent, but can sometimes be jerky.

I found these tips I found on the FieryRobot blog:

glassy-scrolling-with-uitableview

more-glassy-scrolling-with-uitableview

Does anyone have any tips for improving uitableview scrolling performance?

Bags answered 29/8, 2009 at 21:51 Comment(1)
If you need to cache the cell heights (which can be expensive to calculate and are also used frequently), I have given an example. Only use this if it is suitable in your application. #1371723Poucher
H
157
  1. Cache the height of the rows (the table view can request this frequently)
  2. Create a least-recently-used cache for the images used in the table (and invalidate all the inactive entries when you receive a memory warning)
  3. Draw everything in the UITableViewCell's drawRect: if possible avoid subviews at all costs (or if you require the standard accessibility functionality, the content view's drawRect:)
  4. Make your UITableViewCell's layer opaque (same goes for the content view if you have one)
  5. Use the reusableCellIdentifier functionality as recommended by the UITableView examples/documentation
  6. Avoid gradients/complicated graphical effects that aren't pre-baked into UIImages
Hieratic answered 29/8, 2009 at 22:57 Comment(6)
Additionally, downloaded images should be scaled down to the imageView's size before displaying on the cell!Retroflexion
I would like to add to this answer one my experiences from the last few years - having transparent cells is probably never the cause of bad scrolling performance. We have an app with VERY complicated cells (20+ subviews) and it's all transparent to show the background. With proper optimizations the transparency makes no difference even on a 3GS. Actually the thing that slowed stuff down the most was nib loading before there were enough cells to dequeue from the table view. If using subviews, just make sure to have efficient hierarchies and you don't need to use drawRect.Sixtasixteen
@Accatyyc, it seems that I have the same problem. There's a small lag when there's not enough cells to dequeue, when 3-4 cells are dequeued then the scrolling is smooth. Is there any way to preload cells so there are cells to dequeue and not to load NIB files when scrolling?Lazes
@Lazes Sure there is. You need to use the old way of dequeuing cells (don't register classes/nibs, but create them if dequeueCellWithIdentifier: returns nil). This way you can create a set of cells before your table view even exists, for example creating 20 of them before. Then instead of creating new ones in cellForRowAtIndexPath:, you pull them from your own cache first, until it is empty.Sixtasixteen
I am using UICollectionView and facing same issue. In my custom cell nib file. I am using several subviews including UIwebView and UIImageView inside vertical UIstackView. when I scroll my list reused cells take significant time to readjust their size and scrolling looks very jerky.Kapor
I am also facing the same issue using UITableView and calculating height for each cell depends on the number of subviews need to show. every cell having multi-line text labels, UIButtons, and a collection view for Images and Video and could be a MapView as well. Scrolling is not jerky but some times its freeze while adding more rows.Constabulary
V
40
  1. If you are subclassing UITableViewCell, don't use a Nib, write it in code instead. It's much faster than loading Nib files.
  2. If you're using images, make sure you're caching them so you don't have to load from file more than once for each (if you have the memory -- you'd be surprised how much space images take up).
  3. Make as many elements opaque as possible. Similarly, try not and use images with transparency.
Valuable answered 29/8, 2009 at 22:11 Comment(5)
dont worry... that were trolls. great answer!Gast
The down votes were probably because "avoid nibs" is bad advice for improving performance. If you're reusing cells, the cells aren't reconstructed from nibs at all when scrolling.Jasminejason
Nibs are equivalent in speed, or a little faster based on Cocoa with Love research. cocoawithlove.com/2010/03/…Kabuki
@Steven Fisher using Nib may be slower when table allocs and deallocs cells, for example - during fast scrolling.Pharyngitis
Using NIBs may be slower when the cell is being constructed. If you're using cell recycling, there are only enough cells allocated to fill the screen; say, maybe 10 at most. When you're scrolling, cells are not created. They're just reused, not deallocated and reallocated. And, of course, there's no cost to dealloc. So no, this isn't correct.Jasminejason
B
34

The developer behind Tweetie has written extensively about this and has some code that demonstrates how it was done for that app. Basically, he/she advocates one custom view per table cell, and drawing it manually (rather than subviewing with Interface Builder, among other options).

fast-scrolling-in-tweetie-with-uitableview

Also, Apple has updated its own sample code for TableView in its TableViewSuite tutorials (maybe in response to this?)

TableViewSuite

Burtburta answered 26/10, 2009 at 3:3 Comment(4)
This is an awesome solution. I'm just curious how would I add a UIButton into the cellView? Is it being drawn in the drawRect method?Ambrosane
@beno, your link seem broken (the first one) any chance to put our hands on the original article ?Drop
The original article can be read here: web.archive.org/web/20100922230053/http://blog.atebits.com/2008/…Rotorua
added link to web archive as original version doesn't existUrbanna
G
1

#1 performance killer for UITableView scrolling is drawing shadows on any cell view layer, so if scrolling performance matters then don't do shadows unless basically it doesn't slow down your main thread.

thought this had to be said since none of the accepted answers made mention of shadows and layers. :+)

Genni answered 27/6, 2014 at 6:9 Comment(1)
if the problems are the shadows add this two lines of code and all works perfectly self.layer.shouldRasterize = YES; self.layer.rasterizationScale = UIScreen.mainScreen.scale;Perithecium
C
0

Any problem with UITableView scrolling performance can be solved using techniques already described in other answers. However many a times sluggish performance is caused by something inherently erroneous, or repetitive.

The fact that UITableView reuses the cells, and the fact that each cell may need its own image - together makes the solution bit complex. From how it's being solved the general way, here I summarize things that should be taken care of:

  1. Load data into data source - from REST / database. This step should be done on background, eventually using dispatch_async along with GCD queue.
  2. Create and initialize relevant data model objects and putting them inside an array
  3. [tableView reloaddata]
  4. Inside cellForRowAtIndexPath, include code that will set data (text) from correct data model object of the array.
  5. Now images maybe in the form of URL too, so this step might be little quirky because of cell reuse done by table view. The heart of the fact is to load once again image from device cache / URL using async queue, then set it to correct cell.image (whatever is your cell image property).

To avoid problems, refer to this tutorial about lazy loading of images inside table view.

Chairman answered 16/1, 2016 at 13:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.