Solved: SwiftUI Previews Hanging

I just wanted to post this here because since we started using SwiftUI, SwiftUI Previews have been painful to use, and then became basically unusable. And then after many hours of investigating, I seem to have found a solution and I wanted to share it somewhere useful.

The symptoms were that when clicking in the circle to enable preview (from the preview paused state) for any view, the progress spinner would sit there for... sometimes forever, but sometimes for 20 minutes before a preview would show.

It wasn't just slow, it was entirely unusable. Most of the complaints I've seen from other developers are about it being slow and unresponsive, but for us, it would just spin infinitely (rarely it would stop and then the preview would display). None of the 'fixes' here or on StackOverflow, etc helped.

So after a year of just mostly not using SwiftUI Previews, I found something interesting - under the build tab, the app was continually being rebuilt when the preview canvas with the spinner was being shown.

What?

OK, so it turns out we have a Run Script build step that generates output (a Credits.plist for open source libraries). It did not declare output files, which XCode had long complained about, but in general was not an issue... except apparently for SwiftUI Previews.

Checking the "For install builds. only" checkbox for this build step made the problem go away. That was it. SwiftUI Previews build and run fairly well now.

I have not tried fixing the complaint about the build script outputs - that might have also fixed the problem, but "For install builds only" definitely fixed our issue.

Answered by DTS Engineer in 845940022

First, try turning off all shell script build phases (like linters), that will give you idea if that is the issue.

If it is, you might want to consider moving some phases into asynchronous steps like only running when in CI, or on demand (like running linters before committing, not on every build). If you need a shell script build phase, make sure to explicitly define the inputs and outputs. That's a huge way to improve performance.

If you have further questions you can file a bug report with previews diagnostics so the engineering team can investigate. Please post the FB number here once you do.

Bug Reporting: How and Why? has tips on creating your bug report.

Accepted Answer

First, try turning off all shell script build phases (like linters), that will give you idea if that is the issue.

If it is, you might want to consider moving some phases into asynchronous steps like only running when in CI, or on demand (like running linters before committing, not on every build). If you need a shell script build phase, make sure to explicitly define the inputs and outputs. That's a huge way to improve performance.

If you have further questions you can file a bug report with previews diagnostics so the engineering team can investigate. Please post the FB number here once you do.

Bug Reporting: How and Why? has tips on creating your bug report.

Solved: SwiftUI Previews Hanging
 
 
Q