KEMBAR78
Xcode Build Time Optimization, Xcode 14 - Medium | PDF | Swift (Programming Language) | Xcode
0% found this document useful (0 votes)
47 views20 pages

Xcode Build Time Optimization, Xcode 14 - Medium

The article discusses strategies to optimize build times in Xcode, particularly for large-scale projects, highlighting a case study where build time was reduced by 80%. It explains the build process, identifies problematic phases, and suggests disabling the Integrated Swift Driver introduced in Xcode 14 as a solution to excessive build delays. Additionally, it recommends using commit hooks for running SwiftLint to improve efficiency without sacrificing code quality.

Uploaded by

Anderson Reis
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
47 views20 pages

Xcode Build Time Optimization, Xcode 14 - Medium

The article discusses strategies to optimize build times in Xcode, particularly for large-scale projects, highlighting a case study where build time was reduced by 80%. It explains the build process, identifies problematic phases, and suggests disabling the Integrated Swift Driver introduced in Xcode 14 as a solution to excessive build delays. Additionally, it recommends using commit hooks for running SwiftLint to improve efficiency without sacrificing code quality.

Uploaded by

Anderson Reis
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

Xcode Build Time Optimization


How to improve Xcode build time

Emin DENİZ Follow 10 min read · Sep 13, 2023

542 4

Xcode Logo

As a developer who has been working with Xcode for over 9 years, I suffer a
lot with lots of features that are in the Xcode. In my opinion, the worst one is
the build time. It can take minutes, possibly hours, for large-scale projects.
In this article, I will explain how we were suffering in the AutoScout24 iOS
project and how we improved it. We managed to decrease the time we spent
by %80 using this methodology.

Improving the build time obviously means clearing up any problematic


process that takes too much time. For each project, these problematic
processes can be different. I will try to explain how you can investigate and
solve this issue in this article. I hope it will be helpful for you.

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 1 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

Introduction to basic concepts


Before starting into the findings it is better to explain which time frames we
will focus on improving on this article.

Fetching time: fetching the source codes and required frameworks from
dependency management tools (SPM or CocoaPods)

Build time (Clean build): Build the Xcode project the first time after
fetching or compiling after cleaning the Derived Data folder.

Incremental build time: Building the project after changing a certain


amount of code blocks in the project. Xcode doesn’t try to compile
everything if you change a single code block. It only compiles the
changed source file and files that needed that specific file (At least in
theory).

Fetching time mostly depends on the bandwidth you have. So we can say that
fetching time is not the focus of this article.

Understanding how Xcode builds a project


Before diving into the investigation let me explain how Xcode builds a
project. Keep in mind that the Xcode build process is a highly complex topic
and there can be some additional phases for some complex projects. I will
try to explain it as simply as possible by showing the basic steps.

When you hit the build button here are the fundamental steps that happen.

1. Xcode analyzes the project and creates a build plan.

2. Xcode builds the framework that needs compiling.

3. Xcode builds the resource files (like Storyboards, XIBs, etc.) that need
compiling.

4. Xcode builds the source files (Swift and Objective-C) that need compiling.

5. Then Xcode links everything (frameworks, resources, and source files)


together.

6. Finally, it runs custom scripts if you have one.

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 2 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

How Xcode builds a project

Keep in mind that some of those steps can be run in parallel in Xcode. For the sake
of simplicity, in this article, we assume those steps are serial.

Although almost all the phases are straightforward, you might wonder why
we need an “Analyze & Build Plan” in the first phase and what it does. In this
phase, Xcode decides what needs to be compiled in the simplest manner.
You may ask ‘Shouldn’t everything be compiled on each build?’. The answer is,
thankfully, no. Let’s assume you just changed a single line of code in a
project with 10,000 Swift files. Recompiling everything is a waste of time
because most of the files are not affected by this change. To understand this
let's get into a bit of detail.

When you implement a source file and build Xcode use the related compiler
(Swift compiler for swift files, CLang compiler for the rest of them.). After
the compiling, it extracts linked objects. Linkers are precompiled and ready-
to-use objects.

How Xcode compiles source file

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 3 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

As you already know we are importing some other source files or some other
frameworks to our source files in both Swift and Objective-C. For example,
let’s examine the diagram below. Class D imports Class C and Framework A.
Class C imports Class A and Class B. As a result, Class D imported Class C &
Framework A directly and it imported Class A & Class B indirectly.

Sample import diagram

When you compile this project for the first time or compile after cleaning,
Clang and Swift compile Class A and Class B then create the linkers. At this
point Class C can use the linkers of Class A and Class B. After that Xcode
compiles Class C to create linkers. Class D can use the linkers of Class C and
Framework A now (Assuming that Framework A already compiled and ready
to use). At last Xcode compiles Class D.

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 4 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

