效能指南
本頁記錄 Mindwtr(桌面版、行動版與核心)的實用效能模式。
高影響範圍
- 大型清單的篩選與排序
- 專案/任務排序更新
- 同步合併與附件核對
- 過於寬泛的儲存區訂閱造成重複轉譯
- SQLite 查詢模式(搜尋、日期篩選、專案/狀態檢視)
介面轉譯指引
- 優先使用範圍精確的儲存區選擇器,避免選取完整儲存區物件。
- 將相關選擇器分組,並記憶化衍生集合。
- 保持項目元件純粹;將耗費資源的轉換上移至清單層級記憶化。
- 大型清單使用虛擬化,並避免在熱路徑中動態重新計算高度。
- 避免在大型對應清單中建立新的行內回呼/物件。
目前桌面版清單列依賴記憶化的 TaskItem 轉譯,因此變更清單、專案、議程、行事曆或回顧檢視時,請維持任務列 props 穩定。若檢視需要額外的逐列中繼資料,請在清單層級一次衍生,不要在每列轉譯時建立新物件。
轉譯最佳化操作手冊
畫面反應緩慢時,請依下列順序處理:
- 先確認清單項目的轉譯次數(React DevTools profiler)。
- 將靜態常數/樣式提升至轉譯函式之外。
- 使用
React.memo記憶化繁重的子元件,並視需要明確比較 props 是否相等。 - 依職責(標頭/表單/清單/互動視窗)拆分大型元件,使狀態更新維持局部。
- 以較小的記憶化選擇器/輔助函式取代寬泛的相依陣列。
桌面版專案清單虛擬化
- 對共用主要工作區捲動容器的大型桌面任務清單使用
@tanstack/react-virtual。 - 列鍵值應以任務 ID 為基礎;對可編輯、選取、移動或重新排序的任務列,絕不可使用索引。
- 任務卡片高度可變時,請測量虛擬列,並採用保守的預估列高以免捲動跳動。
- 對現有可排序列元件進行虛擬化,不要換成另一套列介面,以保留拖曳/重新排序語意。
- 避免專案區段內出現巢狀捲動容器。若虛擬清單位於專案中繼資料或區段標頭下方,請以捲動邊距計入清單位移。
- 為大型清單迴歸加入有界轉譯次數測試。測試應證明掛載列數接近可見視窗加上過度掃描範圍,而不是完整任務數量。
FlatList/虛擬化調校(行動版)
- 依畫面需求明確設定
initialNumToRender、maxToRenderPerBatch、windowSize。 - 可行時提供
getItemLayout(固定值或測量後的備援值)。 - 對較大型清單啟用
removeClippedSubviews。 - 維持
keyExtractor穩定,避免使用索引鍵值。 - 在深層巢狀項目樹狀結構中避免行內匿名轉譯器。
一般任務畫面維持使用 FlatList。若任務清單嵌入既有 ScrollView,請使用含間隔列的手動可見視窗切片,不要再巢狀加入另一個垂直虛擬化清單,讓滑動、下拉、鍵盤與拖曳手勢共用單一捲動擁有者。 行事曆專用規則:虛擬化無界的結果集,而不是固定的行事曆骨架。行動版排程檢視會隨每個可見任務/事件增長,應維持使用 FlatList;日與週時間軸受可見小時格線限制,月檢視儲存格則受行事曆週數限制,因此只要在轉譯迴圈外預先篩選任務/事件,就可使用 ScrollView。
同步效能指引
- 合併前先驗證承載資料形狀,以快速失敗。
- 合併必須具決定性,且相對實體數量為 O(n)(依 ID 建立對應,避免巢狀掃描)。
- 先核對附件中繼資料;將檔案 IO/網路延後至另一個同步階段。
- 使用退避限制重試次數,並區分可重試與終止錯誤。
- 在同步週期內快取後端設定讀取結果,以減少重複存取儲存區。
同步引擎在合併期間會維護已建立索引的衝突/修訂版查詢。新增同步實體類型或衝突報告時,請保留此索引結構,不要重新引入對每個實體掃描完整集合的作法。
同步調校提示
- 在行動網路上,附件上傳/下載並行數應保持保守。
- 分別調整中繼資料與附件的逾時及重試時間範圍。
- 切換至離線時迅速中止;連線中斷後避免長串重試。
- 對耗時較長的附件階段使用進度檢測。
- 追蹤每次同步的衝突數量、最大時鐘偏移與時間戳記調整。
- 將同步衝突樣本視為有界診斷資料。保持樣本數與差異鍵值限制精簡,避免衝突報告主導大型合併的成本。
同步除錯檢查清單
若同步延遲惡化:
- 分別比較本機讀取、合併、遠端寫入與附件階段。
- 確認速率限制回應(
429)未造成連鎖重試。 - 檢查附件雜湊驗證/重試是否反覆失敗。
- 確認遠端承載資料大小與集合數量在設定限制內。
- 擷取緩慢時段前後帶有時間戳記與請求 ID 的日誌樣本。
發行模式關鍵歷程剖析
廣泛變更效能前,請先剖析真實的發行版/剖析版組建。開發組建與測試執行器適合用作防護,但可能掩蓋真正的主導層:資料衍生、React 轉譯/提交、虛擬化、持久保存或原生/介面執行緒工作。
關鍵歷程預算
請將這些數字視為分流預算,而非硬性產品保證。盡可能記錄 p50 與 p95,並在每項結果旁附上資料形狀。
| 歷程 | Android 發行版預算 | 桌面發行版預算 | 主要訊號 |
|---|---|---|---|
| 快速收集開啟並接受第一個按鍵 | 開啟 <= 500 ms,輸入延遲 <= 100 ms | 開啟 <= 300 ms,輸入延遲 <= 100 ms | 從命令/點按到可編輯輸入欄及接受第一個字元的時間 |
| 完成/切換任務 | 視覺回應 <= 150 ms,排入儲存 <= 500 ms | 視覺回應 <= 100 ms,排入儲存 <= 300 ms | 從輸入至視覺更新,加上持久保存階段 |
| 開啟/儲存/關閉任務編輯 | 開啟 <= 300 ms,儲存/關閉 <= 300 ms | 開啟 <= 200 ms,儲存/關閉 <= 200 ms | 互動視窗/面板提交時間與儲存排清 |
| 開啟含 100+ 項任務的專案 | <= 2,000 ms | <= 1,000 ms | 從導覽至任務清單可互動 |
| 在專注/收集箱/專案掛載時開啟/關閉選擇器 | <= 200 ms | <= 150 ms | 選擇器轉場與上層檢視重新計算 |
| 切換專注、收集箱與專案檢視 | <= 500 ms | <= 300 ms | 從路由/檢視切換到可互動狀態 |
| 隨打即搜 | 每次按鍵 p95 <= 150 ms | 每次按鍵 p95 <= 100 ms | 從按鍵到可見結果更新 |
擷取矩陣
請將擷取資料附在 issue 或後續 issue。每份擷取資料都應註明 commit、應用程式版本、安裝管道、裝置、作業系統、資料形狀、歷程與成品連結。
| 平台 | 必要組建 | 工具 | 擷取成品 | 要記錄的主導層 |
|---|---|---|---|---|
| Android | 含代表性本機資料的發行版或剖析版 APK/AAB | Android Studio profiler、Hermes sampling,或可用時使用 Flipper | CPU trace 或 Hermes profile,加上螢幕錄影/時間戳記 | JavaScript 衍生、React 轉譯/提交、清單虛擬化、SQLite/持久保存、原生/介面執行緒 |
| 桌面版 | 含代表性本機資料的 Tauri 發行組建 | WebView DevTools Performance profiler 與應用程式診斷日誌 | 效能追蹤加上診斷時間戳記 | 資料衍生、React 轉譯/提交、網頁虛擬化、SQLite/持久保存、WebView/原生殼層 |
擷取備註範本
Commit:
Version/channel:
Platform/device/OS:
Dataset:
- tasks:
- projects:
- largest project task count:
- contexts/tags:
Journey:
Tool/artifact:
Observed p50/p95:
Dominant layer:
Notes:
Follow-up issue:層級分類
- 資料衍生:profile 顯示在轉譯開始前,反覆進行完整儲存區掃描、排序/篩選、數量彙總或選擇器抖動。優先使用查詢範圍明確的選擇器與衍生索引。於 #647 追蹤。
- React 轉譯/提交:profile 顯示提交時間過長、列重複轉譯、props 不穩定或訂閱範圍過廣。變更資料模型前,先記憶化列並縮小訂閱範圍。
- 虛擬化:profile 顯示可見清單掛載了數千個列元件。使用平台虛擬化工具及有界轉譯次數測試。於 #648 追蹤。
- 持久保存:介面停頓與儲存排清、SQLite 作業、匯入/匯出、同步寫入或 JSON 序列化同時發生。將急迫的視覺更新與儲存工作拆開。
- 原生/介面執行緒:Android trace 或桌面版 WebView trace 顯示動畫/版面/輸入停頓發生在 JavaScript 之外。減少版面抖動、巢狀捲動或原生橋接流量。
對於 #643 回報的專案開啟緩慢,請先擷取 Android 與桌面版資料。若資料衍生主導成本,使用 #647;若掛載列數主導成本,使用 #648;若持久保存或原生/介面執行緒停頓主導成本,請建立範圍較小的後續 issue,並附上擷取成品與確切歷程。
資料庫指引
- 可用時使用 FTS 索引進行全文搜尋。
- 為常用狀態/專案/日期篩選建立索引。
- 大型匯入/同步儲存路徑應在交易中批次寫入。
- 在讀取邊界正規化 JSON 欄位,避免重複解析/字串化迴圈。
剖析檢查清單
- 使用實際的資料集(數千項任務、大型專案)重現。
- 測量變更前後(轉譯次數、查詢時間、同步時間)。
- 檢查長時間工作階段中的記憶體增長。
- 確認低階裝置/模擬器沒有迴歸。
效能預算建議
- 清單互動應保持靈敏(可行時維持 <16ms 畫面預算)。
- 一般本機資料集的搜尋請求應低於 100ms。
- 同步合併應隨實體數量呈線性擴展。
- 避免以檔案/網路操作阻塞介面執行緒。
持續維持效能
- 修正迴歸時加入目標明確的測試(轉譯抖動、合併複雜度、重試行為)。
- 在 CI 中保留關鍵檢視與同步路徑的預算檢查。
- 優先採用可測量的小幅改善,不要進行廣泛的推測性重構。
- 每次最佳化後重新剖析,以確認實際效果。