0

I have a UIViewController that controls a simple page with one UITableView in my app. The table has 12 rows. I just added an image (40px by 40px) to each row with the following simple line of code in tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath):

cell.imageView?.image = UIImage(named: "<image_name_for_row>")

After doing this, the time it takes for the page to display increased by about 3x. This is the only change I made to the code. After displaying the page for the first time, if I display the same instance of the view controller again, it displays almost instantly; essentially as fast as it used to before I added the images. So, I can only assume that the images get cached somewhere after the page displays for the first time... is there a way to cache the images when the app loads to avoid the very noticeable delay the first time I show the view?

I tried putting the following code in application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?):

menuViewController.view.setNeedsLayout()

But, this didn't decrease the page load time. This also failed to decrease the load time:

_ = UIImage(named: "menu_row_1")
...
_ = UIImage(named: "menu_row_12")

Any suggestions?

kmell96
  • 1,365
  • 1
  • 15
  • 39
  • 1
    The usual approach is to load the images in a background thread. There are many questions about this, such as https://stackoverflow.com/questions/7502073/loading-images-from-a-background-thread-using-blocks – Gary Makin Apr 04 '18 at 04:40
  • Are you downloading images or fetching images from assets? – Sagar Thummar Apr 04 '18 at 04:40
  • I'm just fetching images from assets which is why it's so strange that it seems to be causing a delay. I'll take a look at loading on a background thread but I'm not sure how I'd load them other than just instantiating a bunch of UIImages, which didn't work when I put it in the AppDelegate. – kmell96 Apr 04 '18 at 04:43
  • You are taking static images. Is you number of rows fixed? – Ankit Jayaswal Apr 04 '18 at 05:19
  • Yes, it's fixed at 12. – kmell96 Apr 04 '18 at 05:23

1 Answers1

2

There is a known performance impact while using [init(named:)] method. Try using this instead. Just pass nil for bundle and traitCollection args:

init(named:in:compatibleWith:)
Puneet Sharma
  • 9,369
  • 1
  • 27
  • 33
  • I'll give that a try, but it seems like the bug you linked to is fixed as of iOS 9.1 and I'm experiencing this on iOS 11. – kmell96 Apr 04 '18 at 05:08
  • @kmell96: The UIImage imageNamed is still slow for tableviews and collectionviews, for the first time. This method then cache the image, which makes subsequent load of image of same name anywhere in app faster. Somehow, using named:in:compatibleWith: is a little faster. Also, are you using autolayout for the cell row height? – Puneet Sharma Apr 04 '18 at 05:12
  • Yep, you were right... I instantiated a bunch of static variables using `init(named:in:compatibleWith:)` and that brought the load time down to virtually instant. Thanks! – kmell96 Apr 04 '18 at 05:26