iT邦幫忙

2026 iThome 鐵人賽

DAY 26
0
Modern Web

一個活了六年的 Vue 2 後台,升級到 Vue 3 的那兩年系列 第 26

Day 26|那四個月我以為是停滯,把四條曲線並排才發現看錯了

  • 分享至 

  • xImage
  •  

模組五|重構期的品質與節奏(Day 22–26)

我在整理開發紀錄的時候,看到一段讓我心裡一沉的曲線。

其中一個新專案,開發量連續四個月掉到近乎停擺,最低的那個月,只剩高峰期的 3%

我的第一反應是:這個專案被放掉了。

然後我把四個 repo(新舊各兩套)的曲線並排放在一起,發現我完全看錯了。

先看那條讓我誤判的曲線

以下是連續八個月的開發量,換算成相對指數(各專案以自己在這段期間的高峰為 100):

觀察期第 N 個月 新專案 A
1 29
2 69
3 19
4 3
5 9
6 5
7 92
8 100

第 3 到第 6 個月,掉到個位數。

如果你只看這一條,結論很明顯:這個專案停了四個月,然後不知為何又活過來。

而「停了四個月」在重構這件事上,通常代表一件事:有人把資源抽走了,而這個專案可能永遠回不來。

把四條並排

然後我把同一段期間的另外三個 repo 也拉出來:

折線圖:四個專案的月度開發量並排,兩個舊系統與兩個新專案,縱軸為相對指數

四條線疊在一起才看得出那個「安靜的四個月」不是意外,它在四個專案上都出現過,只是時間點不同。單看一條線你會以為是團隊懈怠;四條並排之後,形狀本身就是解釋。

第 N 個月 舊系統 A 舊系統 B 新專案 A 新專案 B
1 5 29 29 53
2 33 59 69 100
3 12 100 19 61
4 0 61 3 83
5 2 54 9 20
6 23 34 5 25
7 100 38 92 48
8 96 70 100 60

看第 3 到第 6 個月那四行。

新專案 A 掉到個位數的同時:

  • 新專案 B 是 61、83、20、25,完全沒有停
  • 舊系統 B 是 100、61、54、34,而且在第 3 個月達到整段期間的高峰

也就是說:團隊沒有停工。那四個月,主力在別的地方。

真相:那個專案已經交付了

風箏已經到位,我手上的線鬆下來,不用再一直拉了

拼起來的故事是這樣的:

新專案 A 是第一個被重構的系統。它在更早之前就打出了第一個正式版本(Day 5 講過,第四個月就有了)。

所以在這段觀察期,它已經進入上線後的驗收期。

證據在改動的內容裡:那四個月的改動,幾乎全部是「修復 + 驗收單號」的形狀:沒有新功能、沒有重構,都是使用者回報的問題。

而團隊的主力,早就轉場到新專案 B 去了(Day 5 講過那個接力:第一個專案收斂的那個月,正好是第二個起步的月份)。

所以「停滯」是我用錯的詞。

正確的說法是:那個專案進入了它該有的狀態。

這件事改變了我對「進度」的理解

我彎腰在熄掉的這一堆前撥灰,卻沒有回頭看還在燒的那一堆

一個專案的開發量下降,有兩種完全相反的可能:

現象 可能是 怎麼分辨
開發量掉到谷底 它做完了 改動類型幾乎全是修復;其他專案有在動
開發量掉到谷底 它被放掉了 沒有任何改動;團隊也沒有轉去別的地方

分辨的關鍵不在那條曲線本身,在「同時間別的地方發生了什麼」。

這就是為什麼看單一 repo 會誤判:你缺的不是資料,是對照組。

而我覺得這件事可以推得更遠一點:

重構的成功指標,不是 commit 一直很多,是它能不能安靜下來。

一個永遠很忙的專案,通常代表它永遠有沒做完的部分。

那第二波為什麼會來

第 7、8 個月,新專案 A 從 5 跳回 92、100。

如果按前面的邏輯,「它做完了」那為什麼又忙起來?

答案在同一張表:同一時間,舊系統 A 也從 2 跳到 100。

兩邊同時衝刺。 而這正是 Day 13 講過的那件事:切換前的最後功能對齊。

那段時間在做的是:把所有「新系統有、舊系統沒有」和「兩邊行為不一致」的地方一次補平,好讓最後一批使用者可以切換過去。

