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

重さの原因はMarkdownではなくWebエンジンだった

Markdownエディターを開いておくだけでファンが回るのは、Markdownの処理が重いからではありません。同じ文書を同じ条件で測ると、コストはレンダリングエンジンと時計に紐づいたループから生じています。

m
mote
同じ7.5 KBの文書を同じXvfb上で測定した2つのアプリのアイドル時CPU使用率とメモリ使用量。上側の短いバーがWebエンジンのないプロトタイプです。
同じ7.5 KBの文書を同じXvfb上で測定した2つのアプリのアイドル時CPU使用率とメモリ使用量。上側の短いバーがWebエンジンのないプロトタイプです。

ノートパソコンでMarkdownエディターを開いたままにしていました。何も入力していないのに、ファンが回り始めました。

最初はMarkdownのせいだと思いました。文書を何度も描画し直しているために遅いのだと。

本当にそうなのでしょうか?

同じ条件で比較しました

画面サイズ、レンダリング方式、文書をすべて同じに揃えました。7.5KB、113行の文書を開き、25秒間何もしませんでした。タイピング時にも、同じ文字を同じ速度で入力しました。

Webエンジンでプレビューを描画するapostropheのアイドル時CPU使用率は34.6%、メモリ使用量は378MBでした。プロセスは5つでした。

Webエンジンを使わず、同じ文書をインラインで描画したプロトタイプは、CPUを0.7%、メモリを64MB使用しました。プロセスは1つでした。

どちらもMarkdownを描画していましたが、結果は大きく異なりました。

apostropheでプレビューだけをオフにすると、CPUは7.0%、メモリは133MBに減りました。アプリもツールキットもそのままでした。変わったのはプレビューの描画方法だけでした。

Markdownをまったく描画しないテキストエディターも測定しました。CPUは2.2%、メモリは79MBでした。

Markdownを描画するプロトタイプのほうが、むしろ軽量でした。

そこでようやく明らかになりました。問題はMarkdownではありませんでした。

何もしなくても毎秒60回動いていました

原因は、プレビューのスクロールを本文に合わせるコードにありました。

このコードは、スクロールするときだけ実行されていたわけではありません。16msごとにタイマーが起動し、WebKitプロセスでJavaScriptを実行していました。応答が返ってくると、再びタイマーをセットしていました。

誰もウィンドウに触れていなくても、毎秒約60回ずつ動いていたのです。

Webエンジンを使うと、文書を編集する領域とプレビューを描画する領域が別々の世界になります。2つの状態を合わせる最も簡単な方法は、確認し続けることです。アイドル時のCPU使用率を個別に測定しなければ、このコストはなかなか見えません。

タイピング時には、差がさらに大きくなりました。apostropheはCPUを180%、プロトタイプは41%使用しました。

一方はキーを押すたびにブラウザプロセスとの間を行き来していました。もう一方は変更された行にだけタグを付け直していました。

測定結果を設計原則にしました

プロトタイプには特別な最適化はありませんでした。

スタイルはテキスト上にタグとして適用しました。複数の編集は、自ら消える一回限りのidleにまとめました。タグを付け直す範囲は、変更された行に限定しました。プロセスも1つだけ使いました。

何かを追加したのではなく、必要のないものを置かなかったのです。

その後、2つのことを設計原則として定めました。

第一に、Webエンジンを依存関係に含めません。

第二に、文書が変更されておらず、アニメーションもないのであれば、フレーム、タイマー、ティックを予約しません。

この原則を後から取り入れるのは困難です。Webエンジンは単なるライブラリではなく、アプリの構造を変えます。一度導入すると、取り除くことは作り直すことと同じになります。タイマーもルールがなければ、機能ごとに1つずつ増えていきます。

その代わり、簡単な方法を諦めなければなりませんでした。ファイルの変更をポーリングで確認することはできず、数式をWebViewに任せることもできませんでした。必要なレイアウトは自分たちで作らなければなりませんでした。

原則が曖昧にならないよう、リリースのたびに実機で再測定しています。

実機のGPUで実行したパフォーマンスゲートの出力。ウィンドウが表示された後、アイドル状態で描画されたフレームは0で、CPU使用率は0.10%です。
実機のGPUで実行したパフォーマンスゲートの出力。ウィンドウが表示された後、アイドル状態で描画されたフレームは0で、CPU使用率は0.10%です。

数字を見る際の注意点もあります

実験はソフトウェアレンダリングで行いました。実際のGPU環境よりもCPU使用率が高く出ます。そのため、絶対値より比率を見る必要があります。

プロトタイプのアイドル時CPU使用率0.7%も、その大部分はカーソルの点滅に使われた値です。点滅をオフにすると、0と区別するのが難しいほどでした。

すべてのWebエンジンベースのアプリが同じ問題を抱えているという意味ではありません。今回の結果はapostropheに限られます。Chromium系のように、アイドル状態で処理を減らすエンジンもあります。

プロトタイプの機能も多くはありませんでした。表、数式、エクスポート、検索機能はありませんでした。比較できるのはレンダリングコストまでです。

それでも、1つだけ明らかなことがありました。

コストを生み出していたのはMarkdownではありませんでした。レンダリングエンジンと止まらないループでした。

原因を正確に突き止めれば、軽さは新しい機能ではなく引き算になります。

← 前の記事Markdownエディターをもう1つ作った理由次の記事 →モードを切り替えても文書は1つ
RSSで更新を追えます。
書くことだけを残す
日本語
© 2026 mote