After this clean compile, let’s see what happens if you change some files and
build (incremental build) the project.

If you change something in Class C, Xcode only needs to recompile Class C


and Class D. Because the linkers of Class A and Class B are still valid.

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 5 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

Build plan after changing some code at Class C

If you change something in Class A, Xcode needs to recompile Class A,


Class C, and Class D. Class B and Framework A’s linkers are still valid.

Build plan after changing some code at Class A

If you change something in Class D, Xcode only needs to recompile Class


D because the rest of the linkers are still valid.

I think you get the point So “Analyze & Build Plan” phase tries to
understand which files are changed and which other files are importing
those files. As a result, Xcode understands what needs to be compiled.

Incremental build time takes longer if you change a


file that is imported a lot, directly or indirectly.

Investigation
Search Of The Current Build Time Write

In practice, it is acceptable that Clean Build takes more time than Incremental
Highlight Respond Share Private note
Build. We will investigate both build time. But keep in mind that most of the
time we are using the Incremental Build. This means the problems with
Incremental Build time can kill our productivity.

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 6 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

Xcode Build Timeline


Luckily we have a Build Timeline panel in Xcode 14. After building your
project go to the “Report Navigator” in the left pane of Xcode. Then select the
latest build report. After clicking the “Related Items” button select the
“Recent Build Timeline”. Please see the gif below to see visually how you can
do this.

How to open Recent Build Time in Xcode

Here are the results I saw when I ran it on a complex project.

Build time investigation of a complex iOS project

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 7 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

As you can see we spent a total of 185 sec on a clean build. It is not perfect
but in high-scale projects, it is acceptable. Here are the time frames in the
image above and what they mean.

t1: Time for Xcode to analyze the overall project and create a building
plan. (48s)

t2: Time for Xcode to compile and integrate the frameworks we use. (39s)

t3: Time for Xcode to compile resources (xib, storyboards, etc.) we have.
(8s)

t4: Time for Xcode to compile source codes we have and link everything.
(69s)

t5: Time for Xcode to run custom scripts like Swift Lint. (22s)

t6: Time for Xcode to run remaining custom scripts and complete the
validation. (9s)

You probably already realize that the timeframes we


found on build time match the build steps we
discussed in the previous section.

Okay, we see that it takes 185 for a clean build for our project. Let’s see what
happens if we just change a single line of code. We already point out that
incremental build can take a longer time if you change a file that is imported
a lot, directly or indirectly. For that reason, I updated a file that does not
import any file. This means only this file should be compiled and linked.
Let’s see the results.

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 8 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

Incremental build time investigation of a complex iOS project

As you can see the results are nonsense. I just added a single line of code in a
file that is not imported to any file and it took 103 sec Let’s investigate the
timeframes again and try to understand the problem.

t1: Time for Xcode to analyze the overall project and create a building
plan. (35s)

t2: Time for Xcode to emit swift modules (Not sure what it means). (16s)

t3: Time for Xcode to compile source codes, some unchanged and not
imported lines due to bridging header. (33s)

t4: Time for Xcode to run Swift Lint custom script. (19s)

Even if I changed some strings in a log in the same file it took more than 80
seconds!

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 9 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

It is obvious that what we see at t1, t3, and t4 is killing our productivity. Let’s
try to understand what the problems are and how we can solve them.

Investigation of issues about t1 and t3


After digging into this problem on the internet I realized that Apple released
a new Xcode compiler component called Integrated Swift Driver with Xcode
14. According to WWDC 2022 — “Demystify parallelization in Xcode builds”
session, Swift Driver is a replacement for the current driver that is a part of
the Clang compiler. According to Apple the great benefit of the new Swift
Driver is that it can run parallelized tasks that improve build time.

When you want to build an application or a framework Xcode starts to build


and link the dependent frameworks first. Assume that you have a project
with 3 modules (source files or frameworks), Red, Orange, and Purple. Red
depends on Orange and Purple. To be able to build the Red you first need to
build and link other 2 frameworks, like in the image below. A, B, C, D, and E
stand for internal tasks for each module (like compiling a single swift class).

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 10 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

Build time frame before Xcode 14

So until the Orange D and Purple D are completed Xcode won’t start to build
the Red module. This is the legacy approach we have until Xcode 14.

After the Xcode 14 with Swift Driver Apple paralyzed these internal tasks (A,
B, C, D, and E) to have faster builds. So it will change the image above like
this:

Build time frame after Xcode 14

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 11 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

In theory, this will give us the opportunity to have


