I've noticed that iOS 18+ seems to issue low-memory warnings more frequently than older iOS versions (at least on devices with <=4GB RAM). It can now happen with the app is using less than half the device's RAM, which I don't recall seeing before. I assume this is because the OS is using more RAM for AI and such.
ksec · 2h ago
iOS used to be hyper memory efficient. Somewhere along the line, that is no longer the case. The same with App responsiveness as well. With Apps size increasing every year.
JamesSwift · 1h ago
In many ways, images are a big reason why things naturally become inefficient. We are up to a 3x scale factor now and so just by virtue of the higher resolution display we are at 3x the pixels for a given image at a given display size.
And apps are much more image heavy now with network/cpu speeds improving to support real time image loading/decoding.
epistasis · 2h ago
The idea of showing a splash screen with the last app contents while the app loaded was a good idea on slower hardware.
Now that we have faster hardware with more memory, developers use frameworks which no longer load fast enough, so we have the splash screen with the last app state, followed by a complete load of up of UI from the ground up with something else.
And the splash screen becomes actively deceptive.
Someone · 2h ago
For developers, the choice used to be between a memory efficient application or no application at all. Nowadays, there’s a third option “not as memory efficient as possible, but tomorrow instead of next month/quarter, and you won’t have to hire and pay experts to tune things”
For many developers, the choice between those three is easy.
stalfosknight · 46m ago
Gross.
conradev · 2h ago
Load images lazily — only when needed — to avoid wasting memory upfront. AsyncImage or Kingfisher are the options.
Kingfisher and AsyncImage decompress images into dirty memory, and images are big. They're fairly CPU and memory inefficient from that perspective.
If anyone wants to build a modern rkyv + FastImageCache hybrid…
ethan_smith · 1h ago
Nuke (https://github.com/kean/Nuke) is a modern alternative that handles efficient memory management with features like progressive decoding and intelligent prefetching.
conradev · 1h ago
It does progressive CGImage decoding right, I do remember looking at that! Efficient for network to pixels. But it stores PNGs on disk.
JamesSwift · 1h ago
So does FastImageCache as far as I can tell? But it also maps it to a packed sprite sheet before writing
JamesSwift · 1h ago
The two approaches seem to serve different use cases. Mapping to a sprite-sheet (how FastImageCache describes itself) doesnt matter if images arent actually reused often (eg doom scrolling). But if you do tend to either reuse the same image or scroll up/down on the same content then yes it will come out ahead.
Ive seen a lot of async image loaders over the years on ios and for the most part they were all fine. The async offload and pushing remote url loading to the background is the most important part of what was historically missing from the first party ios api.
conradev · 36m ago
I largely agree. The other thing that happened is that phones got faster: it just doesn't matter as much anymore. A slow disk cache is fine, but if it does anything on the main thread: straight to jail.
The article is about memory efficiency, though! In order to get equivalent memory behavior the buffers would need to be marked as purgeable (from the article) so that kernel can empty the cache if needed. Not sure if any of these libraries do that.
The main situation where cache speed is tested is app launch: load every image for the current viewport simultaneously. It can take some time if your images are slow to decode.
jamil7 · 1h ago
Is Nuke any different? I know it’s author wrote a lot about performance but I’ve never looked into it.
The framework is lean and compiles in under 2 seconds
It compiles fast, though!
tomovo · 1h ago
> This dramatically reduces memory usage for lists or grids with many items
I'd love to see a specific example with before/after numbers.
> Lottie [...] ends up loading every frame as a raw bitmap.
Isn't Lottie rendering the vector data directly to screen?
JamesSwift · 42m ago
> Isn't Lottie rendering the vector data directly to screen?
It has to rasterize if theres not native vector support, unless its converting the vector to GL calls. Maybe it targets lowest common denominator for the platforms it supports in order to have a stable output.
iOS also didnt support native vector display until fairly recently, and Im not sure if its limited to baked assets in an image atlas or not. It also had limitations in that it only allowed pdf vectors rather than SVG directly. I haven't kept up to know what current state is.
And apps are much more image heavy now with network/cpu speeds improving to support real time image loading/decoding.
Now that we have faster hardware with more memory, developers use frameworks which no longer load fast enough, so we have the splash screen with the last app state, followed by a complete load of up of UI from the ground up with something else.
And the splash screen becomes actively deceptive.
For many developers, the choice between those three is easy.
FastImageCache uses memory mapping and is very efficient, but it's 10 years old: https://github.com/path/FastImageCache
If anyone wants to build a modern rkyv + FastImageCache hybrid…
Ive seen a lot of async image loaders over the years on ios and for the most part they were all fine. The async offload and pushing remote url loading to the background is the most important part of what was historically missing from the first party ios api.
The article is about memory efficiency, though! In order to get equivalent memory behavior the buffers would need to be marked as purgeable (from the article) so that kernel can empty the cache if needed. Not sure if any of these libraries do that.
The main situation where cache speed is tested is app launch: load every image for the current viewport simultaneously. It can take some time if your images are slow to decode.
I'd love to see a specific example with before/after numbers.
> Lottie [...] ends up loading every frame as a raw bitmap.
Isn't Lottie rendering the vector data directly to screen?
It has to rasterize if theres not native vector support, unless its converting the vector to GL calls. Maybe it targets lowest common denominator for the platforms it supports in order to have a stable output.
iOS also didnt support native vector display until fairly recently, and Im not sure if its limited to baked assets in an image atlas or not. It also had limitations in that it only allowed pdf vectors rather than SVG directly. I haven't kept up to know what current state is.