Comments (7)
One more thing you can try is enabling isUsingPrepareForDisplay
. It then switches to use the native prepareForDisplay method for decompression. It's disabled by default because there've been multiple reports of it causing issues in earlier iOS versions. It's probably a good time to revisit it and see if it can be enabled by default. Apple recently added a bunch of error logs when you use it for formats that don't require decompression, so it makes it very hard to use now.
from nuke.
Update: we tried to release a version with the isUsingPrepareForDisplay
and seems like it still has issues 😓 .
It's not super significant as well, but seems to happen twice as much as the original one (so it's affecting ~0.4% users).
I tried now setting the isDecompressionEnabled
to false
, which avoids both crashes. There seems to be no much difference in CPU usage, but looks like the memory consumption increases quite drastically.
Any other advices?
14 ourApp 0x7676d0 UIImage.decompressed(isUsingPrepareForDisplay:) + 151 (Graphics.swift:151)
15 ourApp 0x77fb58 specialized ImagePipelineDelegate.decompress(response:request:pipeline:) + 10 (ImageDecompression.swift:10)
16 ourApp 0x79b830 closure #1 in TaskLoadImage.decompressImage(_:isCompleted:isFromDiskCache:) + 202 (TaskLoadImage.swift:202)
17 ourApp 0x772004 thunk for @escaping @callee_guaranteed @Sendable () -> () + 4341030916 (<compiler-generated>:4341030916)
full stack trace:
NSOperationQueue 0x13cbc8b60 (QOS: UNSPECIFIED)
0 libsystem_kernel.dylib 0x1b7c __psynch_cvwait + 8
1 libsystem_pthread.dylib 0xfd4 _pthread_cond_wait + 1228
2 CoreMedia 0x2540 WaitOnCondition + 20
3 CoreMedia 0x2484 FigSemaphoreWaitRelative + 164
4 VideoToolbox 0x30e068 VTDecompressionSessionRemote_DecodeTile + 576
5 CMPhoto 0x15b70 VTTileDecompressionPluginClass_decode + 376
6 CMPhoto 0x1b974 _decodeItem + 6008
7 CMPhoto 0xb78c _applyDecodeStrategy + 396
8 CMPhoto 0x7055c _decodeImage + 452
9 CMPhoto 0x6c564 _createImageForIndex + 804
10 CMPhoto 0x273b0 CMPhotoDecompressionContainerCreateImageForIndex + 280
11 UIKitCore 0xa361ec -[_UINewCGImageDecompressor waitForImageRef] + 160
12 UIKitCore 0x85acdc -[_UIImageCGImageContent contentPreparedForDisplay] + 84
13 UIKitCore 0x9f7638 -[UIImage imageByPreparingForDisplay] + 28
14 ourApp 0x7676d0 UIImage.decompressed(isUsingPrepareForDisplay:) + 151 (Graphics.swift:151)
15 ourApp 0x77fb58 specialized ImagePipelineDelegate.decompress(response:request:pipeline:) + 10 (ImageDecompression.swift:10)
16 ourApp 0x79b830 closure #1 in TaskLoadImage.decompressImage(_:isCompleted:isFromDiskCache:) + 202 (TaskLoadImage.swift:202)
17 ourApp 0x772004 thunk for @escaping @callee_guaranteed @Sendable () -> () + 4341030916 (<compiler-generated>:4341030916)
18 Foundation 0x49c00 __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 24
19 Foundation 0x7b0ec -[NSBlockOperation main] + 104
20 Foundation 0x78974 __NSOPERATION_IS_INVOKING_MAIN__ + 16
21 Foundation 0x77a64 -[NSOperation start] + 648
22 Foundation 0x7a57c __NSOPERATIONQUEUE_IS_STARTING_AN_OPERATION__ + 16
23 Foundation 0x7a2e8 __NSOQSchedule_f + 172
24 libdispatch.dylib 0x13250 _dispatch_block_async_invoke2 + 148
25 libdispatch.dylib 0x4300 _dispatch_client_callout + 20
26 libdispatch.dylib 0x77b8 _dispatch_continuation_pop + 600
27 libdispatch.dylib 0x6dd4 _dispatch_async_redirect_invoke + 584
28 libdispatch.dylib 0x15be4 _dispatch_root_queue_drain + 392
29 libdispatch.dylib 0x163ec _dispatch_worker_thread2 + 156
30 libsystem_pthread.dylib 0x1928 _pthread_wqthread + 228
31 libsystem_pthread.dylib 0x1a04 start_wqthread + 8
EDIT: to elaborate in the memory consumption part - this seems to be kind of an unexpected outcome?
From the description, I understand that the decompression step is meant to improve CPU performance (and achieve smoother scrolling), but turns out Nuke's implementation when using isUsingPrepareForDisplay = false
has a 30% less memory usage compared to either isUsingPrepareForDisplay = true
or isDecompressionEnabled = false
, which basically have the same memory footprint 🤔
After scrolling ~180 products/images on a single screen | |
---|---|
isUsingPrepareForDisplay = true | isUsingPrepareForDisplay = false |
from nuke.
Hey, thanks for the report!
Not sure if relevant, but the image format we are using is avif.
If you find a way to reproduce it, that would be fantastic.
until we wait for Apple to fix it (if ever)?
A Feedback report may help.
from nuke.
Thanks for you reply!
If you find a way to reproduce it, that would be fantastic.
I spent hours on it, but unfortunately could experience the crash only once (when I took the screenshot). It's not a deterministic crash, i.e., the exact same place/image that caused the crash wouldn't do so on next runs.
Seems like some kind of random memory corruption, so really hard to reproduce, otherwise numbers would be higher.
For now I guess it would help to know if there's any way to avoid this call, or if it's something mandatory in the download pipeline
A Feedback report may help.
yeah, will open a radar
from nuke.
You can pass skipDecompression option for any avif images and see if it fixes it. But I see HEIFReadPlugin::decodeImageImp
in the crash log, so it may actually be HEIF that's causing the issue.
from nuke.
But I see HEIFReadPlugin::decodeImageImp in the crash log, so it may actually be HEIF that's causing the issue.
Interesting, haven't noticed before. That's weird, because I'm quite positive we don't load HEIF images on our app (checked on monitoring all content types of all network requests). I can only imagine that under the hood this code is shared when the image data is from another format and/or the image data is miscategorised. Since the code is private, I wonder if there's any easy way to check/confirm that.
One more thing you can try is enabling isUsingPrepareForDisplay. It then switches to use the native prepareForDisplay method for decompression. It's disabled by default because there've been multiple reports of it causing issues in earlier iOS versions. It's probably a good time to revisit it and see if it can be enabled by default. Apple recently added a bunch of error logs when you use it for formats that don't require decompression, so it makes it very hard to use now.
That sounds great and seems like what I was looking for. Since it avoids the the CoreGraphics
code it should fix our issue, and I can also report here if any other issue happens or not as side effect.
PS: I also filed the bug report with Apple, can post here if there's ever any feedback, but we know how this things goes...
from nuke.
We released a version using skipDecompression option and now all the crashes are gone, since it avoids the CoreGraphacs problematic code.
Like said above, unfortunately this has the side effect of increased memory consumption, so we will keep an eye to revert this change if/when Apple ever fixes the issue.
I'm closing this issue to avoid it hanging forever in the repo. Thanks @kean for the support!
from nuke.
Related Issues (20)
- storeCachedData: callback once stored in cache HOT 5
- LazyImage: What is the correct way to reload reload an image after a network failure? HOT 2
- Use GIF with NukeUI HOT 2
- Custom CacheKey like SDWebImage HOT 1
- Images fetched with ImagePrefetcher on shared pipeline are not in cache, but they are when manually loading each one HOT 1
- Include Privacy Manifests for the SDK HOT 4
- Is it possible to use a custom CIFilter with an ImageRequest? HOT 2
- Missing support for macCatalyst in Nuke 12.4 HOT 2
- LazyImage(url:) does not load image when using ImageRenderer HOT 4
- Add mandatory privacy manifest HOT 1
- SwiftUI Warning: Accessing StateObject's object without being installed on a View. This will create a new instance each time. HOT 2
- Xcode 15.3 concurrency warnings when using `Screen.scale`
- The operation couldn’t be completed: ImagePipeline.Error error 0 HOT 1
- Missing documentation for using LazyImage implementation inside Package HOT 2
- ImageRequest userInfo dictionary `Any` type for value allows unsupported types for imageIdKey HOT 2
- Any way to modify ImageRequest before it's executed? HOT 1
- Potential Memory Issue when using any processors such as Resize HOT 11
- Custom DataLoader without native URL cache HOT 1
- JPG not resizing, just black HOT 2
- Xcode warning: IO on main thread HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nuke.