Gobble up pudding

プログラミングの記事がメインのブログです。

MENU

Angular5のmain.bundle.jsが重いのでSpring BootのGzip圧縮を試してみる

スポンサードリンク

f:id:fa11enprince:20180611025013j:plain Angular6出ましたね!割と前に…
Angularを使っています。Angularは割といろいろ好きなところはあるのですが、
やはり、FullのSPAを作っているならまだしも、そうでないので、
趣味&実験でプロダクトにぶっこんだ側面もあるので、いろいろ困難があります。
まぁ、端的に言うと、作ろうとしているものに対しての選定ミス。
おとなしくVue.jsとかが向いていたと思います。
そこで今回、重大だ、という問題について書きます。

Angularのmain.bundle.のサイズでかい問題

Angularのmain.bundle.jsが重い問題。
貧弱なネットワークの中ではこれがとても問題になる。
1M超えのJSはやっぱりちょっときつい…
何とかしたい。Angular5を使っているのだがどうにもならない…。
なんででかくなるかはわかっている
JQuery, Momentを使っているからだ。
JQueryは対処しようがなく、使用しないしか対処法がない。
Momentはlocaleを絞ればよい。
それでもでかい…1MBを切るのが難しい。
いろいろ調べると--vendor-chunck=trueを付けるといいとかでてくるが、これは意味がない。
main.bundle.jsのかわりにvendor.bundle.jsのサイズがでかくなるからだ。
Angular6に実験で上げてみるも、あんまり効果ない&RxJSの書き換えがだるい…ので諦めました。
時間があったらバージョンアップしたい。

いろいろ調べてみる

やはりjQuery, Lodash, Momentあたりを使ってると部分的な対策はあるものの(特にMomentのlocaleとか)、
根本的な対策はないようだ。
そもそもそれらを使わないというのがベストなのだが、どうしようもない事情があるのも確か…。

https://github.com/angular/angular/issues/16850
によると…

元の文

" it shouldn't be expected to use gzip in order to get a realistic file size." If being lightweight is crucial to your project, you might want to consider trying out a view library like React or VueJs until angular properly supports server-side rendering and platform-server is documented. Unfortunately, since angular is a complete framework, its size is large and getting the porduction files to less than 100kb even with compression is not trivial [I've read some people experimenting with the closure compiler getting builds ~50kb in size]

" As I said, the servers I'm using do not support gzip" . The express compression middle-ware does the compression on the fly as a client requests the resources and does not need the server to support gzip files, meaning that the files you'll be uploading to your server are going to be the original files built using ng build command as-is, without being compressed.

翻訳

「(サーバがgzip圧縮に対応してないので)現実的なファイルサイズを得るためにgzipを使用することは期待できません。」 軽量であることがプロジェクトにとって重要なら、サーバサイドレンダリングやplatform-serverを適切にサポートしていることがドキュメントに書かれるまで、ReactやVueJsなどのViewライブラリを試すことを検討することをお勧めします。 残念ながら、Angularは完全なフレームワークなので、サイズは大きく、圧縮してもporductionファイルを100kb未満にすることは自明ではありません。 [私はclosureコンパイラを使って~50kbのサイズをにしたというのを読んだことがあります]

「私が言ったように、私が使用しているサーバはgzipをサポートしていません」 。 Expressのオンザフライで圧縮を行うミドルウェアがあるので、gzipファイルをサポートする必要がありません。つまり、サーバーにアップロードするファイルは圧縮されずにng buildのそのままということになります。

端的に言うと、それなりのbundleのサイズは覚悟しろってことか。

他にもSSRを使えというのがあるが、そもそもサーバサイドはExpressじゃなく、Javaなので使えない…
部分的に導入ってのもありはありだが、めんどくさい事がかなり増える。
そもそもExpressは好きじゃない(そういう問題ではない)。
JavaでSSRを行うものもGitHubに上がってるが、今後のバージョンアップに追随できるか謎なのでまっとうな方法でいきたい。しかし、このやりっぷりには感動した。
ちなみにJNIでV8をたたいてる……ものだった。
github.com そのほかの方法としてはLazy Loadingか…。

ということで…
結論としてはGzip圧縮を試みようということになった。
幸い、使っているものはSpring Bootなので、Gzip圧縮を気軽に試せる。
もちろん、古き良きApacheにもモジュール追加でその方法は試せるが。

Gzip圧縮を使ってみる

まずはAOTビルド時のサイズ

Time: 119604ms
chunk {scripts} scripts.bundle.js (scripts) 398 kB [initial] [rendered]
chunk {0} main.bundle.js (main) 1.16 MB [initial] [rendered]
chunk {1} polyfills.bundle.js (polyfills) 169 kB [initial] [rendered]
chunk {2} styles.bundle.css (styles) 219 kB [initial] [rendered]
chunk {3} inline.bundle.js (inline) 1.36 kB [entry] [rendered]

SSDのそこそこのスペックのマシンだが11sかかってる…。そして1.16MB…
もちろん、RxJSとかのimportは極小になるように頑張っている

Spring Bootの公式サイトによると

server.compression.enabled=false # If response compression is enabled.

がデフォルトのことなので、

application.yamlを書き換える

server:
  compression:
    enabled: true
    mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css

Chromeの帯域制限で計測

kamatama41.hatenablog.com に記載の方法で試してみる。 Fast3Gで計測

圧縮前 f:id:fa11enprince:20180709224402p:plain 圧縮後 f:id:fa11enprince:20180709230852p:plain 帯域を絞ると…だいぶ早くなってますね!

GZIPで返ってこないと少しハマった件

ちなみにですが、あれれ?gzipでレスポンス返ってきてない!!とおもってハマりました。 アンチウィルスのESETのせいでgzipで受け付けなかったようです。 f:id:fa11enprince:20180709230605p:plain ここの設定をOFFにしないとダメでした(ファイヤーウォール全無効にするだけじゃダメでした) github.com