まずは比較テスト:通信中・待機中の消費と集計の見方を分ける

Clashを起動したスマホが熱くなっていても、プロキシのコアが常にCPUを使い切っているとは限りません。動画のダウンロード、クラウド写真のアップロード、電波が弱い場所でのモバイル通信の再送などが同時に起きている可能性があります。AndroidのローカルVPNは他のアプリの通信を受け取るため、システムのバッテリー画面で一部の通信がVPNクライアントの消費として集計されることがあります。集計方法はシステムによって異なります。まず端末全体の電池残量を確認し、次にアプリ別の使用状況を見ましょう。ランキングの1位だけで判断しないでください。

各回60分以上、2回に分けてテスト

  1. 条件をそろえる:同じWi-Fi、開始時の電池残量と室温をそろえ、ダウンロードとシステム更新を一時停止します。充電しながらのテストは避けてください。
  2. プロキシをオフにしてテスト:画面をロックして60分待ち、開始・終了時の電池残量、発熱の有無、バックグラウンドアプリ、電波状況を記録します。
  3. プロキシをオンにしてテスト:同じノード・同じ設定で画面をロックし、60分待ちます。2~3回繰り返し、できればテストの順番も入れ替えてください。
  4. モバイル通信でもテスト:モバイル通信でのみ異常が目立つ場合は、TUNスタックをすぐに変更するのではなく、電波状況、ネットワークの切り替わり、接続の再試行を先に確認します。

たとえば電池残量が80%から77%になった場合、記録するのは「1時間で3ポイント減少」です。この結果から正確な消費電力を推定することはできません。以下は記録項目の例であり、本サイトでの実測値ではありません。電池残量の表示には丸め誤差があるため、差が小さい場合は3~6時間に延長すると比較しやすくなります。

記録項目内容目的
ソフトウェア環境クライアントのバージョン、コアのバージョン、Androidのバージョンアップデート前後の結果を同じ条件として扱わないため
ネットワーク条件Wi-Fiまたはモバイル通信、ノード、テスト時間通信経路の違いを除外するため
電池残量と温度開始・終了時の残量、明らかな発熱の有無端末全体の変化を確認するため
動作状況サービスの再起動、ネットワークの再接続の有無バックグラウンドでの再起動を見つけるため

バックグラウンド動作:必要な権限は維持し、再起動の繰り返しを防ぐ

Androidクライアントは通常、VpnServiceでローカルVPNインターフェースを作成し、通信をコアに渡して処理します。システムに常駐通知が表示されていても、高負荷が続いているとは限りません。一方、通知を無理に隠したりバックグラウンド動作を制限したりすると、サービスが終了して自動再起動を繰り返し、通信断や初期化の繰り返しにつながることがあります。

まずAndroidの3つの設定項目を確認

  • バッテリー制限:Android 13~15では、一般に「設定」→「アプリ」→「すべてのアプリを表示」→対象クライアント→「アプリのバッテリー使用量」から確認できます。機種によっては「バッテリー」→「制限なし/最適化/制限あり」と表示されます。項目名は端末によって異なります。
  • VPNの設定:標準Androidでは、一般に「設定」→「ネットワークとインターネット」→「VPN」→クライアント横の設定ボタンから、「常時接続VPN」と「VPNなしの接続をブロック」を確認できます。後者はVPN切断時に通信を遮断する設定で、省電力機能ではありません。
  • メーカー独自のバックグラウンド管理:アプリ情報画面で「自動起動」「バックグラウンド実行」などの項目を確認します。まず対象クライアントだけを変更し、すべてのバックグラウンドアプリを一括で許可しないでください。

画面ロック後も接続が安定し、サービス終了の記録もないなら、「バックグラウンド動作を強化する」ために定期再起動やサードパーティ製の監視ツール、定期的な通信を追加する必要はありません。ロック後に切断される場合は、まずクライアントのバックグラウンド実行を許可し、そのうえで電池消費の変化を確認します。省電力と接続維持は別々に検証してください。権限を次々と切り替えて運任せにするのは避けましょう。

必要なアプリだけをVPN経由にすれば、コアが処理する接続数を減らせますが、端末全体の省電力が保証されるわけではありません。除外したアプリもバックグラウンドでダウンロードすることがあります。変更後はブラウザー、メッセージ通知、地図、LAN内の機器への接続を確認し、機能が使えなくなった状態を省電力の成功と取り違えないようにしましょう。

定期処理:ヘルスチェックとサブスクリプション更新を確認

待機中も定期的に通信する原因として、ノードのヘルスチェック、自動選択ポリシー、サブスクリプションやルールの更新がよくあります。これらは同じタイマーではありません。ノードのチェックは接続可能性の確認、サブスクリプション更新は設定やノード一覧の取得、ルール更新はマッチング用データの更新です。すべてを数十秒間隔にすると、余計なリクエストが増えます。

間隔とノード数を合わせて確認

