Electronで開発したアプリケーションを動作させていると、アプリケーションがバックグラウンド動作をしている時にフリーズしてしまうことがあります。これはバックグラウンド状態のアプリの動作優先度を下げられてしまうためで、その原因は特定のプラットフォーム特有の挙動による場合と、ElectronにバンドルされているChromiumの挙動による場合の2つが考えられます。
どちらの場合もElectronアプリ側から行える対処法がありますので、以下にそれぞれの対策をまとめます(おまけとしてChromiumの中でそれらがどのように処理されているかもリンクしておきました)。
プラットフォーム側による動作優先度変更への対策
プラットフォームによってはOS XのAppNapのように、ユーザが操作中でないアプリの動作優先度を強制的に下げる機能を持っています。
このようなプラットフォーム側の機構を回避するためにElectronに用意されているのがpowerSaveBlockerモジュールです。以下にpowerSaveBlockerモジュールの使い方を示します。
import { powerSaveBlocker } from 'electron';
const id = powerSaveBlocker.start('prevent-app-suspension');
// 優先度を下げてほしくない処理
powerSaveBlocker.stop(id);
powerSaveBlcoker#start
への引数はprevent-app-suspension
とprevent-display-sleep
の2種類がありますが、アプリの動作優先度を維持したいだけであればprevent-app-suspension
を利用します。startメソッドを呼び出してからstopを呼びだすまで、アプリの動作優先度が維持され、またコンピュータがスリープに入らなくなります。
powerSaveBlockerの処理はElectronではなく、ElectronにバンドルされているChromiumに実装されている機能で、各プラットフォームごとに別々の実装がされています。
例えばOS X向けの実装ではIOPMAssertionCreateWithNameというOS XのAPIを利用してMacがスリープ状態になるのを防いでいます。また、この処理で呼び出し元のアプリケーションがAppNapで低優先度動作になるのも防止されます。
ユーザが操作していないアプリケーションの優先度を下げたり、コンピュータが自動的にスリープ状態になるのは電力消費を抑えるための機能であり、本来は強制的に停止させるべきではありません。powerSaveBlockerを使う際はアプリケーションのライフサイクル全体で使うよりも、どうしても守りたい処理を行っている間だけに限るべきでしょう。
Chromiumによる描画優先度変更への対策
ElectronにバンドルされているChromium自体も、現在表示中でないページの描画優先度を下げる機能があります。これにより、ウィンドウが隠れている際などに処理が極端に遅くなってアプリがフリーズしてしまうことがあります。
この機能を無効化するには以下のようにdisable-renderer-backgroundingスイッチを使用します。
import { app } from 'electron';
app.commandLine.appendSwitch('disable-renderer-backgrounding');
app.on('ready', () => {
...
});
この処理は上記のようにready
イベントが呼ばれる前に実行する必要がある点に注意してください。こちらも実際にはElectronではなく、Chromiumの動作に影響するのですが、Chromiumのrendererプロセス処理の中で表示状態に応じてバックグラウンド状態に設定されるのを防止することで描画の優先順位を維持します。
参考文献
- powerSaveBlocker - GitHub
- Supported Chrome command line switches - GitHub
- Process priority when application is minimized on dock or not focused - GitHub Issues
- Seems like page-visibility option on BrowserWindow is broken - GitHub Issues
- Electron - Slow performances in background
- Extend App Nap - Energy Efficiency Guide for Mac Apps