Xcode 26 編譯太慢:2026 遠端 Mac 怎麼加速?

Xcode 26 編譯太慢:2026 遠端 Mac 怎麼加速?

Xcode 26 編譯太慢時,先用建置計時資料定位瓶頸,再修改專案,最後才評估硬體。Apple 的文件將建置效率、測試組織、Swift Package 持續整合分開處理;因此一次建置應至少拆成 四類紀錄:增量建置、乾淨建置、Archive 與測試,而不是只看總耗時。刪除 DerivedData 或直接租用更高規格的遠端 Mac,都不應是未診斷前的固定答案。

這篇文章適合每天多次執行增量編譯、希望縮短「修改程式碼到看到結果」時間的獨立開發者。
也適合需要在遠端 Mac 執行 Release Archive、自動測試或持續整合,卻尚未確定問題是否真的來自硬體的小型團隊。

先建立可比較的建置基線

同一個專案在不同條件下得出的時間,不能直接互相比較。首次建置可能包含 Swift Package 下載與解析;遠端工作又可能受到原始碼同步、私有套件驗證或磁碟狀態影響。測量前應固定以下輸入:

  • 相同的程式碼提交版本。
  • 相同的 Scheme、Build Configuration 與目標裝置。
  • 相同的相依套件版本與 Package.resolved
  • 相同的簽署設定,以及是否啟用腳本。
  • 相同的測試範圍與模擬器設定。

Apple 的 增量建置效能說明可用來核對建置系統與程式碼變更的關係。Xcode 26 的版本行為與已修正問題,則應直接查看 Xcode 26 Release Notes,不要把社群分享的加速比例當成官方保證。

在 Xcode 中開啟 Build Timing Summary,記錄最慢的 Swift 檔案、Target、腳本與資源處理工作。若需要在自動化環境重現,可先使用明顯的佔位名稱:

xcodebuild \
  -workspace <WORKSPACE_PATH> \
  -scheme <SCHEME_NAME> \
  -configuration <BUILD_CONFIGURATION> \
  -destination '<DESTINATION_SPECIFIER>' \
  build

輸出範例只用來說明閱讀方式:

CompileSwiftSources <TARGET_NAME>
PhaseScriptExecution <SCRIPT_NAME>
Ld <PRODUCT_NAME>
ProcessInfoPlistFile <RESOURCE_PATH>

看到 CompileSwiftSources 很慢,才適合進入 Swift 程式碼與 Target 依賴分析。若最慢的是 PhaseScriptExecution,換晶片通常不會解決腳本重複執行。若輸出先長時間停在套件下載,這是依賴或網路問題,不是源碼編譯問題。

工作場景 應記錄的階段 首要檢查方向 不宜先做的事
日常增量建置 受影響 Target、Swift 檔案、腳本 Target 依賴、符號可見性、程式碼生成 反覆刪除 DerivedData
乾淨建置 套件準備、源碼編譯、連結 相依性是否完整、快取是否可重建 把首次下載算成編譯時間
Release Archive 編譯、連結、資源、簽署、腳本 Release 設定、額外 Target、符號處理 只看 Archive 總時間
測試與模擬器 App 編譯、模擬器啟動、測試案例 測試分組、並行度、記憶體壓力 無限制增加測試工作數

增量建置:專案側修正優先於硬體

日常編輯最在意的是增量建置。一次小修改若觸發大量無關 Target,問題多半在依賴圖,而不是遠端 Mac 的 CPU。先檢查新增 Target 是否真的需要依賴完整模組,也要確認共用程式碼是否被過度暴露,導致不必要的檔案重新編譯。

Apple 的 Target 設定文件可用於核對 Target 與建置產品的關係。對 Swift 程式碼,亦可參考 改善建置效率的程式碼實踐,再以同一提交版本的計時結果驗證修改是否有效。

建議先做一個小範圍變更,例如只改動一個畫面或一個模組,然後比較修改前後的相同增量建置。若每次都同時執行程式碼生成、資源索引與多個無關 Target,應逐項確認:

  • 自訂腳本是否缺少輸入與輸出檔案宣告。
  • 程式碼生成是否每次建置都重新執行。
  • 某個大型模組是否被過多 Target 直接引用。
  • 小型變更是否造成整個共用檔案集合重新編譯。
  • Debug Scheme 是否無意間啟用了發佈階段才需要的工作。

