Frames loading
Hello, I'm trying to use animated webp images as cells for collection view and it works nice on new devices, but on devices like iPhone 7 I have such an issue: on first appearing of cell the loading of images is freezed, and scrolling is not (I can scroll the collection without freezes, so it is not main thread lock). There are approximately 50 cells of images, and they loads by frame. After some time (I guess when all frames of images are passed) all cells begin to animate correctly (after closing and reopening the screen too). Looks like it is something connected with caching. All webp-s are local files, so it is not network loading. Am doing something wrong? Here is the code:
SDWebImageManager.shared.optionsProcessor = SDWebImageOptionsProcessor { _, options, context in
var mutableOptions = options
mutableOptions.insert([.retryFailed, .highPriority/*, .preloadAllFrames*/]) // no efffect on frames loading
return SDWebImageOptionsResult(options: mutableOptions, context: context)
}
SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared)
SDWebImageDownloader.shared.setValue("image/webp,image/*,*/*;q=0.8", forHTTPHeaderField: "Accept")
...
var stickerImageView = SDAnimatedImageView(frame: .zero)
// stickerImageView.shouldIncrementalLoad = true // no efffect on frames loading
stickerImageView.sd_imageTransition = .fade(duration: 0.3)
...
stickerImageView.sd_setImage(with: url, placeholderImage: placeholder)
I guess this is SDAnimatedImageView issue
Did you use the latest version in SDWebImage (current SDWebImage 5.19.0) ?
I remember that SDWebImage recently 5.18.5 fix a issue in https://github.com/SDWebImage/SDWebImage/pull/3636
but on devices like iPhone 7 I have such an issue: on first appearing of cell the loading of images is freezed,
Only iPhone 7 (like a real old device) contains this issue ? What about other devices ?
Is this because of the decoding speed can not even get 1 frame in reasonable time ?
And, actually always remember, SDWebImage is open-sourced.
You can set a breakpoint at SDAnimatedImageView in that animationFrameHandler callback, to see whether new frames is decoded and calledback (so that the SDAnimatedImageView is ready to render this frame onto screen)
https://github.com/SDWebImage/SDWebImage/blob/db1efed37e7e0c21fa1eb2a0e7f11f813f888898/SDWebImage/Core/SDAnimatedImageView.m#L174
@dreampiggy
Did you use the latest version in SDWebImage (current SDWebImage 5.19.0) ?
I used 5.18.10, same behavior on 5.19.0.
Only iPhone 7 (like a real old device) contains this issue ? What about other devices ?
I checked on XR, it was better, but still with frames freezing.
Is this because of the decoding speed can not even get 1 frame in reasonable time ?
Looks like so 😓 Also, I saw a disk activity while freezing, I thought freezing may be connected with cache, but setting stickerImageView.maxBufferSize to any value didn't change anything.
I guess the problem could be connected with amount of decoding webp-s. I don't look to decoding strategy, but looks like we try to decode all webp-s simultaneously, so, we get freezing on decoding on all of them. I checked kingfisher realization, they decode webp-s one by one and show images only after full decoding (but they have artifacts on images on iPhone 7 and XR).
So, @dreampiggy is it possible to add some flag to show animated webp image only after all frames decoding?
You can set a breakpoint at
SDAnimatedImageViewin thatanimationFrameHandlercallback, to see whether new frames is decoded and calledback (so that theSDAnimatedImageViewis ready to render this frame onto screen)
As I assumed, frames actually comes with significant delay on iPhone 7 and not such significant but visible on XR
we try to decode all webp-s simultaneously
If you use mutliple SDAnimatedImage, point to the same SDAnimatedImage object, this may cause bad performance.
which means, different image view, share the same image instance
currently this will cause multiple player been created for each image view (because image player is retained by image view, not image object), and decode each of them
I have indeed a idea to break this old behavior. Like:
- only the image retains the player, same image object share the same play status
- but this will cause that you can not showing the two same WebP at different frame index, all image playback status for the same animated image should be the same😂
is it possible to add some flag to show animated webp image only after all frames decoding?
Can you try using the decode options SDWebImagePreloadAllFrames ? It need to passed during the image loading (which looks like enlarge the network loading time, but actually it's decoding time), not after the completion block.
As I mentioned before, no efffect on frames loading :///
mutableOptions.insert([.retryFailed, .highPriority/, .preloadAllFrames/]) // no efffect on frames loading
This preloadAllFrames actually, decode each Animated WebP frame into a [UIImage] array. In sync and blocking the loading until all frames decode finished.
So, actually, it does not need any decoding during the rendering. If the completion block is called for you, then all frames will be in the RAM and ready to use.
When the timer fired (for animated image's next frame), it will directly render the current frame (that UIImage array's element).
My guess
Is this the timer (means, a class named SDDisplayLink) bug ? Since you don't provide a demo and I don't have a iPhone 7 for testing. You need to set the breakpoint and run to see what happends.
You can set a breakpoint at SDAnimatedImageView in that animationFrameHandler callback, to see whether new frames is decoded and calledback (so that the SDAnimatedImageView is ready to render this frame onto screen)
https://github.com/SDWebImage/SDWebImage/blob/db1efed37e7e0c21fa1eb2a0e7f11f813f888898/SDWebImage/Core/SDAnimatedImageView.m#L174
Or...Can you provide a reproducible demo...Since it's hard to guess what actual happends (on iPhone XR it works but suck at iPhone 7, sounds really surprise, because we don't use some magic hardware detection code like Video Decoding or Metal GL shader).
If you can read simple objc code, you can try to debug with that and provide some more useful information.
And, please fill the template (actually in SDWebImage Core repo)
OS: iOS version ? SDWebImage version (and your WebP coder)
--
Maybe possible a regression for lower iOS firmware for SDAnimatedImageView. Currently I only tested on iOS 15~17 (the old code actually tested on iOS 11, the 4 years ago, but I'm afraied some bugfix may breaks its function)
You can try to cherry-pick to a really old version (2-3 years ago like 5.9.0) to see what's happends.