機能価格ドキュメントブログ
moteを入手
← ブログ
開発·2026年8月21日·読了まで6分

開いているだけなら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でも安心はできません。見えないところでスレッドが目覚め続けているかもしれないからです。プロセスのすべてのスレッドが1秒間に何回目覚めるかも併せて記録します。まだ基準を蓄積している最中なので、この数値だけで開発を止めることはありません。

例外はキャレットの点滅だけです。繰り返しタイマーは使わず、一度点滅したあとに次の動作を改めて予約します。ウィンドウがフォーカスを失えば、すぐに停止します。キャレットを含むアイドル時の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。一番下の行には測定条件が四つ記されています

コードで一度、実機で一度

原則は時間が経つと曖昧になります。そこで二度確認します。

まずコードを検査します。繰り返しタイマー、終わることのないティック、眠っては目覚めることを繰り返すポーリング、ファイル全体を不必要に読み直すコードを自動的に探します。見つかれば、CIはそこで止まります。どうしても必要な例外なら、なぜその処理が終了するのかをコードのすぐ上に記さなければなりません。

次に実機で測定します。このとき、四つの条件を守ります。

GPUのある実際の画面で測定します。ポインターはウィンドウの外に置きます。実際のセッションバスを使用し、フレームは描画された瞬間に数えます。

これらの条件は、失敗を経験するなかで生まれました。ポインターがウィンドウ上にあるという理由だけで、アイドルフレームが150個発生したことがありました。隔離されたセッションでは、ツールキットが応答を待つために起動が数秒ずつ遅れました。遅れて報告されるフレームカウンターを使ったときには、起動画面のフレームがアイドル区間に混ざることもありました。

メモリも絶対値では判断しません。ツールキットとグラフィックドライバーが占めるメモリは、環境によって数十MB単位で変わるからです。

代わりに、空の文書を基準にします。空の文書と比べて、文書を開いたときにどれだけ多く使用するかだけを見ます。最近の測定では、空の文書は116MB、100KBの文書は120MBを使用しました。moteが追加で使用したメモリは4MBで、予算の8MB以内です。

最初からこのように測定していたわけではありません。メモリ予算を超えたと思ったところ、実はアプリではなく実行環境の基本メモリが増えていたことがありました。その日から、絶対値ではなく「私たちの機能が増やした分」を測り始めました。

ゲートが使用する100 KBのフィクスチャをライブモードで開いた画面 — 下部のステータス行で単語20,584個と文字96,513字を数えています。この文書と空の文書との差が、予算でいう「私たちの分」です
ゲートが使用する100 KBのフィクスチャをライブモードで開いた画面 — 下部のステータス行で単語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