33MB 這個數字先被算出來了:一個 Tauri 版桌面應用的體積設計
從一則未被合併的 PR 與 33MB 安裝包看起,觀察掘金 AI 用量統計 Tauri 版如何在體積、資料層與維護成本之間做出設計取捨。
科技 設計評論 約 4 分鐘閱讀
2026 年 10 月 25 日,掘金上出現一篇標題直白的文章:「PR 沒被合併,我把 Tauri 版自己做出來了:安裝包從 100MB 砍到 33MB」。作者「雨夜尋晴天」交代了一件拖欠兩個月的作業:把掘金 AI 用量統計工具重做成 Tauri 版,獨立維護,macOS 安裝包 33MB,功能對齊官方的 Electron 版。
先看這個案子最有意思的一個設計決策:資料層一根手指都沒碰。
殼與引擎,先分清楚
掘金 AI 用量統計這個工具,本業是記錄 Claude Code、Codex、Cursor 等三十多個 AI 工具的 Token 消耗。難的地方從來不是視窗和按鈕,是資料層:每家工具把用量藏在不同的位置、用不同的格式,官方維護了一大堆解析器,還得跟著工具更新一直修。
作者的架構用一句話講完:官方 core 原樣包進來當引擎,Tauri 只做殼。這個取捨的回報很具體:官方這段時間新增了 6 個數據源,他這邊合併上遊之後,一個解析器都沒寫,功能自動跟上;官方修 bug,他也一併受益。
代價也講得誠實:官方 core 是 Node 寫的,為了跑它,安裝包裡得內嵌一個 Node 執行時。所以那個 Rust 殼其實只有 10MB,剩下的大頭是 Node。這種把成本結構攤開來講的寫法,比單純曬體積數字更有說服力。
體積是被一口一口咬下來的
從 44MB 磨到 33MB 的過程,讀起來像一份減法清單。第一步是掃目錄:把打包產物攤開,發現 hono 的 TypeScript 型別宣告(執行期根本不讀)、CJS 重複建構、yaml 的瀏覽器版本都被打了進去,先剝掉一層。
第二步動大頭:內嵌的 node 二進位檔有 110MB,其中 30MB 是全量 ICU 多語言庫。一個跑在本機、只處理日期格式的 sidecar,帶著全套世界語言,確實浪費。換成 small-icu 版的 node 聽起來簡單,但有坑:程式裡有 4 處日期格式化用了 en-CA、en-GB locale,小 ICU 下格式會變,日期一變,資料分桶就跟著亂。
幸運的是檢查之後發現這 4 處全部用的是 formatToParts 寫法,按欄位取值再自己拼,天生跟 locale 無關。最後一步是對照實驗:同一個日期、同一個時區,官方 node 和 small-icu node 的輸出逐位元組一致;再跑 516 個測試案例,兩邊結果一模一樣。
這段敘述值得留意的地方在於驗證方法。很多人會停在「換了更小的依賴,變小了」,作者做到的是證明「換了之後行為沒變」。逐位元組比對輸出、跑完整測試集,這是把體積最佳化當成工程問題而非信仰問題的態度,跟DeckCraft 用純 Rust 做簡報編輯器時對格式忠實度的計較,是同一種誠實。
那個沒被合併的 PR
回到起點。作者 9 月給官方提了 PR,把桌面端做成 Tauri 版,結果沒被合併。他對官方決定的理解寫得很清楚:桌面端是多端共享的產品,為了一個社羣貢獻再養一套 UI 框架,建構、測試、維護全是雙倍成本。換成他是維護者,大概也是先說「謝謝,再看看」。
這裡的取捨其實是介面設計裡的老問題:一個產品願意為了效能,多背一套技術棧嗎?官方選了維護成本,社羣選了體積,兩邊都有道理,差別只在誰付帳。Tauri 版的答案是把維護成本留給自己,用「官方 core 當引擎」的架構把重複勞動壓到最低,讓這筆帳算得下去。
功能面上,Tauri 版有完整面板、12 個渠道的訂閱額度卡、桌面寵物(三隻內建加社羣目錄下載,同步完會冒氣泡回報 Token 增量)、macOS 選單列即時用量,以及掘金登入深鏈與自動更新。與其說是功能對齊,不如說是同一套資料層換了一個更薄的殼之後,該有的東西都還在。
這個案子最後留下的觀察是:33MB 不是 Rust 的魔法,而是三個務實決策疊出來的結果。不重寫資料層,讓上遊替自己打工;掃掉打包裡的死重;換小的 ICU 之前先證明行為不變。全 Rust 化的 1.0、15MB 以內的目標排在後面,到時候能不能守住「資料分桶不亂」這條底線,才是這個瘦身故事真正的下一章。