faster builds. But unfortunately, it does the opposite
thing for us.

After a little research, I found out that people are complaining about the
Xcode 14 incremental builds as we do in this swift forum thread. It turns out
the new Swift Driver is wasting time on the build plan and trying to
recompile some sources that are irrelevant to the changes. This is especially
a problematic situation for projects which has Objective-C and Swift code in
their projects. As a solution, people suggested disabling the new integrated
Swift driver with a build setting called SWIFT_USE_INTEGRATED_DRIVER . We can
add a User-Defined setting in Xcode and set SWIFT_USE_INTEGRATED_DRIVER to
NO .

Disabling Xcode integrated driver

Here are the results after disabling the new driver.

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 12 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

As you can see comparing the previous image total time we spent for t1, t2,
and t3 decreased from 84 sec to 19 sec Results clearly show that the new
swift driver causing meaningless delay on builds. This is especially a
problem if your project has both Swift and Objective-C codes.

Important note: You need to clean the DerivedData folder and quit the Xcode
after disabling the SWIFT_USE_INTEGRATED_DRIVER option. Otherwise, you may
not see the effects after the upcoming builds.

Investigation of issues about t4 (SwiftLint)


Running a custom script like SwiftLint is a common thing you can see in
most real-life projects. It is pretty handy to execute some custom stuff inside
the build and there is a cost. For us running SwiftLint on every build costs us
19 sec. But this is not something we can easily get rid of. Because SwiftLint is
the tool we trust for the styling of the code.

The solution to such a problem can be to use commit hooks. We can run
SwiftLint on the pre-commit hook, which means it runs SwiftLint before
every commit. There are some articles and Gists you can find online for such
purposes. But let me share the one that also has SwiftLint Fix functionality.

1 #!/bin/bash
2
3 # COLOR codes to use in logs
4 RED='\033[0;31m'
5 YELLOW='\033[1;33m'
6 GREEN='\033[0;32m'
7 BOLD='\033[1m'
8 NC='\033[0m' # No Color
9
10 # LOG tag of file
11 LOG_TAG="PRE_COMMIT_HOOK_LOG :: "
12 # swiftlint.yml path.
13 LINT_CONFIG_FILE=".swiftlint.yml"
14
15 set -e
16
17 # check if lint exists.

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 13 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

17 # check if lint exists.


18 if ! command -v swiftlint &> /dev/null
19 then
20 echo -e "${LOG_TAG}${RED}SwiftLint could not be found. Please install it in your computer.${NC}"
21 exit 1
22 fi
23
24 echo -e "${LOG_TAG}Linting..."
25
26 #Always lint one file to prevent "No lintable files found at paths: ''"
27 export SCRIPT_INPUT_FILE_0="##Put one of your files with its path that will always be in your project. (For Ex
28 # This variable will store the files that needs to be re-added after auto fix.
29 FILES_TO_ADD=""
30 swiftFileCount=1
31
32 # We will count the changed files and apply lint only for them.
33 while IFS= read -r file_path; do
34 export SCRIPT_INPUT_FILE_$swiftFileCount="$file_path"
35 swiftFileCount=$((swiftFileCount + 1))
36 # We should escape from whitespace paths.
37 escaped_path="${file_path// /\\ }"
38 FILES_TO_ADD+="'$escaped_path' "
39 done < <(git diff --diff-filter=d --name-only --cached | grep ".swift$")
40
41 echo -e "${LOG_TAG}The count of Swift files you changed and add to git is '${BOLD}$swiftFileCount${NC}'"
42
43 # In case there is no change besides the default 'Classes/Constants.swift' don't run the lint
44 if [ "$swiftFileCount" -ne 1 ]; then
45 export SCRIPT_INPUT_FILE_COUNT=$swiftFileCount
46
47 if swiftlint --fix --strict --use-script-input-files --config $LINT_CONFIG_FILE && swiftlint --use-script-
48 # Re-add files after lint fix. Otherwise we can't send the auto fixed codes to the remote.
49 # adding with echo prevents incorrect file addings.
50 echo "git add ${FILES_TO_ADD}"
51 echo -e "${GREEN}${LOG_TAG}No Swift Lint violations found. Your commit is good to go.${NC}"
52 exit 0
53 else
54 echo -e "${RED}${LOG_TAG}'${BOLD}swiftlint fix${NC}' ${RED}could not fix the problem. Please check the
55 exit 1
56 fi
57 else
58 echo -e "${LOG_TAG}${YELLOW}No files to lint!${NC}"
59 exit 0
60 fi
61
62 # Unset the environment variables
63 unset "SCRIPT_INPUT_FILE_COUNT"
64 for ((i=0; i<swiftFileCount; i++)); do
65 unset "SCRIPT_INPUT_FILE_$i"
66 done

