I currently made an app which contains a tableview with 1000 cells. Each cell contains on the left side a UIImageview in the contentview. All the image files are currently stored in the NSBundle. Unfortunately the app is to big in size to download over 3g (one of the regelations from Apple) and I will need to cache these images.
I currently am downloading and saving each image once the cell is on the view (dereusable cell) but this slows down the scrolling drastically. Is their a way to keep the scrolling fast but once the user stops at a certain position it caches those files? I tried an NSOperationQueue but this did'nt work out for me.
Some hints in the right direction would be appreciated!
Thanks!
Well if you are the same downloading and displaying a table view, it's normal that you have a performance drop in the fps you get from your tableview as the cpu is using some of it's threads to download the data...
The only way you could gain in performance is if you speed up the drawing of your tableview cells by using core graphics to draw directly into the cell (as Loren Brichter demonstrated with the tweetie app).
Related
I have few questions regarding loading images to tableviews;
I am using ASIHTTPRequest.
1.) I have a tableview, and i need to load images to it. I have images which has the size of 100KB, 180KB, 450KB, and 2MB. I know that these images are too big, but i have no control over this. I am forced to load these images in the tableview. When i do this, it slows the scrolling, and slows to switch from views to views. So how can i prevent this ? any solution?
2.) Presently i am using SDWebImage, i am not satisfied with this library because it slows the scrolling etc (even when i use images which is less than 110kb) I need a library that can perform faster actions ?
You may have to downsample the image to the image view size in the background before displaying it. It will definitely cost you a lot of CPU cycles upfront, but will speed up scrolling. I recommend the ImageIO framework because it has no issues running in non-main threads.
I don't think it's SDWebImage that is slowing your scrolling down. SDWebImage downloads the image in a separate thread, the only thing it really does on the main thread is place the image in the UIImageView and this has to be done on the main thread. I use SDWebImage in a few different UITableViewCells and I have been able to achieve smooth scrolling.
2mb is really large -- you are not going to be able to load that image into a UITableViewCell without seeing some jerk. The fact is that it takes some time for the UIImageView to render that image.
If I were you I would run your app through the Time Profiler instrument and see if you can figure out which lines of code are taking the longest to run in your UITableView or your UITableViewCells.
I have a scrolling grid of photos that looks and functions pretty much exactly like the photo picker on the iPhone. It is constructed from a UITableView that uses a custom UITableViewCell which displays a row of photos (very similar to how Three20 implements it).
It works great except that scrolling performance is poor. I'm already following most of the best practices for fast UITableView scrolling (à la Tweetie).
The images are all bundled with the app. I load them on the UI thread, on demand. I use UIImage's imageNamed: so that the images will be cached after they're first loaded. Once I've scrolled through the table view once, it scrolls very smoothly.
The problem is, the first time scrolling through the table view, scrolling is jittery. I've profiled the app and found that the majority of the time is spent loading the images from the file system. They are JPEG images, already sized correctly (small). I tried using PNG images instead, but performance doesn't improve very much.
The iPhone photo picker exhibits much better loading performance. I'm wondering if combining all the photos into a single image, which I load once and then split into smaller images would be faster. It certainly works in games, but I know that's really a totally different story. Has anyone had experience doing that?
Any other ideas for how I can improve performance?
Incidentally, I'm having a similar, albeit less, performance problem for another UITableView that just uses standard UITableViewCells with one image assigned to the imageView per row.
One thing to try could be pre-caching all the images when the view loads. Beyond that, perhaps loading the images in the background (even though it's loading from the filesystem and not the web). I haven't tried this myself, but perhaps you could use something like https://github.com/rs/SDWebImage and have the URLs point to the filesystem. Users might see some placeholder images at first, but then the UI wouldn't stutter while images are loading.
Setting the PagingEnabled property to off improves the scrolling performance.
I had a similar issue using a UITableView to display information parsed from an RSS Feed. I ran into scrolling performance issues when there was a significant amount of data. Though I'm still working on it I suspend the parsing when the table is being scrolled. It resumes when scrolling stops. I am not at my computer, but I believe I used tableViewDidScroll and tableViewDidEndDecelerating. You can check these tableview delegates. In any case it works very well, I just need a more elegant way to pause my parsing.
Fantastic. That does work like a charm! So efficiently I ended up using insertRowAtIndexPath rather that reloading the table. Now it behaves the way it
Thanks so much!
Joe
I'm having a problem when scrolling down and up a tableView on iPhone it gets kind of stuck while loading the images i need a method to preload the images so the scroll can be fluid or load the images 'till the scroll event stops...
any help on this?
I found this article very helpful. It provides a very detailed example for lazy loading of images in the main runloop.
Lazy Table Images Sample Code included in iPhone Developer Resources. Check out Photo Locations Sample Code as well. It uses Core Data and "lazy loading" techniques if your image files are stored on the device.
Well, generally speaking, preloading images for table view is a bad idea. Think of a following situation: you have 100 cells, each containing one image. That means you'll have to load 100 images before showing the table, which will have a serious impact on avaliable memory.
The "loading effect" you're talking about can be caused by two things:
a) as you have said, the problem with loading images. If so, do it in another thread, and pass the image to main thread when it loads
b) You're using images that are bigger or smaller than the given size. This will result in resizing the image when it appears on screen, causing the ugly stop-effect - the solution is to draw images in size which is exactly the same as their size.
Chope this was helpful, Paul
Not sure about images, but with text I have downloaded JSON files when the view loads, parsed into an array and then loaded the tableview with that array.
i am developing a app which contains feature like default photo browser in iphone. I done some what similar to that. but after loading some(near about 10-15) images from remote server,i am receiving memory warning.My requirement is loading image one by one. For this, on scroll view i am putting an images and increasing the contentSize of scroll view. it will work fine. but due to memory warning app quite.
Guys, any have any idea to approach for this feature which work similar to photo app without problem?
thanks in advance .
You're running out of memory because you're keeping the data for 10 or more images in memory at one time. You need to have more logic in your code that not only preloads and increases the scroll view's content size, but also removes UIImageViews from the scrollview (and thus from memory) as the user scrolls to newer stuff. (You can also save "evicted" images to the cache area on disk so if the users scrolls back you don't have to go to the server again.)
If you use a UITableView, it will request the images only when needed, and will automatically purge off-screen cells to save memory. It may not fit into the aesthetic for your application, though.
I have around 20 tableview cells that each contain a number (2-5) thumbnail sized pictures (they are VERY small Facebook profile pictures, ex. http://profile.ak.fbcdn.net/hprofile-ak-sf2p/hs254.snc3/23133_201668_2989_q.jpg). Each picture is an UIImageView added to the cell's contentview.
Scrolling performance is poor, and measuring the draw time I've found the UIImage rendering is the bottleneck.
I've researched/thought of some solutions but as I am new to iphone development I am not sure which strategy to pursue:
preload all the images and retrieve
them from disk instead of URL when
drawing cells (I'm not sure if cell
drawing will still be slow, so I want
to hold off on the time investment
here)
Have the cells display a placeholder
image from disk, while the picture is
asynchronously loaded (this seems to
be the best solution, but I'm
currently not sure exactly how to do
best do this)
There's the fast drawing
recommendation from Tweetie, but I
don't know that will have much affect
if it turns out my overhead is in network loading
(http://blog.atebits.com/2008/12/fast-scrolling-in-tweetie-with-uitableview/)
Thoughts/implementation advice? Thanks!
Suggest you do a search in the XCode help docs for LazyTableImages. It's a sample app provided by Apple that asynchronously loads images into a table cell. It should be a good starting point.
You'll probably want to add a local cache to save the images so you don't have to keep downloading them each time, and a way to prune out old images out of the cache.