功能價格文件部落格
取得 mote
← 部落格
工程·2026年8月21日·閱讀時間 5 分鐘

讓程式閒置開啟時不占用 CPU 的方法

編輯器雖然整天開著,但真正打字的時間只占其中一小部分。mote 在其餘時間不排程任何畫面更新,也不設定任何計時器,並透過程式碼檢查與實機測量這兩道關卡來確保這一點。

m
mote
執行一次閘門後的輸出。這是在 dev 版本中開啟 100 KB 文件,並於實機 GPU 上測得的數值,因此視窗出現後的 10 秒內,繪製的影格數為 0,閒置 CPU 使用率為 0.10%。
執行一次閘門後的輸出。這是在 dev 版本中開啟 100 KB 文件,並於實機 GPU 上測得的數值,因此視窗出現後的 10 秒內,繪製的影格數為 0,閒置 CPU 使用率為 0.10%。

編輯器是筆記型電腦上開啟時間最長的應用程式。但真正寫作的時間並不長。大部分時間,它只是在人們處理其他事情時安靜地開著。

因此,mote 訂立了一項原則。

如果文件沒有變更,也沒有動畫,就什麼也不做。

沒有排程好的影格,沒有重複計時器,也沒有週期性檢查。這不是最佳化,而是必須優先於所有功能遵守的設計原則。

如果什麼事都沒有發生,影格數也應為 0

光靠 CPU 使用率,很難判斷應用程式是否安靜。因為每次測量時數值都會波動,而且經過四捨五入後很容易變成 0。

所以 mote 會先看影格數。視窗開啟後,如果文件在 10 秒內沒有任何變化,繪製的影格數就必須恰好為 0。這個數字直接在應用程式內計算,只要繪製了一個影格,程式碼就不會被合併。

即使影格數為 0,也不能因此放心。因為執行緒可能在看不見的地方持續被喚醒。我們也會一併記錄處理程序的所有執行緒每秒被喚醒幾次。目前仍在建立基準,因此不會只憑這個數值阻擋開發。

唯一的例外是游標閃爍。它不使用重複計時器,而是在閃爍一次之後,重新排程下一個動作。視窗一失去焦點,就會立刻停止。包含游標在內的閒置 CPU 預算是 0.3%。

我們不會只單獨觀察閒置效能。延後繪製雖然能輕易讓影格數變成 0,卻也可能讓輸入的文字延遲顯示。因此,我們會同時檢查按鍵輸入延遲、啟動速度和記憶體。只要有一項超過標準,程式碼就不會被合併。

預算表中的 hard 項目——閒置影格 0 / 10 s、閒置 CPU 0.3%、從外部測量的按鍵→像素 p95 33.4 ms、從內部測量的按鍵處理 p95 4 ms、冷啟動中屬於我們的部分 10 ms、記憶體中屬於我們的部分 8 MB。最底下一行列出了四項測量條件
預算表中的 hard 項目——閒置影格 0 / 10 s、閒置 CPU 0.3%、從外部測量的按鍵→像素 p95 33.4 ms、從內部測量的按鍵處理 p95 4 ms、冷啟動中屬於我們的部分 10 ms、記憶體中屬於我們的部分 8 MB。最底下一行列出了四項測量條件

在程式碼中檢查一次,再到實際裝置上測量一次

原則會隨著時間逐漸模糊。因此,我們會確認兩次。

首先檢查程式碼。我們會自動找出重複計時器、永不結束的 tick、反覆休眠再喚醒的輪詢,以及不必要地重新讀取整個檔案的程式碼。一旦發現,CI 就會在那裡停止。如果是不可或缺的例外,就必須在程式碼正上方說明這項工作為什麼會結束。

接著在實際裝置上測量。此時會遵守四項條件。

在具有 GPU 的實際畫面上測量。將指標移到視窗外。使用真實的工作階段匯流排,並在影格繪製的瞬間立即計數。

這些條件都是經歷失敗後才形成的。曾經只因為指標位於視窗上方,就產生了 150 個閒置影格。在隔離的工作階段中,工具組因等待回應而使啟動延遲了好幾秒。使用延遲回報的影格計數器時,啟動畫面的影格甚至會混入閒置區段。

記憶體也不以絕對值判斷。因為工具組和顯示卡驅動程式占用的記憶體,會依環境相差數十 MB。

我們改以空白文件作為基準。只看開啟文件時比空白文件多使用了多少記憶體。最近一次測量中,空白文件使用了 116 MB,100 KB 文件使用了 120 MB。mote 額外使用的記憶體為 4 MB,落在 8 MB 的預算之內。

我們並非一開始就這樣測量。曾經以為超出了記憶體預算,後來才發現增加的不是應用程式本身,而是執行環境的基礎記憶體。從那天起,我們不再測量絕對值,而是改測「我們的功能額外增加的部分」。

閘門使用的 100 KB 固定測試檔以 live 模式開啟的畫面——下方狀態列正在統計 20,584 個單字和 96,513 個字元。這份文件與空白文件之間的差異,就是預算所說的「我們的部分」
閘門使用的 100 KB 固定測試檔以 live 模式開啟的畫面——下方狀態列正在統計 20,584 個單字和 96,513 個字元。這份文件與空白文件之間的差異,就是預算所說的「我們的部分」

開發時,畫面上也會顯示仍在運作的計時器數量。如果不是 0,就能在提交之前立即得知。

自動儲存也遵循這項原則。只有文件發生變更時才設定一次計時器,儲存完成後就將它移除。不會週期性喚醒來確認「有沒有什麼變更?」

這些數字不是為了擊敗競爭對手

一開始,我們想把閒置效能當作優於 Typora 的特點來介紹。但實際測量後,發現並非如此。

在相同裝置和相同條件下,Typora 的閒置 CPU 使用率是 0.1%。與 mote 實際上相同。確認有差異的應用程式是 Obsidian 的 0.8% 和 MarkText 的 0.6%。

我們也曾寫錯過。有一段時間,文件中寫著「Typora 開著時會占用 CPU」。作為依據的 34.6% 並不是 Typora,而是 apostrophe 的測量值。重新確認後,我們立刻修改了那句話。

閒置影格數為 0 並不是針對競爭對手的主張。這是 mote 對自己要求的紀律。因為如果沒有重複執行的工作,我們隨時都能說明應用程式此刻正在做什麼。

也有一些東西因為這項原則而被放棄

很多時候,我們無法採用方便的方法。

我們不能週期性檢查檔案是否在外部被修改,而必須接收作業系統的變更通知。我們沒有把數學公式交給 WebView 處理,而是自行製作了版面配置引擎。動畫也不能持續運轉。所有動作都有開始與結束,結束後就必須完全停止。

我們不會聲稱電池續航能多出幾個小時。因為那是未經測量的數字。我們確認過的,是影格數、CPU 使用率,以及執行緒被喚醒的次數。

在什麼事都沒有發生時,什麼也不做。

在 mote 中,這不是一項功能,而是所有功能都必須通過的原則。

← 較舊為什麼定價為購買一次即可使用整個 1.x 版本週期較新 →不只說「輕巧」,而是公開數據的理由
透過 RSS 持續關注。
只留下文字。
繁體中文
© 2026 mote