airbnb / lottie-ios

An iOS library to natively render After Effects vector animations
http://airbnb.io/lottie/
Apache License 2.0
25.82k stars 3.75k forks source link

Frame Rate Drop In CollectionView With Many Objects #759

Closed giantramen closed 5 years ago

giantramen commented 5 years ago

Check these before submitting:

This issue is a:

What Platform are you on?

Expected Behavior

Scrolling should be smooth inside the collection view.

Actual Behavior

Scrolling is choppy and frames are dropped. https://vimeo.com/311323971 (This looks worse on the actual device)

Is having a bunch of LOTAnimationViews inside of collection view cells a supported use case? Is there a way I can make it less laggy?

Code Example

extension TestViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 3
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 25
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let testCell = collectionView.dequeueReusableCell(withReuseIdentifier: TestCollectionViewCell.nibName,
                                                             for: indexPath) as! TestCollectionViewCell
        let imageName = "fat_cat"
        if testCell.currentAnimation != imageName {
            testCell.animationView?.removeFromSuperview()
            testCell.animationView = LOTAnimationView(name: imageName)
            testCell.addSubviewAligned(testCell.animationView!)
            testCell.currentAnimation = imageName
        }
        return testCell
    }
}

I am running into this issue in an actual app, this is just a mockup with a random animation to show the issue :)

giantramen commented 5 years ago

Found a good solution: swapping in and out snapshots of the LOTAnimationViews.


testCell.animationView?.play(fromFrame: 60, toFrame: 60) { finished in
    let snapshot = testCell.animationView?.snapshotView(afterScreenUpdates: true)
    DispatchQueue.main.async {
        testCell.snapshotView = snapshot
        testCell.animationView?.isHidden = true
        testCell.contentView.addSubviewAligned(snapshot)
    }
}
buba447 commented 5 years ago

@giantramen Alternatively you can set shouldRasterizeWhenIdle to true on the Lottie Animation.

giantramen commented 5 years ago

I was not seeing any performance increase when using shouldRasterizeWhenIdle

Kedar-27 commented 1 year ago

@calda i am still facing this issue in v4.0.0. Any idea how to fix this. Tried changing the rendering engine. Also tried using dotlottie.

Kedar-27 commented 1 year ago

Sharing zip files

lottiefiles.zip