It’s not reducing the device CPU cost to zero. It’s moving it to a different process that isn’t captured in the profile. Big difference.
Not blocking the main thread is a clear win though. I’m mildly surprised the work isn’t done in an in-process background thread. But I don’t know that type of detail for iOS.
"This system framework renders animations out-of-process with GPU hardware acceleration. Animation playback is managed by a separate system process called the “render server”. "
This was actually a really cool trick that was in-place from day 1 and the main reason iOS animations were smooth on fairly anaemic hardware. And smoother than Android, even when the Android system had beefier hardware and a faster graphics stack.
This blog post is about enabling Lottie to use that path.
>On iOS, the most performant and power-efficient way to play animations is by using Core Animation. *This system framework renders animations out-of-process with GPU hardware acceleration.* Animation playback is managed by a separate system process called the “render server”. This means Core Animation-powered animations don’t contribute to the CPU utilization of the app process itself, and can continue even when its main thread is blocked or busy.
Though I expect things like complex animations are exactly sort of thing that ought to be considered an exception to that guideline. Especially ones that have limited or no interactivity, as in these examples.
It's more shocking to me that Apple hasn't explicitly shifted at least some of its UI frameworks off the main queue in the last 15 years, especially as they've added tools to make it easier. Of course, given the bugs with the parts that are off the main queue, especially in SwiftUI, perhaps that's a good thing.
(But really, moving all these things to CoreAnimation is really nice, kudos to all involved!)
Lottie – Use after effects animations in web and native apps - https://news.ycombinator.com/item?id=29634114 - Dec 2021 (111 comments)
Lottie for Android, iOS, React Native, and Web - https://news.ycombinator.com/item?id=17209832 - June 2018 (18 comments)
Introducing Lottie: Airbnb's tool for adding animations to native apps - https://news.ycombinator.com/item?id=13543927 - Feb 2017 (97 comments)
Others?
Edit: To make it clear: I'm a complete afterfx noob.
> I always wanted to use lottie, but never really dived into 2d animations.
However, as a person who worked as a motion designer for several years, I must say that creating good animations, especially for lotties limited toolset is not a technical problem, but an artistic one. Making animation feel good is hard and takes a lot of practice. Even more for character animation.
Not only did they just release a thing, that does stuff, and is progress. But they did it over the weekend between surf without breaking a sweat because they are pro. /s
Were these issues present only in the iOS version of the library? or are these issues present across android, web, and RN as well? and will these platforms also get the upgrade?
Is it part of their core value prop? Or do they ignore the advice? Or is their success causing them to waste cash on boondoggles like this? Or do these boondoggles help them attract engineering talent for less than they’d otherwise need to pay?
That's sad. That's really, really sad. I get why you would like to work on such a project, but it's got considerable value for AirBnB. Your work doesn't go to the "community", it goes to a large, unscrupulous, unethical money factory.
[0]: https://rive.app/
I guess people in this space are discovering that their old renderers simply aren't as fast as they need them to be, Lottie included.
Thanks, I hate it.
sorry but bullshit! Sure, multi-threaded rendering can give faster results but the apps AirBnB is making could have easily rendered at 60hz with single threaded software rendering in flash in 1998!
I can only guess that too much abstraction throughout the systems has turned into death by 1000 cuts and their solution, instead of getting rid of the 1000 cuts is to apply more band-aids
This isn’t a video game where they’re direct drawing to a graphics context with exclusive use of the resources. They’re also setting up native widgets in the background, coordinating data downloads etc..
Unlike a video game where you control the rendering and scheduling to a greater degree, here they’re beholden to when the OS deems it ready to redraw or scheduling of background processes that may move their task to a lower priority.
Yes you can go fast if you don’t factor in the rest of the system, but they designed Lottie to play well within a retained mode UI setup, which has inherent overhead.
I also think saying that a retained mode UI has inherent overhead is a bit odd. immediate mode UIs have to rebuild their entire draw graph on each frame! meanwhile retained mode UIs have a bunch of metadata letting them get nice optimization improvements. Translating an object means you might not even need to redraw it!
There is definitely a certain truth to the OS being able to just force you down to a lower priority, but I think we all know that iOS is pushing the top app to as high a priority as possible. Meanwhile the "inherent difficulties" with something like AirBnB (getting data over the wire) are definitely inherent but this is why we talk about placeholders and stuff like that yeah?
But if you're in the business of selling rentals it's hard to have so many engineers focused on the performance of the app (especially when you are in the act of being successful already)
What an absolutely braindead reply. A telltale sign a comment has almost no thought put into it: when you go into the user's post history and see the first page filled with comments written that very same day. Scatterbrained to the max.
Hey dude I'm gonna give you some unsolicited advice. Lay off the keyboard for a bit, would ya? Maybe go outside for a walk. You are spending way too much time writing comments on the internet. https://youtu.be/FmDFCKVnaRY?t=341
You shouldn't need multi-threading to render a few thousand objects and most UI apps of the type Lottie is being used for animate 100 or less at a time.
Note: It's good that Lottie runs faster for its users. My point is only that the entire stack is over engineered and the solutions being used are because the stack is bloated and inefficient
That's engineering at scale. It's impossible to remove more than a small fraction of those cuts within any reasonable time frame.
they’re being told when to draw (hence the immediate), so if you suddenly have computation on the same thread that’s blocking OR your thread gets deprioritized , you’ll get stutters.
Immediate mode UIs aren’t very suitable for mobile use though. They don’t have great consideration for battery efficiency, unless you introduce a retained backing of some kind. They’re also not great for accessibility, though that’s mostly just because they’re not native.
I don't know how deeply animations are tied to the OS API, though.
The most powerful AE competitor(in 2d animation) I've seen is Cavalry. It targets professional motion designers, has neat procedural animation toolset and can export to lottie.
There’s the overhead of pushing updates to the UI layer from your app code, having it trigger an update, which in turn makes it check what other things have updated and what needs to redraw. UIKit is handling all that for you, but as a result you’re not getting full control of when you’re updating. You get pacing issues, where you can’t really guarantee you’re drawing at set intervals either which can lead to pacing stutters since you’re beholden to the apps event loop.
With an immediate mode UI in a game, yes there’s more cost to set up your draws, but you have more direct control of when everything will update because you’re handling the event loop more directly.
As for other priorities, I don’t mean just app priority. I mean intra-app priority. Lottie has to mix in with user code, the app it’s within might schedule a task with a higher QoS priority. It’s not just showing a fixed animation, it’s part of the app interaction model. So it’s easy to get into a situation where the rest of the app introduces stutters inadvertently.
Using CoreAnimation lets you sort of side step that discussion.
And yes I agree games have it harder over all because they have to handle everything. That wasn’t my point really. I think though that games have it easier when it comes to frame timing as a result of being able to control the entire event loop. So it’s easier for a game to reason about and guarantee smoothness of motion than it is for a framework that has to fit into arbitrary applications.
I was very surprised that SwiftUI didn’t do this too.
2. AirBnB’s backing probably gives it more reach because it’s more likely to be maintained.
3. It’s up to the OP where they spend their time. I’m guessing they’re compensated in multiple ways for their efforts.
I’m all for calling out negative behaviour by big tech when I see it, but kneejerk “big company bad” type reactions are counter-productive.
3. The parent post said: passion project/nights+weekends. That doesn't sound like multiple way compensation.
It's not about negative behavior of big tech, but more of a "grind" mentality gone astray. I can totally understand being (somewhat) proud of a project like this: it looks friggin' good. I also expect a company to grab whatever it can; it's the way of the world, and some companies are quite immoral. But we should not be working on something of considerable value to entities with deep pockets for free, just because it hits those 2010s linked-in bingo words. That's not where your self-worth as engineers should come from.
I just wish developers would make mobile UIs consistent with the OS. The Apollo Reddit client and, surprisingly, the official GitHub app are the only third-party apps that I have that feel/look like "native" iOS apps.
When it's not over-the-top animations, giant UI elements, tutorial modals, or fullscreen pop-ups, it's small details like the (IMO ugly) custom font and the sharp-cornered buttons in the Dropbox app. At least for that particular app, I can just use the built-in Files app, but no such luck for other apps.
Tasteful uses of libraries like this can add a fair bit of “fun” and friendliness to an app, and younger generations do dig them from my user testing at least. Depends on the app and use case I think.
Immediate mode guis do cache stuff, at least Dear ImGUI, one of the most popular Immediate mode guis caches. Further, at least in my mobile usage almost everything I do with my phone re-draws the entire screen. The #1 thing to do is scroll through content. There's very few apps I run where only some tiny thing is getting updated. Maybe my music player.
I don't think it's settled that retained more GUIs are a battery win.
Maybe there are fewer purely immediate mode UI libraries today, which muddies the discussion though.
On the note of the apps used, I would say the vast majority of apps I run only have a few elements updating at any given time. Most of them are based on scrolling for navigation but that’s a small part of what I do. Photo viewing and editing, viewing sites, replying to messages or mail, listening to music. Very little is a full screen update, and if it is, UIKit and SwiftUI are caching large amounts of the view objects to keep things snappy and only doing it when they receive input that requires it. Can immediate GUIs do that too? Of course, but again you enter the domain of retention.
You say this with zero proof. Checking 100s of widgets to see if they overlap, updating their damage boxes, drawing the parts of the ones that got overlapped, computing clip bounds for each one, switching graphics contexts, to do all that adds up to "killing the battery"
Retained APIs are like using a binary tree where an Immediate mode GUI is like using a vector. CS principles say the tree should be faster as insert and delete are in O(1) but in reality, cache misses and similar things kill all the perf you supposedly gained by over engineering the solution.
The same is often true of retained mode GUIs vs immediate, especially with all the transparency effects in modern UIs. Computing the minimal amount of parts can requires a ton more CPU than just drawing.
As far as caching = retained, no. The difference between an Immediate Mode and a retained mode API is if you, the user, have to create and maintain a tree of retained API widgets. No one is going to implement an immediate mode API and try to have a text widget that word wraps and expect it to have to compute all the word wrapping every frame.
Keeping the GPU context when switching mobile apps was always a challenge, though, and often the animation state would need to be rebuilt if the context was dropped. I'd assume that's still an issue something like Lottie needs to handle, whether it does so under the hood or not...
By the way, you can “schedule” animations from any thread if you use CoreAnimation directly. CALayers are thread-safe. You just need to manage the CATransaction yourself.
Also, trying to explain “iOS 101” to Marcel Weiher is a bit rich…
> Once per frame, Lottie would execute code on the main thread to advance the progress of the animation and re-render its content
There are some optimizations regarding e.g. scrolling being computed in a different thread/process (still on the CPU) before compositing (on the GPU) but that is not a requirement for smooth animation.
I’d have been happy to discuss the nature of a UIKit and iOS based app cycle that affects these things, but I won’t with such an insufferable person who has nothing better to do than to contribute nothing other than their own anger out to the world.
I find topics interesting. I comment on said topics. That’s all that matters. Not your opinions. Not your weird hang ups.
It’s the holiday season. Go find someone to love you or share joy with instead of finding people to hate on on the internet. You clearly need it if this is the kind of stuff that gets you raging.
With an immediate mode GUI, you have to typically draw most of the hierarchy when even a single widget changes unless you maintain a state based cache. You’re inherently calculating construction of more unless you’re also doing the same optimizations that a retained mode system does.
The tree vs vector analogy isn’t correct either because neither mode prescribe a data structure. I know it was meant to be an analogy but I don’t think it really applies because it doesn’t reflect most code bases and frameworks.
Maybe our definitions of immediate vs retained don’t align.
As for metrics, I don’t have any on hand, and that perhaps makes the discussion moot, but we’ve done multiple UI implementations on my projects, and immediate UIs don’t compare favourably for energy use until and unless you introduce a retained backing.
Indeed that’s what interfaces like Flutter and SwiftUI do by exposing a React+immediate style API while working over a retained base.
I wish I could share our metrics, and I recognize there’s no reason for you to take me at my word on that, but we have done significant work in this area to compare systems for our projects. For reference , we often make use of multiple APIs across our different apps like Dear,Imgui and SwiftUI depending on their needs.
power users that use something every day or many times a day prefer things that are static, fast, and higher information density.
this is from designing the user interface, 1995
Pixel phones fare a lot better, but I suspect it's just a result of their sheer processing power.
Android is the opposite of barebones. It comes loaded with crap, much of it is using "stop the world" garbage collection while also producing lots of garbage. Building on Java is Android's original sin. You could still build an NDK app, talk to OpenGL, and hit 60Hz on low-end devices, years ago, but that's not how most stuff is developed. There are layers upon layers of crap between applications and the hardware, to the point where apparently people have come to believe that you need special OS interfaces to do smooth animation.