I’m running into issues when trying to use NSDiffableDataSourceSectionSnapshot. I want to have this UI, where we have multiple sections and each section has builds, but the additional builds are collapsible. This works, however, since there are a large number of sections there is some significant UI hangs. I played around with the number of sections and the magic number appears to be 80. 80 sections or less and there are no UI hangs, but anything over that will experience a hang.

Here is the snapshot code that I am using to generate the section snapshots.

        if snapshot().sectionIdentifiers != sections.map(\.branch) {
            var snapshot = Snapshot()
            snapshot.appendSections(sections.map(\.branch))
            apply(snapshot, animatingDifferences: animatingDifferences)
        }

        sections.forEach { section in
            var sectionSnapshot = SectionSnapshot()

            if let currentBuild = section.builds.first.map({ SectionItem.currentBuild($0) }) {
                sectionSnapshot.append([currentBuild])
            }

            if section.builds.count > 1 {
                let additionalBuildsHeader = SectionItem.additionalBuildsHeader(forSection: section.branch)
                sectionSnapshot.append([additionalBuildsHeader])
                let additionalBuilds = section.builds
                    .dropFirst()
                    .map({ SectionItem.additionalBuild($0) })
                sectionSnapshot.append(additionalBuilds, to: additionalBuildsHeader)

                if expandedSections.contains(additionalBuildsHeader) {
                    sectionSnapshot.expand([additionalBuildsHeader])
                }
            }
            apply(sectionSnapshot, to: section.branch, animatingDifferences: animatingDifferences)
        }

After some tinkering we discovered that building the snapshot without using a section snapshot loaded the UI without any issues. This works, and I am ok with this approach. We just loose the nice collapsible section for the additional builds.

        var snapShot = Snapshot()
        snapShot.appendSections(sections.map(\.branch))

        sections.forEach { section in
            if let currentBuild = section.builds.first.map({ SectionItem.currentBuild($0) }) {
                snapShot.appendItems([currentBuild], toSection: section.branch)
            }

            if section.builds.count > 1 {
                let additionalBuilds = section.builds
                    .dropFirst()
                    .map({ SectionItem.additionalBuild($0) })
                snapShot.appendItems(additionalBuilds, toSection: section.branch)
            }
        }
        apply(snapShot, animatingDifferences: animatingDifferences)

I feel that this is related to calling apply many times for the section snapshots as opposed to one apply in the second example. Am I doing something wrong with the section snapshots that is causing the bad performance?