上工第一週就減少團隊專案編譯時間 90% 的故事

更新 發佈閱讀 9 分鐘

上篇提到開始了新的工作,這週來稍微聊聊這兩週工作上的一些新奇發現。

沒錯,又是金融業(怎麼台灣好多金融相關的 iOS 工作??)。


上班首日

到職第一天,在 Mac 上建置好開發環境後,主管給我的第一個任務就是熟悉程式碼和文件。他遞給我一本 Uncle Bob 的《Clean Architecture》(聽說是客戶送的),並且知道我是有經驗的開發者,問我能不能也看看專案的 build time。

於是,我從 Git clone 了專案,打開 Xcode workspace,按下 Command+B 開始建置。

然後我等啊等,又在等啊等啊等...

整整八分鐘後,終於完成了。我真是驚呆了。

這意味著同事們把一天中相當長的時間都花在等待 building 上。我的天啊!難怪會叫我看一下!

我打算開始好好分析這個專案。

調查過程

這是一個 legacy Objective-C App,有著:

  • 超過 5,000 個檔案
  • 大約 5% 的 Swift 程式碼
  • 用 CocoaPods 管理套件,不是 SPM
  • 專案的 build time 為 8 分鐘起跳
  • 產出 SDK(.a 檔案)需要超過 30 分鐘
  • 用完所有可用的 Application memory 是家常便飯

我的 Debug 之旅經歷了幾個階段:

1:分析工具

首先,我找了幾個以前用過的工具,嘗試看看能不能有什麼發現:

不幸的是,這些工具都沒有指出長時間建置的明確元兇。

2:清理 低使用率/低依賴/老舊 的第三方套件

我的下一個想法是移除由 CocoaPods 管理的舊的和不常使用的第三方相依性。然而,這需要大量的重構和廣泛的驗證,使其成為一個高風險、耗時的任務。

3:使用 SPM 現代化

我也考慮將專案遷移到 Swift Package Manager (SPM) 並將其拆分為更小的模組化 libraries。這種方法遇到了兩個主要障礙:

  • 程式碼是 Swift 和 Objective-C 的混合,但 SPM 在單一 target 內只能使用單一語言,使得轉換變得複雜
  • 我也嘗試製作了一個暫時性的 Package 來測試,但在將它整合到專案,打包成SDK之後,發生了 duplicate symbol 的 error。搜尋了一下解決辦法,看起來這是靜態 library 一直以來跟 SPM 整合的問題,存在 Xcode 中已數年時間都未修復,暫時也只先放棄。

4:深入研究 Build Script

由於最初的嘗試都沒有結果,我轉向研究 SDK build script。

當我嘗試切換到 aggregate target 並 Clean build 來匯出 SDK 時,失敗了。

我很困惑。我問其他同事,他們告訴我必須分別先切換到「Any iOS Device」和「Any iOS Simulator」build library,然後才能 build aggregate target。我簡直不敢相信,這是正常的嗎?

開始深入研究 build log errors,我看到與 CocoaPods 相關的「modulemap not found」錯誤。讓我回頭檢查了 build script 本身,我發現了罪魁禍首:script 使用 xcodebuild 搭配 -target 參數,直接指向 .xcodeproj 檔案,儘管專案是用 .xcworkspace 設置的。這就是為什麼 clean build之後會失敗,以及為什麼其他人需要先各 build 一次模擬器和實機才可以。(這樣加上 script 總共會 build 4 次啊!!!!!)

我修正了 script,改用 -workspace 和 -scheme 參數。立即地,aggregate target clean build 成功了。這個改動將流程簡化為只需按下一次 Command + B,將 SDK 匯出時間縮短了一半!

新的謎團:Runtime Crash

但接下來又遇到了一個新問題:我的新 script 產生的 SDK,會造成 runtime crash,而那個舊的、慢的 script 產生的卻不會。

我又困惑了,我 revert 了 script 的變更,用原本的方式產出 SDK。經過又一次漫長的等待,終於完成了。「現在應該不會 crash 了吧?我把所有東西都 revert 了耶?」,我天真的想。

但沒錯,不出意外就是得出意外,它在 runtime 時仍然會 crash。然而,當我測試最一開始就在專案裡的原始 SDK 檔案時,它看起來完全沒問題。謎團加深了。

我嘗試問同事們都如何產生 SDK。他們跟我說了 Jenkins server 的位置,通常都會用 Jenkins 包版。

我取得了存取權限,並直接在 Jenkins 機器上執行我新的 script。.....很好,產生的 SDK 工作得很完美——沒有 crash。

答案一定在 Jenkins logs 中。我嘗試打開 job history,但網頁一直在載入,載入到 Safari 當機。我嘗試 reload page,出現了 log 的介面,但是在一半的地方就斷掉了。在有顯示的部分中,我發現了關鍵線索:Jenkins server 執行的是 Xcode 14.3,而我本機是 Xcode 16.3。

經過幾次測試,我確認了:Xcode 版本就是原因。新版本的 Xcode 對 Objective-C 有更嚴格的行為,這導致了 crash。專案的 code 需要更新來符合規範。我做了一點點小修正,嘗試用新的 script 產出 SDK。成功啦!不再有 runtime crash!!!!!

