Animations

As someone who does work in mobile development for iOS and Android, the one thing that has really stood out to me is how accessible Apple's API for animations is. iOS uses an implicit animation API, which means that the programmer changes the properties of views and the operating system handles the interpolation, potentially with the developer defining what sort of timing function is used. What's most useful is that the property changes are just defined within a block of code, unlike the ridiculous APIs on some other platforms which have you specify layouts and property changes in XML files. This makes it incredibly easy to create animations that move views around the screen, resize them, and change properties like their color and alpha. 

While animations on iOS are quite easy to create, the API is not perfect. In the work I've been doing over the last four months I've actually run into two problems that Apple has addressed in iOS 10. The first is the issue of spring animations. The existing API for spring animations on iOS looks like the following:

// Animates with a spring effect
UIView.animate(withDuration: 1.0,
               delay: 0,
               usingSpringWithDamping: 0.8,
               initialSpringVelocity: 1.0

Now, anyone who has taken some sort of higher level math or physics course will probably notice something strange about this function. This function takes a damping value and an initial velocity for the spring. However, it also takes a duration value for the animation. This doesn't really make sense, because the duration of motion of a spring is dependent on its damping, stiffness, and mass properties. A proper spring animation API should not take a duration value; the duration should be a function of the spring properties. Because of this oddity the UIView spring animations API produces animations that have an artificial feel to them, and they rarely look like the true motion of a spring.

Interestingly enough, Apple's internal Core Animation API for spring animations works using the spring properties and doesn't take a duration. The strangeness of the UIView spring API isn't exactly unknown to its creators either:

In iOS 10 Apple has introduced a new class called UIViewPropertyAnimator. While I'm not going to go into the specifics of UIViewPropertyAnimator as they aren't directly relevant to non-developers, there are a few interesting things about it. The first is that it provides a new way of performing spring animations, and like Apple's internal API, it uses the physical properties of the spring to determine the duration of the animation. This should greatly improve how natural spring animations feel in third party applications, 

The second big issue I've run into is that there's no really good way to pause them or reverse UIView animations them. This doesn't sound like a huge issue when you consider simple animations. If you move a view 500 pixels left and you want to reverse it, then just move it 500 pixels to the right. It ends up being the same code but done in reverse. However, things get a lot more difficult when you have more complex animations, particularly in cases where you define specific keyframes for an animation. Any logic that you need to trigger after an animation also has to be reversed, and with each of these things the workload increases dramatically. My own example involves an eighty line keyframe animation to open a menu, which then had to be programmed in reverse to close the menu in the same manner. Naturally, this is also a source of bugs if something isn't done correctly in the reverse animation, and that creates an additional layer of difficulty and complexity.

With UIViewPropertyAnimator developers now have a way to control their animation as it progresses. The object has properties that specify the state of the animation, and it can be paused, reversed, and stopped at any point in the animation. This is a great improvement over the existing API, and it will allow developers to create more complex animations without having to worry about also creating the reverse logic. The API also provides a very easy way to create additive animations. For example, in the middle of an animation a developer could then add an animation that moves the views to a new position, and the API will take care of interpolating from the current state in the middle of the current animation to the new position specified in the added animation.

One last interesting point about UIViewPropertyAnimator is that it provides a way for developers to create and use their own timing functions. The timing function specifies how the state changes progress during the duration of the animation. For example, you could have an animation where a view moves a great distance during the start, but then slows down and takes much longer to reach its final position. Previously it was not really possible to do this, except with complicated timing work involving keyframes or chaining animations. While I doubt many developers will make use of this, it's a very helpful API for the cases where a developer wants to have control over the animation interpolation to give it a very unique look and feel.

Web Performance

With every release of iOS Apple makes performance improvements to the platform's underlying technologies. One of the areas where performance is often improved is Nitro, which is Apple's JavaScript engine. I always like to take a quick look at JavaScript performance on a newer and an older iOS device when Apple updates to a new major version, so I've run our standard smartphone review web benchmarks on the iPhone 5s and iPhone 6s running both iOS 9.3.5 and iOS 10 to see if there are any significant improvements.

  iPhone 5s iPhone 6s
Kraken (time in ms) iOS 9.3.5: 3372
IOS 10: 2956
iOS 9.3.5: 1706
IOS 10: 1504
WebXPRT 2015 (score) iOS 9.3.5: 115
IOS 10: 117
iOS 9.3.5: 207
IOS 10: 203
Jetstream (score) iOS 9.3.5: 57
IOS 10: 54
iOS 9.3.5: 119
IOS 10: 124

Overall there isn't much of an uplift in JavaScript performance going from iOS 9.3.5 to iOS 10. Kraken seems to show a small gain, but in WebXPRT and Jetstream the scores flip between favoring iOS 9 and iOS 10 depending on device, and the gaps are so small that they can be attributed to testing variance. Given that Apple has made some very big leaps in JavaScript performance during the last couple of years it's not really a surprise that the pace has slowed down.

Scrolling Performance

Something iOS has typically been known for is smooth scrolling performance. Apple's own standard is that views should animate at 60fps, which makes sense given the fact that iOS devices all use 60hz displays. There was a time where you really could expect near-constant 60fps animations throughout the system, barring really poorly designed applications. However, in recent years with increasing resolutions, greater pressure on the hardware, and more advanced visual effects, the smoothness of iOS has definitely degraded. Much of this has to do with the greater complexity of modern UIs, particularly ones that make heavy use of translucent views with blur.

In iOS 10 Apple has recognized that problems in their own APIs have played a part in dropping scrolling performance on iOS. This again goes back to the fact that views have become more complex on iOS in recent years. In the past, Apple's TableView and CollectionView APIs have prepared cells for rendering right before they are about to be displayed on the screen, and are removed right when they exit the screen. This doesn't pose a problem for something basic like a table cell with a couple of labels, but with complicated cells that use translucency, load high res images, and even have animated subviews, this method of rendering simply doesn't cut it. You can even have cases with CollectionViews like the iOS Photos app where you have to bring on many cells at the same time, all of which need to be set up individually. It's important to remember that there's only a ~16ms interval between frames, and the work to set up the UI for the next frame has to be completed in an even smaller period of time than that to manage a constant frame rate of 60fps.

To improving scroll performance Apple has changed the cell lifecycle in CollectionView and TableView APIs. As I mentioned before, the previous API essentially did everything relating to cell creation right before it was to be displayed on the screen, and cell removal right after it exited the screen. This caused two key issues. The first is that in the case of a CollectionView with many columns, every cell is rendered at once at that moment. This is a big cause of frame drops, as the hardware simply cannot render all the cells in time for the next frame. The second issue was the situation where a cell would exit one side of the screen and quickly be brought back on. This situation occurs frequently when a user accidentally scrolls past the item they were looking for in a list. In this case, the cell would have to be recreated from scratch despite having been on the screen only a moment before.

The iOS 10 APIs now spread out the work done during the lifecycle of a cell. Cells are now setup well before they need to be rendered, and the display process is spread out so a row of many cells doesn't need to be rendered at the exact same time right before they need to be shown on the screen. Cells are also kept for longer after they exit the screen, which means if the user quickly scrolls back the cell display method can simply be called again rather than having to get a new cell from the reuse queue, set it up, and draw it.

It honestly surprises me that Apple didn't make these changes sooner, because the impact on performance is dramatic. The iPhone 5s on iOS 10 has better scrolling performance than it ever has in the previous three years. This sort of thing is difficult to profile well even with XCode and Instruments, but I think it'll be immediately obvious to users that performance is improved, especially for users of older iOS devices that haven't had such a good time after being updated to iOS 8 and iOS 9.

Swift Playgrounds: Looking to the Future Final Words
Comments Locked

113 Comments

View All Comments

  • damianrobertjones - Wednesday, September 14, 2016 - link

    Cash. Money. The usual. Bills have to be paid. The days of complete, free, impartial journalism died years back. The Verge and Engadget being the worst of the many. I see a web page design in the future for Anandtech.
  • robinthakur - Friday, September 23, 2016 - link

    Because people click on the articles more, would be my guess? I scanned the whole site for the iPhone 7 review and clicked on another apple article on iOS10 when I couldn't find it. This is actually a good technical review by somebody who clearly knows the OS inside out, so I've got no problem with it.
  • ABR - Wednesday, September 14, 2016 - link

    The overall UI smoothness improvement is really noticeable on an iPad Air 2. It's a really shame this is the release they decided to cut support for iPad 2 and that era devices, because those are just the ones that became truly unusable starting with iOS 8. Thinking charitably, it could be that dropping the support is one of the things that helped improve the performance, or, more cynically, maybe it's just part of their plan to continue encouraging purchase of new devices.
  • tipoo - Wednesday, September 14, 2016 - link

    Yeah, even if they dropped all the new features, the performance improvements would have been huge for A5 devices. In fact I wouldn't mind if they stripped the OS as much as they could to get A5 smooth again, but of course they're not going to do such an undertaking for the old chip.
  • tipoo - Wednesday, September 14, 2016 - link

    The worst thing about it is no OS security updates for older OSs, so you're forced to either go insecure, or get a dog slow OS on your formerly decent hardware. There's also no easy downgrade mechanism.
  • m16 - Wednesday, September 14, 2016 - link

    I'm very impressed with the update, really snappy. I'm even more impressed that all my apps work, but I don't have any fancy apps outside of some photography apps that control the aperture.

    I wish they'd brought back notification center social media posting. I mean, OS X Capitan has it!!! It had it back on the iOS 7 days.

    Anyone else thinking this should be back should go to apple's feedback page on either iOS or the iPhone/iPad and request the feature back.
  • yhselp - Wednesday, September 14, 2016 - link

    I'm very glad Apple have seemingly fixed performance and UI issues for the 5s compared to iOS 9.

    After upgrading yesterday I was pleasantly surprised. At least for now. I hope I don't jinx it. The 5s is now noticeably smoother; navigating menus, multitasking, and general use overall is now more in line with how fast it used to be on iOS 8. In-app performance seems to have improved as well; I specifically tested an app that used to work great on iOS 8, then ran poorly on iOS 9, and now seems to work great again on iOS 10. Furthermore, the UI itself is now better optimized for a 4-inch display - not only is it better than iOS 9, but there are also improvement over how it used to be on iOS 8.

    So far so good then. Haven't encountered any major hitches, and battery life seems to be holding up. Still, some things are sometimes actually slower than how I remember them from iOS 8, but the opposite is true as well - sometimes the 5s feels faster than ever. Overall, so far, I'd say the smoothness is on par with iOS 8.

    One thing that still baffles me is the Music app. I still pretty much hate it, although it's an improvement over iOS 9 both in terms of usability and 4-inch friendliness. Maybe it's better suited to how most people seem to consume music nowadays - internet music, music services, etc. I can't believe that so few people listen to music in a more traditional way that it's worth ignoring them. Why is it so hard for Apple to at least offer more control over how the music library is sorted? I want to be able to browse by artist, tap on a band, and see all their songs I have on my device in one place with little bars above every group indicating which albums they're from; just as it used to be, and not how it is now. On top of that, the Music app is now less sexy than ever, there's no cover flow at all (at least, I can't seem to find it), and the UI can still get unnecessarily cluttered on a 4-inch display. For me, the best Music app would be a hybrid of how it used to look on iPhone 5 running iOS 6 with some of the improvements from iOS 7 and 8.
  • yhselp - Wednesday, September 14, 2016 - link

    I can't help but think - thank God they made the SE, because without it iOS 10 might not have been as 4-inch friendly as it is.

    I'd be very much interested to hear any impressions on how iOS 10 works on iPhone 5/5c.
  • yhselp - Wednesday, September 14, 2016 - link

    Update: One important thing that has seen a downgrade, in my opinion, is notification banners. When you're doing something, and someone sends you a message the banner that appears on the top of the screen is bigger, gets in the way, and it's harder to reply quickly without opening the Messages app - pulling down the banner is harder, and once done it takes up to whole screen.

    For me, that is a major downgrade as it makes banner more obtrusive on a 4" device, and make it hard to reply to messages quickly. I understand it might have been made in a bid to improve visibility on 4" devices, but I don't think it was the right call.

    This might prove to be iOS 10's Achilles' heel on 4" devices. I would very much like to see it fixed.
  • mdriftmeyer - Wednesday, September 14, 2016 - link

    You'd be wrong. Works great on my iPhone 5s. Notifications now are more easily flipped through and understood at quick glances.

Log in

Don't have an account? Sign up now