たとえばノードが80個あるグループを60秒ごとに一巡チェックすると、スケジュール上は1時間に4,800回のチェック試行になります。600秒間隔なら480回です。実際の回数は遅延チェック、失敗時の処理、クライアントの実装にも左右されます。これは設定規模の例であり、電池消費の実測値ではありません。また、すべてのノードが同時に接続を確立するという意味でもありません。

  • 原因を調べる間は、不要な自動速度測定をオフにするか、間隔を60秒から600~1,800秒に延ばします。
  • 一時的に手動選択ポリシーへ切り替え、同じノードで画面ロック中の電池消費を確認し、頻繁な自動切り替えを除外します。
  • 通常のサブスクリプションは、まず24時間ごとの更新に設定します。変更をより早く反映する必要がある場合は、間隔を短くしてください。
  • 同じノード群を対象とする頻繁なチェックを複数設定しないでください。ヘルスチェックとプロキシグループのテストが、それぞれリクエストを送信する場合があります。

mihomoのprovider設定例

以下の断片は、既存のproxy-providersにあるHTTP providerの該当項目だけを置き換えるためのものです。既存の名前、サブスクリプションURL、パスはそのまま残し、YAMLの最上位に貼り付けないでください。ここでのintervalとヘルスチェックのintervalは秒単位、timeoutはミリ秒単位です。

interval: 86400
health-check:
  enable: true
  url: https://www.gstatic.com/generate_204
  interval: 600
  timeout: 5000
  lazy: true

lazy: trueは、使用されていないproviderの定期チェックを減らす設定です。使用中のノードに対するすべてのチェックが停止するわけではありません。ヘルスチェック先には、対象ノード経由でアクセスできるアドレスを指定してください。現在のネットワークからアクセスできないと、アドレス側の障害をノードの障害と誤認するおそれがあります。古いClashコアでは対応フィールドが異なる場合があります。読み込む前にコアの種類を確認し、保存後は設定エラーの表示も確認してください。

クライアント側の「サブスクリプション自動更新」は、YAML内のprovider更新とは別に動作する場合があります。両方を確認し、片方の数値だけを変更して済ませないでください。管理対象の設定は次回更新時に手動変更が上書きされることもあるため、クライアントが対応しているオーバーライドまたはマージ機能を使いましょう。

DNSポーリング:ログで繰り返しのリクエストを特定し、むやみにリゾルバーを変更しない

通常、DNSクエリはアプリがドメインを名前解決するときに発生します。fake-ipを有効にしても、スマホがすべてのドメインを一定間隔で問い合わせるわけではありません。主にドメインのマッピング方法と接続処理が変わります。「DNSポーリングによる電池消費」に見える現象は、アプリの再試行、ヘルスチェック、暗号化DNS接続の再確立、DNS設定のループが原因かもしれません。

短時間ログを有効にして、次の3つのパターンを確認

  1. 同じドメインが数秒おきに現れる:メッセージ、広告のリクエスト、同期処理、速度測定先のいずれかを確認します。必要なら該当アプリを一時停止し、リクエストが止まるか確認してください。
  2. タイムアウト直後に何度も再試行する:DNSの上流サーバーに到達できるか、まだ確立していないプロキシ接続に依存していないか、上流のドメイン解決に使うブートストラップDNSを確認します。
  3. ローカルアドレス間で転送を繰り返す:クライアントのDNSが、自身に横取りされる入口へ再び向いていないか確認します。127.0.0.1の待ち受けポートを上流としても指定すると、ループが発生することがあります。

調査中は、到達性を確認済みのDNS上流を1つ残し、重複する上書きを一時停止してから、項目ごとに戻します。省電力のためにすべての名前解決ルールを削除したり、キャッシュの有効期限を無理に延ばしたりしないでください。ドメイン切り替え後もIPアドレスが更新されず、古い接続先を使い続けるおそれがあります。nameserver-policyはドメインごとにリゾルバーを選ぶ設定で、定期処理を一括停止するスイッチではありません。

Androidの「設定」→「ネットワークとインターネット」→「プライベートDNS」も記録しておきましょう。システムのプライベートDNS、ブラウザーのセキュアDNS、クライアント内蔵DNSが併用される場合があります。設定経路はVPNのルーティングやアプリの実装によって異なります。TUNで53番ポートを横取りしても、すべての暗号化DNSを制御できるわけではありません。比較テストでは一度に1項目だけ変更し、終了後はプライバシー要件に合う設定に戻してください。

ログレベルと接続画面:調査後は余分な負荷を抑える

デバッグログは、ログの整形・書き込み・画面更新の負荷を増やします。問題の切り分けに一時的に使うのは有効ですが、ログが流れ続ける画面を長時間表示するのは避けましょう。接続一覧を毎秒更新すると画面側の処理も増えます。画面ロック中の消費を測る際はアプリをバックグラウンドに移し、ダッシュボードを点灯したままにしないでください。

mihomoの日常利用では、まず次のログレベルを使います。設定はdnsやtunと同じ階層に置きます。正しい値はwarningで、warnではありません。

