In this page, there are some tips and tricks to improve the build times of the app.
Table of Contents:
- Build Times
- Build with Timing Summary and Recent Build TimeLine:
- Improve Compile Time in Xcode Projects:
- Improve Compile Time in SPM Packages:
- SwiftLint Rules:
- Additional Tips:
Xcode provides two great tools to measure the compilation time:
From the Product
Menu -> Perform Action -> Build With Timing Summary:
- Note: For clean builds, remember to clean the build folder (
Command + Shift + K
) before performing the build. - Once the build finishes, select it from the
Report navigator
, selectRecent
andAll Messages
sub tabs, then scroll all the way down to check the report.
The Recent Build TimeLine
feature is quite handy for analyzing build times. To access it, select a recent build and go to Editor -> Assistant
. This timeline view provides a visual representation of build processes and times, helping us identify areas that need optimization.
The first step is to make Xcode display warnings in the code that takes too long to compile:
- Select the target project.
- Go to the
Build Settings
tab. - Select the
All
sub tab. - Filter
Other Swift Flags
. - Add the following:
-Xfrontend -warn-long-function-bodies=<milliseconds>
-Xfrontend -warn-long-expression-type-checking=<milliseconds>
These flags enable warnings for long function bodies and expression type checking, allowing us to identify potential bottlenecks in our codebase.
We can actually do the same For SPM packages, by applying the following swiftSettings
to the target:
swiftSettings: [
.unsafeFlags([
"-Xfrontend",
"-warn-long-function-bodies=50",
"-Xfrontend",
"-warn-long-expression-type-checking=50"
])
]
The explicit_init and explicit_type_interface rules can indeed help streamline our code and potentially reduce build times. Ensuring clarity in our code's initialization and type interfaces can prevent unnecessary ambiguity that might slow down the build process.
We could also add this custom rule, to avoid the usage of the .init
sugar syntax.
init_with_name:
name: "Init With Name"
message: "Prefer let object = Class() instead of let object: Class = .init()"
included: ".*.swift"
regex: '(?<!self|super)\.init\('
match_kinds:
- identifier
- keyword
severity: warning
- Check that the scheme's build configuration is set to
Debug
. - Avoid Type Inference: Explicitly defining types can prevent the compiler from spending extra time inferring types, leading to faster builds.
- Avoid shorthand enums usage. Instead of
status == .blocked
, usestatus == UserStatus.blocked
. - Use View Composition: Embracing view composition can result in more modular and focused code, which can lead to improved build times.
- Access Control: Employing the correct access control for our code can help the compiler optimize compilation, reducing unnecessary work.
- Use Periphery to find and delete unused code.
- Watch the Demystify parallelization in Xcode builds
WWDC 2022
video. - BlogPost