Build Timing Summary 要怎樣查看每個建置工作的耗時?
在 Xcode 的建置報告中查看 Build Timing Summary,先按耗時排序,再追蹤最慢項目所屬的 Target 與建置階段。自動化建置則保留 xcodebuild 的完整輸出,將相同提交、Scheme 與設定的結果並列。重點不是取得一個漂亮的總時間,而是找出每次都重複出現的長任務。

DerivedData 不應被當成加速按鈕。它保存中間產物與索引,正常情況下有助於增量建置;刪除後通常需要重新產生這些內容。只有快取損壞、索引狀態異常,或切換工具鏈後出現無法解釋的錯誤,才值得清除並重新建立基線。

提醒: 如果刪除 DerivedData 後只有下一次建置變慢,這不是最佳化失敗,而是把可重用的中間產物一併移除了。應比較後續同類增量建置,不要比較清除後的首次結果。

Release Archive:把總時間拆開看

Archive 慢,與日常編譯慢,可能是兩個不同問題。Release Archive 應分別記錄相依套件準備、源碼編譯、連結、資源處理、簽署、符號檔處理與自訂腳本。Apple 的 Beta 與正式版本分發說明可用來核對分發流程,不過其中的簽署與上傳工作不能簡化成「編譯」。

若 Debug 增量建置正常,只有 Release Archive 明顯變慢,應先檢查:

  • Release 是否啟用不同的最佳化與符號設定。
  • Archive 是否額外包含 Extension、Widget 或其他 Target。
  • 符號處理、資源壓縮與腳本是否集中在最後階段。
  • 發佈腳本是否重複下載工具或重新處理相同檔案。
  • 簽署憑證與 Provisioning Profile 是否需要重新尋找或驗證。
計時結果 較可能的瓶頸 建議決策
增量建置與 Archive 都慢在源碼編譯 程式碼結構或 CPU 持續飽和 先拆分模組;確認後再評估更高 CPU 配置
增量建置正常,Archive 慢在腳本或符號處理 發佈流程工作重複 修正腳本輸入、輸出與工具快取
Archive 前長時間下載套件 依賴解析、下載或認證 固定版本並檢查套件來源,暫不升級硬體
編譯完成後連結或磁碟等待突出 產物規模或儲存裝置瓶頸 檢查產物與磁碟狀態,再決定是否擴容
總時間主要消耗在測試 測試案例、模擬器或並行設定 分開測試計時,不要把問題稱為編譯慢

依賴恢復:固定輸入,避免把下載當成編譯

新租期、持續整合節點或新開發機第一次執行時,Swift Package 常會同時涉及版本解析、套件下載與源碼編譯。三者要分開記錄。若 Package.resolved 沒有提交到版本控制,團隊每次恢復環境都可能得到不同的解析結果,後續時間也失去可比性。

Swift Package 每次重新解析依賴,應怎樣處理?
先確認 Package.resolved 是否已提交,並核對工作區與專案實際使用的套件版本。再區分是解析失敗、下載緩慢,還是下載完成後編譯緩慢。私有套件則要另外檢查 SSH 金鑰、存取權杖、憑證與網路路由。Apple 的 Swift Package 持續整合工作流程文件可作為 CI 環境的核對依據。

快取也要有邊界。套件下載快取可以保留,但不能用一份無法追蹤來源的舊建置產物掩蓋原始碼變更。需要從源碼重建的產物,必須在乾淨 Archive 或指定的 CI 驗收中重新確認。遠端 Mac 上的首次建置時間,應獨立標記為環境恢復成本。

測試並行:速度與失敗率一起判斷

測試總時間不等於 Xcode 編譯時間。單元測試可能主要消耗在測試案例;UI 測試還會涉及模擬器啟動、狀態準備與裝置互動。Apple 的 模擬器與實體裝置執行說明以及改善回饋速度的測試組織文件,都應與實際測試輸出一併核對。

Xcode 測試並行度越高,是否一定越快?
不一定。並行測試會增加模擬器、CPU 與記憶體的同時需求;當主機開始出現記憶體壓力、交換或磁碟等待時,總完成時間可能反而拉長,失敗重試也會增加。應使用低、中、高三組明確的工作數設定逐級比較,並同時記錄完成時間、失敗數與模擬器穩定性,而不是只取最快的一次。