log-level: warning
  • 問題を再現するときだけ一時的にinfoへ変更し、5~10分程度記録します。
  • より詳しい診断が必要な場合に限りdebugを有効にし、大量のログを出力し続けながらテストするのは避けてください。
  • ログを共有する前に、サブスクリプションURL内のトークン、ノードの認証情報、個人のアクセス履歴を隠してください。
  • クライアントに独立した画面ログの設定がある場合は、そちらも確認してください。コアのログレベルがフロントエンドのすべてのログに適用されるとは限りません。

ログレベルを下げると記録にかかる負荷は抑えられますが、ノードのパケットロスやDNSループは解消しません。エラーが頻発する場合は、ログを隠すだけでなく原因を取り除いてください。

TUNスタックとノードのプロトコル:実機で比較して選ぶ

AndroidではVpnServiceが仮想ネットワークインターフェースを提供し、受信したパケットの処理方法はクライアントが決定します。デスクトップ向けの解説にあるTUNスイッチを、Androidの実装にそのまま当てはめることはできません。モバイルクライアントによっては独自にインターフェースを作成するため、YAMLのtunフィールドですべての動作を制御できるとは限りません。

選択できる項目を確認してから、1項目ずつ比較

mihomoの一般的なスタックにはsystem、gvisor、mixedがありますが、モバイルクライアントで選択できるか、どう組み込まれるかはバージョンによって異なります。すべてのスマホに共通する「最も省電力なスタック」はありません。標準のスタックで安定しているなら、そのまま使いましょう。CPU使用率が高止まりする、UDPに異常がある、既知の互換性問題がある場合に限り、対応している別のスタックを試してください。

  1. 現在のクライアントとコアの完全なバージョン番号を記録し、動作する設定をバックアップします。
  2. スタックだけを切り替え、ノード、ルール、DNS、テスト用ネットワークは変更しません。
  3. クライアントの案内に従ってVPNを再確立し、画面ロック中の待機時と通常使用時をそれぞれテストします。
  4. Webページ、音声通話、ゲームのUDP通信、IPv6、LAN内機器へのアクセスを確認します。問題が再発した場合は、元の設定に戻してください。

ノード側のパケットロス、混雑、プロトコルの実装も電池消費に影響します。電波が弱い環境で再接続を繰り返す場合は、正常なハンドシェイクよりも優先して調べましょう。まず同じプロトコルの安定したノードに変更してから、プロトコルの違いを比較します。ノード変更、IPv6の無効化、スタックの切り替えを同時に行うと、効果のあった変更を特定できません。

省電力の確認リスト:リスクの低い順に実施

順番変更内容確認基準
1リアルタイムログ画面を閉じ、通常利用時はwarningにするエラーが連続して表示されず、機能も正常に動作する
2ヘルスチェック間隔をまず600秒にし、重複するテストを減らすノードを正常に選択でき、チェック頻度が下がっている
3サブスクリプション更新をまず24時間間隔にする設定が正常に更新され、ダウンロードを繰り返さない
4DNSのタイムアウトと再試行ループを修正する同じエラーが消え、ドメインを正常に名前解決できる
5必要に応じてバックグラウンド権限とアプリリストを調整する画面ロック中も接続、通知、必要な通信が正常に動作する
6ノードとTUNスタックを比較テストする繰り返しのテストで改善し、必要な機能に問題がない

iPhoneでも同じネットワーク条件で比較テストを行いましょう。ただし、Androidのバッテリー最適化除外リストやVpnServiceのメニューをそのまま参考にしてはいけません。iOSクライアントは通常Network Extensionに依存します。サブスクリプションの更新、速度測定、ログの設定は各アプリ内で確認してください。この記事のmihomo YAMLも、クライアントが該当設定に対応している場合にのみ使えます。

電池消費が続く場合:再現できる情報を添えて報告

ここまでの手順を試してもスマホの発熱が続く場合は、「バックグラウンドで電池を使いすぎる」という一言より、再現手順をまとめたほうが原因を特定しやすくなります。クライアントのプロジェクトの問題報告ページに送る際は、少なくとも次の情報を含めてください。

  • スマホの機種、OSのバージョン、クライアントのバージョン、コアのバージョン、問題がアップデート後に初めて発生したかどうか。
  • Wi-Fiまたはモバイル通信の条件、画面ロックの有無、テストの開始・終了時刻、プロキシのオン・オフそれぞれの電池消費の記録。
  • ヘルスチェックと更新の間隔、ログレベル、TUNスタック、アプリ別プロキシの使用状況。
  • 機密情報を除いた短時間のログ、異常が最初に起きた時刻、サービスの再起動やネットワーク切り替えの有無。

プロキシをオフにしても同じように電池が大きく減る場合は、電波状況、バックグラウンド同期、バッテリーの劣化、システム更新タスクを確認します。原因の切り分けは、まず測定し、次に不要な起動を減らし、最後に低レイヤーの実装を調整する順で進めましょう。一度に1項目だけ変更し、元に戻せる設定を残しておけば、結果を比較できます。基本的な操作は使い方ガイドをご覧ください。接続に問題がある場合はトラブル対処ガイドもご確認ください。