Electronアプリのファイルサイズ最適化,必要なファイルだけパッケージするやり方

ElectronアプリはchromiumをベースにしていてHello worldするだけでも100M近くのファイルサイズになってしまう. 油断しているとすぐに200Mとかになってしまうので,ファイルサイズをできるだけ小さくすることを普段から心がける必要がある.

心がけた結果のPRがこれ

github.com

今までは,

$ NODE_ENV=production ./node_modules/.bin/electron-packager . nicomentron --platform=darwin --arch=x64 --out=packages --overwrite

こうビルドしていた. こうすると,もちろんだがカレントディレクトリのファイル全てがアプリ内に含まれてしまい,node_modulesや当たり前に不必要なファイルが数多く含まれてしまいこのようになる.

f:id:tsuwatch:20170527181027p:plain 最適化できているかは,アプリ内のここのディレクトリを見れば確認することができる.(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

結果 f:id:tsuwatch:20170527223245p:plain 良さそう

ニコ生デスクトップクライアントのニコ生ビューア部分できた

進捗です

f:id:tsuwatch:20170509003735p:plain

github.com

最初に想定していた,ニコ生ビューアに実装したい機能をひとまず実装し終えた.

できることは以下

  • キーワード検索
  • タグ検索
  • ソート
  • 検索条件のお気に入り
  • 放送終了後に自動でプレイリスト内の次の番組に遷移
  • 番組開始通知
  • マイページ

Macのみ対応しています.

今後は,ニコ生ビューアの微修正などしつつ本来の目的であるコメントビューアの実装に取りかかります.

バグご意見ご要望などありましたら是非issuesなどへお願いします.

ダウンロードはこちらから

Release v0.3.1 · tsuwatch/nicomentron · GitHub

Rails5でenable_dependency_loading = trueするのはどうなのか

Ruby on Rails5では,production環境でのautoloadが廃止されました.

A Guide for Upgrading Ruby on Rails — Ruby on Rails Guides

Rails5では,その代わりにeager_loadを行なっていて,これはデフォルトでは,autoload_pathsにデフォルトで指定されているファイルと同じファイルをアプリケーション起動時に全て読み込んでおくということになっています.

よく lib 以下を config.autoload_paths << Rails.root.join("lib") といった風に追加しているのを見かけるし,実際に自分もやっています.

ここで問題になるのが, autoload_pathslib 以下を追加しているので,もちろん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があります.

github.com

色々議論されているんですが,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. 必要なファイルを適宜eager_load_pathsに追加する

まあ良い

あたりがあるのではないかと思われます.


自分も知らねーという感じだったし,こういったことは公式でドキュメントにすべきだというissueが立つも完全スルーのまま終わったり,

github.com

Upgrading guideもスレッドセーフなどには触れずにかなり曖昧な説明にしているあたりに特別な何かを感じるのだが,これは一体