[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-6951":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":20,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":29,"readmeContent":30,"aiSummary":31,"trendingCount":16,"starSnapshotCount":16,"syncStatus":32,"lastSyncTime":33,"discoverSource":34},6951,"Optimizing-Swift-Build-Times","fastred\u002FOptimizing-Swift-Build-Times","fastred","Collection of advice on optimizing compile times of Swift projects.","",null,"Swift",3588,144,131,5,0,3,58.78,"MIT License",false,"master",true,[24,25,26,27,28],"build-time","compile","compile-time","swift","time","2026-06-12 04:00:31","# Optimizing Swift build times\n\nCollection of advice on optimizing compile times of Swift projects.\n\nSwift is constantly improving ❤️. For the time being, though, long compile times persist as a big issue when working on medium-to-large apps. The goal of this project is to gather all there is that can help you shorten your build times.\n\n👷🏻 Maintainer: [Arek Holko](https:\u002F\u002Ftwitter.com\u002Farekholko). Anything missing? **Issues and pull requests welcomed!**\n\n# Table of contents\n\n- [Incremental Compilation Mode with No Optimization](#incremental-compilation-mode-with-no-optimization)\n- [Type checking of functions and expressions](#type-checking-of-functions-and-expressions)\n- [Slowly compiling files](#slowly-compiling-files)\n- [Build active architecture only](#build-active-architecture-only)\n- [dSYM generation](#dsym-generation)\n- [Third-party dependencies](#third-party-dependencies)\n- [Modularization](#modularization)\n- [XIBs](#xibs)\n- [Xcode Schemes](#xcode-schemes)\n- [Use the new Xcode build system](#use-the-new-xcode-build-system)\n- [Showing build times in Xcode](#showing-build-times-in-xcode)\n\n# Incremental Compilation Mode with No Optimization\n\nUntil Xcode 10, it was common to enable [Whole Module Optimization](https:\u002F\u002Fgithub.com\u002Ffastred\u002FOptimizing-Swift-Build-Times\u002Fblob\u002Fce6da1f3a47220259c3924df62f44f06bc45e222\u002FREADME.md#whole-module-optimization) to speed up Debug builds. It was a workaround that's no longer needed in Xcode 10!\n\nCurrently, the recommended setup is to have `Incremental` `Compilation Mode` set for Debug builds and `Whole Module` for Release builds. Also, `No Optimization` should be chosen for `Optimization Level` setting of Debug builds. \n\n\u003Cimg src=\"assets\u002Fcompilation-and-optimization@2x.png\" width=\"551\">\n\n📖 Sources:\n\n- [What's New in Swift – WWDC 2018](https:\u002F\u002Fdeveloper.apple.com\u002Fvideos\u002Fplay\u002Fwwdc2018\u002F401\u002F?time=657)\n\n# Type checking of functions and expressions\n\nSwift build times are slow mostly because of expensive type checking. By default Xcode doesn't show code that's slow to compile. You can instruct it to show slowly compiling functions and expressions, though by adding:\n\n- `-Xfrontend -warn-long-function-bodies=100` (`100` means 100ms here, you should experiment with this value depending on your computer speed and project)\n- `-Xfrontend -warn-long-expression-type-checking=100`\n\nto `Other Swift Flags` in build settings:\n\n\u003Cimg src=\"assets\u002Ftimes@2x.png\" width=\"801\">\n\nBuild again and you should now see warnings like these:\n\n\u003Cimg src=\"assets\u002Fxcode-warning@2x.png\" width=\"801\">\n\nNext step is to address code that Swift compiler has problems with. [John Sundell](https:\u002F\u002Fwww.swiftbysundell.com\u002Fposts\u002Fimproving-swift-compile-times) and [Robert Gummesson](https:\u002F\u002Fmedium.com\u002F@RobertGummesson\u002Fregarding-swift-build-time-optimizations-fc92cdd91e31) are here to help you with that.\n\n📖 Sources:\n\n- [Guarding Against Long Compiles](http:\u002F\u002Fkhanlou.com\u002F2016\u002F12\u002Fguarding-against-long-compiles\u002F)\n- [Measuring Swift compile times in Xcode 9 · Jesse Squires](https:\u002F\u002Fwww.jessesquires.com\u002Fblog\u002Fmeasuring-compile-times-xcode9\u002F)\n- [Improving Swift compile times — Swift by Sundell](https:\u002F\u002Fwww.swiftbysundell.com\u002Fposts\u002Fimproving-swift-compile-times)\n- [Swift build time optimizations — Part 2](https:\u002F\u002Fmedium.com\u002Fswift-programming\u002Fswift-build-time-optimizations-part-2-37b0a7514cbe)\n\n# Slowly compiling files\nThe previous section described working on an expression- and function-level but it’s often interesting to know compile times of whole files too.\n\nThere’s no UI in Xcode for that, though, so you have to build the project from the CLI with correct flags set:\n\n```sh\nxcodebuild -destination 'platform=iOS Simulator,name=iPhone 8' \\\n  -sdk iphonesimulator -project YourProject.xcodeproj \\\n  -scheme YourScheme -configuration Debug \\\n  clean build \\\n  OTHER_SWIFT_FLAGS=\"-driver-time-compilation \\\n    -Xfrontend -debug-time-function-bodies \\\n    -Xfrontend -debug-time-compilation\" | \\\ntee profile.log\n```\n\n(Replace `-project YourProject.xcodeproj` with `-workspace YourProject.xcworkspace` if you use a workspace.)\n\nThen extract the interesting statistics using:\n\n```sh\nawk '\u002FDriver Compilation Time\u002F,\u002FTotal$\u002F { print }' profile.log | \\\n  grep compile | \\\n  cut -c 55- | \\\n  sed -e 's\u002F^ *\u002F\u002F;s\u002F (.*%)  compile \u002F \u002F;s\u002F [^ ]*Bridging-Header.h$\u002F\u002F' | \\\n  sed -e \"s|$(pwd)\u002F||\" | \\\n  sort -rn | \\\n  tee slowest.log\n```\n\nYou’ll end up with `slowest.log` file containing list of all files in the project, along with their compile times. Example:\n\n```\n2.7288 (  0.3%)  {compile: Account.o \u003C= Account.swift }\n2.7221 (  0.3%)  {compile: MessageTag.o \u003C= MessageTag.swift }\n2.7089 (  0.3%)  {compile: EdgeShadowLayer.o \u003C= EdgeShadowLayer.swift }\n2.4605 (  0.3%)  {compile: SlideInPresentationAnimator.o \u003C= SlideInPresentationAnimator.swift }\n```\n\n📖 Sources:\n\n- [Diving into Swift compiler performance](https:\u002F\u002Fkoke.me\u002F2017\u002F03\u002F24\u002Fdiving-into-swift-compiler-performance\u002F)\n\n# Build active architecture only\n\nThis setting is a default but you should double check that it’s correct. Your project should build only active architecture in Debug configuration.\n\n\u003Cimg src=\"assets\u002Factive-arch@2x.png\" width=\"488\">\n\n📖 Sources:\n\n- [What is Build Active Architecture Only](http:\u002F\u002Fsamwize.com\u002F2015\u002F01\u002F14\u002Fwhat-is-build-active-architecture-only\u002F)\n\n# dSYM generation\n\nBy default in new projects, dSYM files aren’t generated at all for Debug builds. However, it’s sometimes useful to have them available when running on a device – to be able to analyze crashes happening without the debugger attached.\n\nRecommended setup:\n\n\u003Cimg src=\"assets\u002Fdsym@2x.png\" width=\"536\">\n\n📖 Sources:\n\n- [Speeding up Development Build Times With Conditional dSYM Generation](http:\u002F\u002Fholko.pl\u002F2016\u002F10\u002F18\u002Fdsym-debug\u002F)\n\n# Third-party dependencies\n\nThere are two ways you can embed third-party dependencies in your projects:\n\n1. as a source that gets compiled each time you perform a clean build of your project (examples: [CocoaPods](https:\u002F\u002Fcocoapods.org), git submodules, copy-pasted code, internal libraries in subprojects that the app target depends on)\n2. as a prebuilt framework\u002Flibrary (examples: [Carthage](https:\u002F\u002Fgithub.com\u002FCarthage\u002FCarthage), static library distributed by a vendor that doesn’t want to provide the source code)\n\nCocoaPods being the most popular [dependency manager](https:\u002F\u002Ftwitter.com\u002Farekholko\u002Fstatus\u002F923989580948402177) for iOS by design leads to longer compile times, as the source code of 3rd-party libraries in most cases gets compiled each time you perform a clean build. In general you shouldn’t have to do that often but in reality, you do (e.g. because of switching branches, Xcode bugs, etc.).\n\nCarthage, even though it’s harder to use, is a better choice if you care about build times. You build external dependencies only when you change something in the dependency list (add a new framework, update a framework to a newer version, etc.). That may take 5 or 15 minutes to complete but you do it a lot less often than building code embedded with CocoaPods. You can even skip those initial minutes using [Rome](https:\u002F\u002Fgithub.com\u002Fblender\u002FRome).\n\n📖 Sources:\n\n- time spent waiting for Xcode to finish builds 😅\n\n# Modularization\nIncremental compilation in Swift isn’t perfect. There are projects where changing one string somewhere causes almost a whole project to get recompiled during an incremental build. It’s something that can be debugged and improved but a good tooling for that isn’t available yet.\n\nTo avoid issues like that, you should consider splitting your app into modules. In iOS, these are either: dynamic frameworks or static libraries (support for Swift was added in Xcode 9).\n\nLet’s say your app target depends on an internal framework called `DatabaseKit`. The main guarantee of this approach is that when you change something in your app project, `DatabaseKit` **won’t** get recompiled during an incremental build.\n\n📖 Sources:\n\n- [Technical Note TN2435 – Embedding Frameworks In An App](https:\u002F\u002Fdeveloper.apple.com\u002Flibrary\u002Fcontent\u002Ftechnotes\u002Ftn2435\u002F_index.html)\n- [uFeatures](https:\u002F\u002Fgithub.com\u002Fmicrofeatures\u002Fguidelines)\n\n# XIBs\nXIBs\u002Fstoryboards vs. code. 🔥 It’s as hot a topic as they go but let’s not discuss it fully here. What’s interesting is that when you change the contents of a file in Interface Builder, only that file gets compiled (to NIB format). On the other hand, Swift compiler may decide to recompile a big part of your project when you change e.g. a single line in a public method in a `UIView` subclass.\n\n📖 Sources:\n\n- [(…) in a large project incremental build is much faster if only a .xib was changed (vs. only a line of Swift UI code)](https:\u002F\u002Ftwitter.com\u002FMichalCiuba\u002Fstatus\u002F925326831074643968)\n\n# Xcode Schemes\nLet’s say we have a common project setup with 3 targets:\n- `App`\n- `AppTests`\n- `AppUITests`\n\nWorking with only one scheme is fine but we can do better. The setup we’ve been using recently consists of three schemes:\n\n### App\nBuilds only the app on cmd-B. Runs only unit tests. Useful for short iterations, e.g. on a UI code, as only the needed code gets built.\n\n\u003Cimg src=\"assets\u002Fapp-scheme@2x.png\" width=\"600\">\n\n### App - Unit Test Flow\nBuilds both the app and unit test target. Runs only unit tests. Useful when working on code related to unit tests, because you find about compile errors in tests immediately after building a project, not even having to run them!\n\nThis scheme is useful when your UI tests take too long to run them often.\n\n\u003Cimg src=\"assets\u002Fapp-unit-test-flow@2x.png\" width=\"600\">\n\n\n### App - All Tests Flow\nBuilds the app and all test targets. Runs all tests. Useful when working on code close to UI which impacts UI tests.\n\n\u003Cimg src=\"assets\u002Fapp-all-tests-flow@2x.png\" width=\"600\">\n\n📖 Sources:\n\n- [All About Schemes](http:\u002F\u002Fpilky.me\u002F17\u002F)\n\n\n# Use the new Xcode build system\nIn Xcode 9 Apple [introduced a new build system](https:\u002F\u002Fdeveloper.apple.com\u002Flibrary\u002Fcontent\u002Freleasenotes\u002FDeveloperTools\u002FRN-Xcode\u002FChapters\u002FIntroduction.html#\u002F\u002Fapple_ref\u002Fdoc\u002Fuid\u002FTP40001051-CH1-SW878). To enable it, go to Workspace or Project Settings from the File menu in Xcode. There you can switch build systems to the new build system.\n\n\u003Cimg src=\"assets\u002Fnew_build_system@2x.png\" width=\"536\">\n\n📖 Sources:\n\n- [Faster Swift Builds with the New Xcode Build System](https:\u002F\u002Fgithub.com\u002Fquellish\u002FXcodeNewBuildSystem)\n\n# Showing build times in Xcode\nFinally, to be able to actually know whether your build times are improving, you should enable showing them in Xcode’s UI. To do that, run this from the command line:\n\n```\n$ defaults write com.apple.dt.Xcode ShowBuildOperationDuration -bool YES\n```\n\nOnce done, after building a project (cmd-B) you should see:\n\n\u003Cimg src=\"assets\u002Ftime@2x.png\" width=\"348\">\n\nI recommend comparing build times under same conditions each time, e.g.\n1. Quit Xcode.\n2. Clear Derived Data (`$ rm -rf ~\u002FLibrary\u002FDeveloper\u002FXcode\u002FDerivedData`).\n3. Open your project in Xcode.\n4. Start a build either immediately after Xcode opens or after indexing phase completes. The first approach seems to be more representative because starting with Xcode 9 building also performs indexing.\n\nAlternatively, you can time builds from the command line:\n\n```\n$ time xcodebuild other params\n```\n\n📖 Sources:\n\n- [How to enable build timing in Xcode? - Stack Overflow](https:\u002F\u002Fstackoverflow.com\u002Fa\u002F2801156\u002F1990236)\n","该项目旨在提供一系列优化Swift项目编译时间的建议。其核心功能包括增量编译模式、类型检查优化、第三方依赖管理及模块化等，通过这些技术手段显著减少中大型应用的构建耗时。特别适合于需要频繁编译调试或面临较长等待时间的Swift开发者使用，在提高开发效率的同时保证了代码质量。",2,"2026-06-11 03:09:50","top_language"]