SDWebImageSwiftUI: Freeze when embedded in LazyVStack (iOS14) with 100% CPU usage

Hello,

I tried the example project embedded in Scrollview & LazyVStack instead of the list and the project freeze at startup (100% CPU) on animated tab and freeze after some ‘fast’ scroll on WebImage tab (100% CPU) on emulator.

I tested to fix the SDWebImage version to: s.dependency 'SDWebImage', '~> 5.8.3' without conclusive results.

If i use the native Image component with local image then it’s working.

Do you have any idea about this ?

func contentView() -> some View {
        ScrollView {
            LazyVStack {
                ForEach(imageURLs, id: \.self) { url in
                    NavigationLink(destination: DetailView(url: url, animated: self.animated)) {
                        HStack {
                            if self.animated {
                                #if os(macOS) || os(iOS) || os(tvOS)
                                AnimatedImage(url: URL(string:url))
                                    .onViewUpdate { view, context in
                                        #if os(macOS)
                                        view.toolTip = url
                                        #endif
                                    }
                                    .indicator(SDWebImageActivityIndicator.medium)
                                    .transition(.fade)
                                    .resizable()
                                    .scaledToFit()
                                    .frame(width: CGFloat(100), height: CGFloat(100), alignment: .center)
                                #else
                                WebImage(url: URL(string:url), isAnimating: self.$animated)
                                    .resizable()
                                    .indicator(.activity)
                                    .transition(.fade(duration: 0.5))
                                    .scaledToFit()
                                    .frame(width: CGFloat(100), height: CGFloat(100), alignment: .center)
                                #endif
                            } else {
                                WebImage(url: URL(string:url))
                                    .resizable()
                                    .indicator(.activity)
                                    .transition(.fade(duration: 0.5))
                                    .scaledToFit()
                                    .frame(width: CGFloat(100), height: CGFloat(100), alignment: .center)
                            }
                            Text((url as NSString).lastPathComponent)
                        }
                    }
                    .id(UUID())
                    .buttonStyle(PlainButtonStyle())
                }
                .onDelete { indexSet in
                    indexSet.forEach { index in
                        self.imageURLs.remove(at: index)
                    }
                }
            }
        }
    }

Thanks !

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 60

Most upvoted comments

The problem is still happening on lazyvsack with foreach and scrollview, WebImage is taking 100+% of cpu, version 2.0

Having same issue. I wonder if it’s bug in the implementation of the lazy stacks when you refresh the item once it’s been already presented.

Appears to be fixed, in my project at least 👍 it was very easy to reproduce before but not able to reproduce it anymore.

@wilg Thanks for the heads up. I should have made it clearer in my comment that the type of the @State var doesn’t matter. It can be Bool? or Bool or Int or String and the same problem occurs. I’ll change the code in my example so it won’t be complicated by that part. 🙏

As far as class vs. structs, you’re right that in the general case I wouldn’t expect a class to work with @State. I obviously don’t know the implementation details of SwiftUI, but my intuition is that since UIImage is immutable the specific problem of a View not updating when a class’s fields change isn’t applicable.

I have the same issue, with a structure like Netflix app with images. Using LazyStack. Normal starck are working great but takes too much time to render since there is a lot of images.

@dreampiggy this is the call

image

this happens when there are few hundreds images (100KB ish) in LazyVStack

and it seems after everything is ‘cached’, the problem will no longer exist

I have the code like that demo that you sent, but not inside a NavigationLink, should I send you the instrument profile that checks the cpu usage? or provide you with code?

I have the same problem on tvOS with Xcode 12.0.1 and LazyVGrid. I get this error:

Attempted to read an unowned reference but the object was already deallocated

Screen Shot 2020-10-11 at 11 44 53 PM

I have images in NavigationLink inside the grid. If I get the image out of NavigationLink, it works without problem.