In this book's Git repository, you'll find a project named Instrumental. The app is still in its early stages of development, so there is plenty of work that needs to be done to improve the app. Some implementations are not ideal and the app contains some placeholders that might not make a lot of sense.
Even though the app isn't finished and the code isn't perfect, the app should be working fine, especially in the performance department. If you launch the app and click around, you'll notice that the app isn't working fine. It's actually really slow! Let's see if we can find the issue that's making the app slow.
If you dig through the source code, you'll immediately see that the app has three main screens: a table view, a collection view, and a detail view. The table view displays a list of 50 items, each of which links to an infinitely scrolling collection view with a custom layout. The layout for the collectionview is custom because we needed to have exactly one pixel of spacing between items, and this layout can be achieved with a reusable layout that can be used in other collections or apps. Finally, the detail view just shows an image and a label on top of the image.
Based on knowledge from earlier chapters, you should know that a simple app such as this should be able to run smoothly on virtually any iOS device. Collection views and table views are optimized to display huge datasets, so an endless scrolling collection view that keeps adding fifty new rows whenever we almost reach the end of the list should not be too much of a problem. In other words, this app should be able to run at 60 frames per second with no trouble at all.
However, if you start scrolling through the collection view and move back and forth between screens and then scroll more and more, you'll find that some collections will stop scrolling smoothly. They will randomly freeze for a little while and then continue scrolling. And the more we scroll through the collections, the bigger this issue seems to become.
When we look at the memory usage in Xcode's Debug navigator (the sixth icon in the left sidebar), we can tell that something is wrong because memory usage just keeps on going up when we navigate through screens. This in itself is nothing to worry about, temporary memory spikes are normal. When the used memory never gets freed even though you might have expected it to, that's when you should start worrying. Take a look at the following graph:
Whenever you debug performance issues or if you're trying to measure performance, make sure to measure on a real device. If you measure using the simulator, your app might run fine even though it might not run fine on a device. This is due to the way the simulator works. It mimics an iOS device, but it's backed up by all the power your Mac has to offer. So, the processor and available memory are those of your Mac, resulting in performance that's often much better than it would be on a device.
For now, we'll make a mental note of our app's rising memory usage and shift our attention towards the Instruments app. To profile your app with Instruments, you can either select Product | Profile from the toolbar or hit Cmd + I on your keyboard. Xcode will then build your project and launch Instruments so you can select a profiling template:
There are many available templates and most of them are pretty specific. For instance, the Network template will measure network usage. This isn't very relevant if you're not trying to debug networking issues. There are also templates available to profile animations, database operations, layout, Metal graphics performance, and more.
If you select a blank template, you're presented with the Instruments interface. The interface features a record button that we can use to start or stop profiling for our app. If you look further to the right side of the top toolbar, there's a plus icon. You can use this icon to add profiling for certain metrics yourself. You could use this to create a profiling suite that fits your needs without having to switch between the default templates all of the time. The center of the Instruments interface is the timeline. This is where graphs are drawn, depicting the measurements that were made for your app. The bottom section of the screen shows detail about the currently selected metric, as we'll see soon:
Now that you know a little bit about how the Instruments app is laid out, let's make an attempt at profiling the Instrumental app. The biggest issue in the app is the choppy scrolling. We know that the app has a memory issue, but choppy scrolling occurs even if the app's memory usage is low. This should be a flag that a memory leak probably isn't the problem that is causing the collection views to scroll badly. Something in the code is likely to be slow and Instruments can help us figure out which parts of the app's code are taking a long time to complete.