Electronアプリのファイルサイズ最適化,必要なファイルだけパッケージするやり方
ElectronアプリはchromiumをベースにしていてHello worldするだけでも100M近くのファイルサイズになってしまう. 油断しているとすぐに200Mとかになってしまうので,ファイルサイズをできるだけ小さくすることを普段から心がける必要がある.
心がけた結果のPRがこれ
今までは,
$ NODE_ENV=production ./node_modules/.bin/electron-packager . nicomentron --platform=darwin --arch=x64 --out=packages --overwrite
こうビルドしていた.
こうすると,もちろんだがカレントディレクトリのファイル全てがアプリ内に含まれてしまい,node_modules
や当たり前に不必要なファイルが数多く含まれてしまいこのようになる.
最適化できているかは,アプリ内のここのディレクトリを見れば確認することができる.(asarで圧縮してしまうともちろん見れない
せっかくビルドした結果をapp以下に吐いているのに無関係に全ファイルアプリ内に入ってしまっていることがわかる. 必要なのはビルド結果のapp以下のファイルとpackage.json,その他必要なファイルだけだ.
不必要なファイルで気をつけるべきなのは,自分のアプリで言うとフラッシュプラグインがあり,今後マルチプラットフォーム対応するにあたって各プラットフォームごとのフラッシュプラグインを用意するので,このままだと全てのフラッシュプラグインが入ってしまう
結果以下のようにapp以下をパッケージングするように変更した.パッケージングするにはpackage.json
が必要である.自分のアプリはexternals
でネイティブモジュールを使用しているので,仕方なくnpm install
して,electron-rebuild
も実行するようにしている.もちろん,本来であればnode_modules
も必要ない
$ cp package.json ./app && cp -r plugins ./app && cd ./app && rm -rf node_modules && npm install --production && ../node_modules/.bin/electron-rebuild -m . sqlite3 keytar $ NODE_ENV=production ./node_modules/.bin/electron-packager ./app nicomentron --platform=darwin --arch=x64 --out=packages --overwrite --asar
結果 良さそう
ニコ生デスクトップクライアントのニコ生ビューア部分できた
Rails5でenable_dependency_loading = trueするのはどうなのか
Ruby on Rails5では,production環境でのautoloadが廃止されました.
Upgrading Ruby on Rails — Ruby on Rails Guides
Rails5では,その代わりにeager_load
を行なっていて,これはデフォルトでは,autoload_paths
にデフォルトで指定されているファイルと同じファイルをアプリケーション起動時に全て読み込んでおくということになっています.
よく lib
以下を config.autoload_paths << Rails.root.join("lib")
といった風に追加しているのを見かけるし,実際に自分もやっています.
ここで問題になるのが, autoload_paths
に lib
以下を追加しているので,もちろんproduction環境時にlib
以下が読み込まれなくなってしまうということです.
ここでさっきのGuideを読むと,
For the vast majority of applications this change needs no action. But in the very rare event that your application needs autoloading while running in production mode, set Rails.application.config.enable_dependency_loading to true.
「圧倒的大部分のアプリケーションは何もする必要がない.puroduction環境で実行中にautoloadingする必要のあるとてもめずらしいアプリケーションの場合は, Rails.application.config.enable_dependency_loading = true
にしてください」と書かれています.
じゃあRails.application.config.enable_dependency_loading = true
すれば良いんだ,ということではないです.
圧倒的大部分のアプリケーションでは何もする必要がなく,trueにするのはメチャクチャまれだとかなり強調して言っています.ここは,ちょっと調べないといけないなと思うわけなんですが,面白いissueがあります.
色々議論されているんですが,eager_load
の場合も,autoloadingしていてスレッドセーフじゃないということなんですが,スレッドセーフの問題があったようです….
If developers follow our guidelines of not changing autoload_paths, adding directories to app for autoloading code and explicitly requiring code in lib then Rails will be threadsafe.
threadsafeにするには,私たちのガイドライン(非公式)に従ってautoload_paths
を変更せずに,明示的にrequireすると良いとかかれています.
とにかくautoload
するのはスレッドセーフの観点から良くないということがわかります.
なので解決策としては,
1. app以下にlibを持っていく
読み込まれる必要のあるコードをapp
以下にlib
ディレクトリなどを作って,置いておく
2. とにかくrequireする
3. lib以下をeager_load_pathsに追加する
autoload_paths
同様にeager_load_paths
が指定できるので,ここで lib
以下を指定する方法ですが,Rakeタスクなどあると思うので良くない
4. 必要なファイルを適宜requireするか、eager_load_pathsに追加する
まあ良い
あたりがあるのではないかと思われます.
自分も知らねーという感じだったし,こういったことは公式でドキュメントにすべきだというissueが立つも完全スルーのまま終わったり,
Upgrading guideもスレッドセーフなどには触れずにかなり曖昧な説明にしているあたりに特別な何かを感じるのだが,これは一体