到這邊為止,已經是我新工作的第四天結束,主要是因為 build time 太長太痛苦。每做一個小 change,都需要長時間等待才能驗證是否有效。

最終突破

即便 SDK script 修好了,專案的 8 分鐘 build time 仍然是個大問題。

我回到那個 Jenkins log。由於 Safari 無法完整顯示它,我決定試試看下載下來。「只是一個 log 文字檔案,應該幾秒鐘就好了」,我是這樣想的。但我等了... 又等了。將近六分鐘後,下載終於完成了。

我打開下載資料夾中,找到下載的檔案。**它的大小是 5.63 GB。蛤!?**一個 5.63 GB 的 build log!?

這一看就不正常。我問了 Claude:「這個 Jenkins build log 有 5.63 GB,這會是造成 build time 太久的可能原因嗎?」它給了我肯定的答案。

接著我問它減少 log 輸出的 build settings,它給了我幾個設定的選項嘗試。

我修改了專案設定,按下 Command + B 然後觀察。結果!僅僅 63 秒就完成了!

我找了其他同事,在他們的電腦上也修改了這些設定,同樣達成了這令人難以置信的改善。我們找到了暫時將 build time 減少超過 90% 的方法,提高了全體團隊成員的工作效率,而這一切,都發生在我上工的第一個禮拜。

暫時解決方案與長期目標

有些人應該會說:「啊你沒有修正 warnings,你只是隱藏了它們而已啊。」這樣說是沒錯。

然而,當一個專案有超過 2,500 個被忽略多年的 warnings 時,warnings 本身就成了問題,就算出現了任何新的、重要的 warning,也沒有人會發現。

在我自己的 side projects 中,我嚴重的潔癖讓我能保持 0 warning policy,因為我知道它們有多重要。如果你持續忽略它們,有一天你的專案,必然會變成怪獸反過來吃掉你。

這就是為什麼我稱這為暫時解決方案。為了立即提升整個團隊的生產力,這是最有效的第一步,況且我也沒說我們決定就這樣一直隱藏他們下去。

因此,長期目標是系統性地檢視 legacy 程式碼,修正根本問題,讓 app 更穩定、提高效率。我希望能和團隊夥伴一起開始逐一消除這些 warnings。即使一天只修正一個 warning,也是很棒的進步。

你也有類似的經驗嗎,或者對這種情況有更好的解決方案嗎?留言讓我知道!

那本週分享先到這邊,下次見!

