ポータブル版とは
electron-builderで作れる、全ファイルを1つのEXEに纏めたもの。Electronでexeのビルドまでやったことのある人なら分かると思いますが、そのままだとファイル数がかなり多く、移動するならフォルダ単位になってしまうので魅力的ですね
問題点
最小構成でも起動が7秒前後かかる上に、原理上スプラッシュスクリーンも出しようがないこと
Exeを起動した後、内部では以下のような処理が行われます。
- Tempフォルダに全ファイルをコピー
- 1ファイルに圧縮状態のため展開
- Electron起動(このため、app.getPath("exe")でExeファイルのパスを取得しようとすると、Tempフォルダ内の実際に動作しているファイルのパスが取れてしまうというトラップがある)
- アプリを落とすとTempフォルダにあるファイルが削除される
この1~2がネックとなっており、Electron自体の準備に時間がかかっているため、Electronの仕組みではスプラッシュスクリーン(起動準備中に表示する画像)の出しようがないという。検索した限り、ネイティブ言語でこの処理にフックして画像表示するスクリプトを書く等するツワモノもいましたが、うーん
対処方法
調べた結果、ビルドオプションでちょっとだけ緩和できます。
- asar:trueにする(デフォルト設定)
- useZip:trueにする
asmrasarは自前のファイル類を1つの.asarファイルに圧縮する設定ですね。詳しいことは省きますが早くなります。useZipは上のフローで言うところの2の部分ですね。1つのExeに固めるのをお馴染みのzipで行うことにより高速化を図ります。
また、対処方法ではないですが、2回目以降の起動はキャッシュが効くので初回だけ我慢してもらうというのもあります。
各オプション個別適用によるガバガバ計測
マシン
CPUはHaswell世代でHDD搭載
ビルドに用いたもの
Electron ver8系/electron-builder ver22系
テストアプリについて
自作の小さなアプリをビルドする設定を詰めるために行ったので、純粋なhallo,world系のアプリではないですが、かなり軽めのアプリのため結果には大差ないと思います。
なおElectron起動した直後はウィンドウ表示せず、1回目のDOM描写が終わった後に発動するready-to-showイベントを拾ってウィンドウ表示する一般的なフローとなります。(Electron起動直後に素直にウィンドウ表示すると、DOM描写の前で一瞬真っ白画面になる現象への対策)
計測方法
Exeダブルクリック→画面表示までの所要時間を計測。面倒だったのでWindowsのストップウォッチ機能使ってのアナログ計測。このため誤差1秒はあるかと。
結果(単位:秒)
portable | useZip | ASAR | 1回目 | 2回目 |
---|---|---|---|---|
TRUE | TRUE | TRUE | 6 | 7 |
TRUE | TRUE | FALSE | 8 | 7 |
TRUE | FALSE | TRUE | 6 | 7 |
TRUE | FALSE | FALSE | 9 | 7 |
FALSE | TRUE | TRUE | 3 | 0 |
FALSE | TRUE | FALSE | 2 | 0 |
FALSE | FALSE | TRUE | 4 | 0 |
FALSE | FALSE | FALSE | 4 | 0 |
見てのとおりポータブルにしない方がいいですね。理論上、結果がおかしいところがありますが誤差で流せるレベルかと。
個人的には全部Trueの約6秒コースならまだ我慢できなくもない感じはしましたが、実際はSPAフレームワーク使って、起動時にCSSや画像も読み込んで、ついでに通信やらローカルファイル読み込み等行うと思うので、Exe叩いて6秒後にようやくローディング表示して云々では苦痛でしょうね
その他の問題点
ポータブル版に限った話ではないですし、今更ですが、Electronの仕組み上、Chromiumを丸々乗せてるので最小構成でも容量がデカいですね。ver8系だと未圧縮で100MB、フル設定で60MB前後が目安。ますます小さなアプリには採用し辛い……