對獨立開發者,快速回饋與發佈前驗證應分層:

  • 快速回饋:只跑受影響模組的單元測試與必要的模擬器測試。
  • 合併前驗證:跑完整單元測試,確認測試資料與環境隔離。
  • Archive 前驗證:加入 Release 設定、簽署與必要的 UI 測試。
  • 發佈前驗證:在固定的遠端 Mac 節點重跑完整流程,保留輸出與失敗原因。

遠端建置:先驗收工作負載,再決定擴容

遠端 Mac 的價值不只在編譯速度,也在於能否穩定執行 Archive、測試與持續整合。若本地機在建置時被長時間佔用,遠端節點可以把發佈工作拆出去;但遠端連線延遲、原始碼同步、套件來源與權限設定,仍需納入驗收。

可先用同一個脫敏提交執行以下流程:

xcodebuild \
  -workspace <WORKSPACE_PATH> \
  -scheme <SCHEME_NAME> \
  -configuration <DEBUG_CONFIGURATION> \
  -destination '<SIMULATOR_DESTINATION>' \
  test
xcodebuild \
  -workspace <WORKSPACE_PATH> \
  -scheme <SCHEME_NAME> \
  -configuration <RELEASE_CONFIGURATION> \
  -archivePath <ARCHIVE_PATH> \
  archive

連續執行時,觀察是否出現以下差異:

  • CPU 長時間飽和,但依賴已完成下載。
  • 記憶體壓力持續升高,測試並行後失敗變多。
  • 磁碟等待明顯,連結、索引或產物處理成為長項目。
  • 遠端工作階段本身影響互動,但非互動式 CI 建置仍然穩定。
  • 每次都重新解析或下載相同套件。
  • 增量建置改善,但乾淨 Archive 沒有改善。

  • [ ] 固定程式碼提交、Scheme、設定與目標裝置。

  • [ ] 分開保存增量建置、乾淨 Archive、測試與依賴恢復紀錄。
  • [ ] 在 Build Timing Summary 找出反覆出現的長任務。
  • [ ] 檢查 Target 依賴、程式碼生成與自訂腳本輸入輸出。
  • [ ] 確認 Package.resolved 已提交,並測試私有套件認證。
  • [ ] 逐級調整測試並行度,同時記錄總時間與失敗率。
  • [ ] 只有在 CPU、記憶體或磁碟等待持續成為主因時,才比較遠端 Mac 配置。
  • [ ] 用同一提交重跑驗收,確認改善可重現,而非單次偶然結果。

遠端 Mac 編譯慢,應升級晶片還是增加記憶體?
先看計時與系統資源的對應關係。源碼編譯長時間受 CPU 限制,才有理由比較更高效能的晶片;測試並行、索引或多個 Target 同時工作造成記憶體壓力,才考慮增加記憶體。若主要時間花在套件下載、腳本或錯誤的依賴關係,兩者都不是正確修復方向。

若經過上述驗收,本地仍會被增量編譯反覆佔用,而 Release Archive、測試與 CI 又需要穩定常駐環境,遠端 Mac 才具備明確的成本理由。此時可先參考 SFTPMAC 的 Mac 租用方案,再用實際專案而非規格表選擇配置;若需要特定地區的連線路徑,也可查看香港 Mac 租用環境

本地方案與遠端 Mac 的取捨

如果目前方案是把所有工作放在一台本地 Mac,常見缺點是建置時佔用開發機、磁碟快取與模擬器互相爭用資源,團隊也缺少一台可長時間執行 Archive 與 CI 的固定節點。若改用一般雲端環境,則可能遇到無法直接執行 Xcode 的限制;若只靠臨時借用實機,版本、憑證與工作狀態又不容易固定。

在瓶頸已被確認的前提下,租用 SFTPMAC 的遠端 Mac 可把同一個專案部署到可持續使用的 macOS 環境,讓開發者分開處理日常編碼與建置、簽署、測試工作。若工作只是偶爾 Archive,短期租用較合理;若每天都有固定 CI 負載,才值得用較長租期驗證成本。需要實體 USB、長期滿載且必須完全自行維護硬體的人,則應如實比較自購 Mac,而不是為了「編譯太慢」盲目搬遷。

核心判斷很簡單:先證明瓶頸在哪裡,再決定修專案、調整測試,或擴充遠端 Mac。這樣才能避免清空 DerivedData 後反覆失去快取,也避免在真正的套件、腳本或 Target 問題尚未處理前,支付不必要的硬體成本。