留言
avatar-img
留言分享你的想法!
avatar-img
Rice把拔的生活與開發筆記
0會員
25內容數
這裡是我的開發與生活筆記。 分享iOS開發經驗、教學技巧,也記錄生活中的點滴與觀察。 偶爾來點評論,輕鬆聊聊技術與日常。
2025/07/31
SF Symbols 的出現,為我們提供了一套共享的「視覺語言」。降低了對設計方面的溝通成本,並提高了設計的一致性。
Thumbnail
2025/07/31
SF Symbols 的出現,為我們提供了一套共享的「視覺語言」。降低了對設計方面的溝通成本,並提高了設計的一致性。
Thumbnail
2025/07/16
Swift Forums 宣布 Android Workgroup 的計畫後,對 Mobile App Development 生態造成了什麼樣的變化?
Thumbnail
2025/07/16
Swift Forums 宣布 Android Workgroup 的計畫後,對 Mobile App Development 生態造成了什麼樣的變化?
Thumbnail
2025/07/09
介紹 Apple 原生的 Swift Package Manager,了解基本架構與特性。
Thumbnail
2025/07/09
介紹 Apple 原生的 Swift Package Manager,了解基本架構與特性。
Thumbnail
看更多
你可能也想看
Thumbnail
透過蝦皮分潤計畫,輕鬆賺取零用金!本文分享5-6月實測心得,包含數據流程、實際收入、平臺優點及注意事項,並推薦高分潤商品,教你如何運用空閒時間創造被動收入。
Thumbnail
透過蝦皮分潤計畫,輕鬆賺取零用金!本文分享5-6月實測心得,包含數據流程、實際收入、平臺優點及注意事項,並推薦高分潤商品,教你如何運用空閒時間創造被動收入。
Thumbnail
單身的人有些會養寵物,而我養植物。畢竟寵物離世會傷心,植物沒養好再接再厲就好了~(笑)
Thumbnail
單身的人有些會養寵物,而我養植物。畢竟寵物離世會傷心,植物沒養好再接再厲就好了~(笑)
Thumbnail
不知你有沒有過這種經驗?衛生紙只剩最後一包、洗衣精倒不出來,或電池突然沒電。這次一次補貨,從電池、衛生紙到洗衣精,還順便分享使用心得。更棒的是,搭配蝦皮分潤計畫,愛用品不僅自己用得安心,分享給朋友還能賺回饋。立即使用推薦碼 X5Q344E,輕鬆上手,隨時隨地賺取分潤!
Thumbnail
不知你有沒有過這種經驗?衛生紙只剩最後一包、洗衣精倒不出來,或電池突然沒電。這次一次補貨,從電池、衛生紙到洗衣精,還順便分享使用心得。更棒的是,搭配蝦皮分潤計畫,愛用品不僅自己用得安心,分享給朋友還能賺回饋。立即使用推薦碼 X5Q344E,輕鬆上手,隨時隨地賺取分潤!
Thumbnail
身為一個典型的社畜,上班時間被會議、進度、KPI 塞得滿滿,下班後只想要找一個能夠安靜喘口氣的小角落。對我來說,畫畫就是那個屬於自己的小樹洞。無論是胡亂塗鴉,還是慢慢描繪喜歡的插畫人物,那個專注在筆觸和色彩的過程,就像在幫心靈按摩一樣,讓緊繃的神經慢慢鬆開。
Thumbnail
身為一個典型的社畜,上班時間被會議、進度、KPI 塞得滿滿,下班後只想要找一個能夠安靜喘口氣的小角落。對我來說,畫畫就是那個屬於自己的小樹洞。無論是胡亂塗鴉,還是慢慢描繪喜歡的插畫人物,那個專注在筆觸和色彩的過程,就像在幫心靈按摩一樣,讓緊繃的神經慢慢鬆開。
Thumbnail
最近遇到一個難題。   到新公司已經二個月,以邏輯來說我算是新人,但以系統軟體來說算是有一定的概念及觀念,而公司是新公司,同事幾乎都是新進或是年紀很輕的工程師。   而最資深的工程師是一位很年輕的弟弟先稱他為Jack,他進公司二年了,再來是一位APP工程師及UI/UX工程師也待超過一年,而其
Thumbnail
最近遇到一個難題。   到新公司已經二個月,以邏輯來說我算是新人,但以系統軟體來說算是有一定的概念及觀念,而公司是新公司,同事幾乎都是新進或是年紀很輕的工程師。   而最資深的工程師是一位很年輕的弟弟先稱他為Jack,他進公司二年了,再來是一位APP工程師及UI/UX工程師也待超過一年,而其
Thumbnail
社畜簽了合約的日子 這幾天真的是在倒時差的感覺…以前工作十分鐘就到公司。現在早起兩個小時就是給了交通……
Thumbnail
社畜簽了合約的日子 這幾天真的是在倒時差的感覺…以前工作十分鐘就到公司。現在早起兩個小時就是給了交通……
Thumbnail
這是我的第一週! 第一週實習生活結束啦,過程中獲得了很多機會與挑戰,像是我這一週協助 HRBP 進行履歷撈選,下一週也要開始跟著企業面試求職者的流程,除此之外也有其他像是教育訓練、實習生計畫的內容在運作,這次的暑期實習應該會是一個很豐富的體驗!之後再詳細跟大家介紹我的工作內容。
Thumbnail
這是我的第一週! 第一週實習生活結束啦,過程中獲得了很多機會與挑戰,像是我這一週協助 HRBP 進行履歷撈選,下一週也要開始跟著企業面試求職者的流程,除此之外也有其他像是教育訓練、實習生計畫的內容在運作,這次的暑期實習應該會是一個很豐富的體驗!之後再詳細跟大家介紹我的工作內容。
Thumbnail
今天要說的是我在前公司砸鍋的故事。 前公司是軟體公司,我在那邊擔任前端工程師,負責維護公司後台網頁的介面跟資料串接。 先交代一下故事背景:
Thumbnail
今天要說的是我在前公司砸鍋的故事。 前公司是軟體公司,我在那邊擔任前端工程師,負責維護公司後台網頁的介面跟資料串接。 先交代一下故事背景:
Thumbnail
從母語使用者到專利工程師,這篇文章分享了作者從事新工作的體驗和感受。包括工作內容、困難和情緒波動。作者深入探討了作為專利工程師可能遇到的挑戰,並呈現對工作的認真與努力。
Thumbnail
從母語使用者到專利工程師,這篇文章分享了作者從事新工作的體驗和感受。包括工作內容、困難和情緒波動。作者深入探討了作為專利工程師可能遇到的挑戰,並呈現對工作的認真與努力。
Thumbnail
第一次開始接案後,隔天就接到了一個專案。看似報酬相當豐厚,但專案功能並不簡單,大概相當於我在公司上班一年的工作量,而且交期也很緊迫。這是一個基於ASP.NET的專案。 專案上線後,開始了噩夢般的日子。好壞參半,剛開始熟悉整個系統的時候真的是最艱難的階段,有一種回到初心的感覺。之前用過前端框架,現在
Thumbnail
第一次開始接案後,隔天就接到了一個專案。看似報酬相當豐厚,但專案功能並不簡單,大概相當於我在公司上班一年的工作量,而且交期也很緊迫。這是一個基於ASP.NET的專案。 專案上線後,開始了噩夢般的日子。好壞參半,剛開始熟悉整個系統的時候真的是最艱難的階段,有一種回到初心的感覺。之前用過前端框架,現在
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News