PreCommitHook.sh hosted with ❤ by GitHub view raw

You can add this file to your .git/hooks directory and use it.

Let’s see the results without having SwiftLint in the custom script phase.

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 14 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

The final form of incremental build time

As you can see the total time we spent to build decreased to 18 sec (it was
between 73–103 sec). Also, as you can see in the image below Clean Build
time also decreased to 91 sec (it was 185 sec).

The final form of clean build time

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 15 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

From the test results we saw here, we can say that disabling the integrated
swift driver and putting swift lint to commit hooks decreases the build time
from 103 sec to 18 sec. This means we use %80 less time to build the project.
Also, a clean build takes %50 less time.

Summary
In this article, my aim is to show you how you can investigate a build-time
problem in Xcode and how you can solve some of them.. Keep in mind that
build time-related issues can be caused by a variety of things. It is possible
that you might suffer from another problem. But if you follow this
methodology I believe that you can solve your problems one by one.

During this process, I applied some of the suggested improvements that


Apple suggested to improve build speed. But for me, it didn’t make that much
difference. Here are the links in case you wonder:

Improving the speed of incremental builds | Apple Developer Documentation


Tell the Xcode build system about your project's target-related dependencies, and reduce
the compiler workload during…
developer.apple.com

Improving build efficiency with good coding practices | Apple Developer


Documentation
Shorten compile times by reducing the number of symbols your code exports and by
giving the compiler the explicit…
developer.apple.com

IOS Xcode Mobile App Development Xcode 14 IOS App Development

Written by Emin DENİZ Follow


227 followers · 52 following

Mobile Team Lead at AutoScout24

Responses (4)
https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 16 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

Responses (4)

Anderson Chagas

What are your thoughts?

Cédric Bahirwe
Nov 3, 2023

it imported Class A & Class C indirectly.

I think you mean, it imported Class A & Class B indirectly.

6 Reply

Jaypy
Mar 7, 2024

this is excellent!

5 Reply

Minurrica
Jul 28, 2024

i added swift use integrated driver and set to no, i had to clone the project from Git because it fked up and
won't build anymore. Add a disclaimer

Reply

See all responses

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 17 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

More from Emin DENİZ

Emin DENİZ Emin DENİZ

Downloading App Store Reviews iOS UI Testing with Deep Links


Using App Store Connect API UI Test, Deeplinks, Universal Links, URL
How to Download App Store Reviews with the Scheme
App Store Connect API automatically

Jun 17, 2024 40 3 Dec 18, 2023 237 2

Emin DENİZ In Orion Innovation techClub by Emin DENİZ

Push UTM Tracking on iOS for GA4 Xcode Workspace with multiple
Implementing UTM Parameter Tracking for projects
GA4 in iOS After Push Notification Received In simple projects you can easily organize
files using groups. You just need to create…
groups and put your files in them as in the
Jun 4, 2024 225 5 example…
Jul 29, 2021 648 2

See all from Emin DENİZ

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 18 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

Recommended from Medium

In The Airbnb Tech Blog by Cal Stephens MdNiks

Understanding and Improving Why Acyclic Dependency Graphs


SwiftUI Performance Matter in Modular iOS Projects
New techniques we’re using at Airbnb to Modularization is a common architectural
improve and maintain performance of Swift… strategy in iOS development that helps with…
features at scale code scalability, testability, and team
Jun 24 290 4 collaboration…
Jun 20 1

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 19 of 20
Xcode Build Time Optimization, Xcode 14 | Medium 07/07/25, 00:02

In Axel Springer Tech by Bo Liu Ebillson GRAND JEAN

AI Meets iOS Development iOS Security Deep Dive: How I


Comparing Copilot for Xcode, Xcode Code Implemented Device Attestation…
Completion, Cursor, and Cline Without Third-Party
“Attestation SDKs
isn’t just a feature —it’s a shield.
And Swift gives you everything you need to…
build it.”
Apr 24 3 Apr 24 5 1

Avi Levin JC

Developing in Xcode with AI: Building an AI ChatBot with Apple’s


Comparing Copilot, Claude, MCP,… Foundation Models Framework: A…
Cursor, and More
Introduction Complete SwiftUI
Harness the power Guide AI to create a
of on-device
beautiful, privacy-focused chat experience

May 31 7 1 Jun 10 4 1

See more recommendations

Help Status About Careers Press Blog Privacy Rules Terms Text to speech

https://emndeniz.medium.com/xcode-build-time-optimization-abee9893e4c8 Page 20 of 20

You might also like