We've already established how similar UITableView is to UICollectionView in terms of how you implement each component. In terms of performance, the similarities just don't stop. UICollectionView is optimized to display cells on screen as fast as possible with as little memory usage as possible, just like UITableView is. For UICollectionView, these optimizations are even more important than they are for UITableView because UICollectionView typically displays a lot more cells at the same time than UITableView does.
The fact that UICollectionView can show a lot of cells at once makes it a little bit harder to manage its performance behind the scenes. Before iOS 10 came out, cell reuse was managed as depicted in the next screenshot. All of the cells on a single row are requested right before they need to be displayed. Because we're not scrolling one cell into view but multiple cells, the collection view must obtain multiple cells in the same time frame that a table view requests a single cell.
If you have a complex layout in your cells or if you have a somewhat slow operation in one of your cells, a collection view can quickly start to drop frames. The result of this is choppy scrolling in your UICollectionView, which is something you should avoid at all costs:

When you're aiming for a 60fps scrolling, you only get about 16 milliseconds to perform the calculations you need for the layout before the system has to render a new frame. So, assuming that the UICollectionView works just like UITableView and that it requests cells just in time, you are calculating the layout for not just one cell in 16 milliseconds, but potentially you're setting up five cells or maybe even more. This is a significant increase in the calculations that need to be performed, and it's easy to miss that 16-millisecond window. Also, once this expensive operation is finally completed, there is a short period of time with barely any calculations going on. The following diagram displays this uneven distribution of the work that's required with the pre-iOS-10 way of requesting cells:

You can see the peaks and drops in the time that's spent for each frame. Ever since iOS 10, the process of requesting cells has become a lot smarter. Cells aren't requested just in time, but they are requested in a more predictive manner. While a user is scrolling in a certain direction, the UICollectionView will start asking for cells that aren't just on the next row but also for cells that are one or two rows down or up. It won't request all of them at once but it will request them in small batches. The next figure shows how this looks compared to the old visualization:

This results in a much more evenly distributed workload for the UICollectionView, which means better scrolling performance for your users. The following graph visualizes the new iOS 10 style. You can see that there aren't peaks in the 16ms+ range anymore. This is an awesome improvement for performance that you get entirely for free:

The last performance optimization you should know about is prefetching. This technique is present in UITableView as well, and it helps the HelloContacts collection view with decoding images, just like it did for the original table. With the knowledge you gained from the previous chapter, you should be able to implement this on your own. If you want to see the implementation for the collection view, you can have a look at this book's code bundle.
Cell prefetching in UICollectionView will benefit your application a lot more than it did for UITableView. This is mainly because the UITableView won't prefetch as many cells at once as the UICollectionView has owing to the amount of cells that are displayed at any given time. Typically, a UICollectionView displays more cells at a given time so prefetching is more beneficial.