所以第二波的性質是下線前的收尾,而不是重構重新啟動。

而在那之後,舊系統就掉到斷崖,然後歸零。

完整的形狀

把整段拼起來,一個大型重構的節奏長這樣:

衝刺 → 首版 → 收斂 → 驗收期(看起來像停滯)
     → 下線前的最後對齊(兩邊同時衝)→ 舊系統歸零 → 維護

我覺得最反直覺的是第四段。因為那一段在數字上長得跟「失敗」一模一樣,但它其實是整個過程裡最健康的一段:

系統上線了、在被使用、問題在收斂、而團隊的注意力已經去做下一件事。

這就是重構該有的樣子。

如果當初是大爆炸式重寫呢

這裡值得停一下,把 Day 5 的伏筆收回來。

Day 5 講過我們沒有選擇 Big Bang Rewrite,而是按業務域一塊一塊搬,讓計畫「隨時可以停」。

現在把那四個月放回去看:

如果當初是大爆炸式重寫,那四個月會發生什麼?

答案是:專案會死。

因為 Big Bang Rewrite 在完成之前,手上永遠是「一個做到一半、不能上線的東西」。當團隊主力被調去做別的事、而這個專案連續四個月只有零星改動:

沒有人會相信它還會完成。 而一旦停下來,重啟的成本會高到讓「乾脆不要做了」變成理性的選擇。

而我們的情況是:那個專案在停下來之前已經上線了。所以那四個月不是風險,是成果在被使用。

一個可以隨時停下來的計畫,才有資格經歷低潮。

那,怎麼衡量重構的進度

如果 commit 數量會誤導,那該看什麼?

我的答案在 Day 13 講過,這裡再確認一次:

看「舊系統還差什麼才能關掉」。

這個指標的好處是它不會被假象欺騙:

  • 新系統做得很快 → 舊系統還是關不掉 → 進度就是沒有推進
  • 新系統很安靜 → 但舊系統的使用者已經全部切走了 → 進度是滿的

而且它天然地把「共存期的成本」算進去了:那段最貴、也最容易被忽略的日子(Day 13)。

代價

一、這個判斷需要多個 repo 的資料。 如果你的重構只有一個專案、沒有對照組,那條曲線的低谷就真的很難解讀。你只能靠記憶,而記憶不可靠(我自己就記錯過那四個月的原因)。

二、「安靜是好事」這句話很容易被濫用。 一個真的被放掉的專案,也很安靜。差別在於「有沒有人在用它」,而那個數字不在 git 裡。所以這個判準不能單獨使用。

三、對外溝通仍然困難。 你很難跟主管解釋「這四個月開發量很低是好事」。比較有效的講法是換一個指標:不要報「這個月做了幾件事」,報「舊系統還剩幾個模組沒切換」。後者在那四個月裡是有進展的(使用者在陸續切換),而前者看起來像停擺。

帶走什麼

  1. 單一專案的開發量曲線會騙人。 你缺的不是資料,是對照組:同一時間別的地方發生了什麼。
  2. 開發量掉到谷底有兩種相反的可能:做完了,或被放掉了。 分辨的方法是看改動的類型(是不是幾乎全是修復)和團隊的去向。
  3. 重構的成功指標不是 commit 一直很多,是它能不能安靜下來。 一個永遠很忙的專案,通常是永遠沒做完。
  4. 一個可以隨時停下來的計畫,才有資格經歷低潮。 這是分期交付真正的價值,不是進度好看,是低潮不會致命。
  5. 用「舊系統還差什麼才能關掉」衡量進度。 它不會被「新系統做得很快」這種假象欺騙。

模組五到這裡結束。這五天講的與其說是「怎麼寫程式」,更像是重構這件事在時間軸上長什麼樣:為什麼一直在修 bug、最好的改動是刪掉一萬行、有些醜東西不能改、以及看起來停滯的那四個月。

明天開始模組六,最後四天。Day 27 講一個問題:人會離職、記憶會消失,怎麼讓「為什麼這樣做」留下來?


上一篇
Day 25|有一個欄位名拼錯了,而我們決定不改
下一篇
Day 27|Day 3 那三行被註解掉的程式碼,沒有人知道為什麼
系列文
一個活了六年的 Vue 2 後台,升級到 Vue 3 的那兩年30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言