Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
106
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

JavaScriptライブラリ/プロジェクトのファイルサイズの問題点を見つける方法

ブラウザ向けのJavaScriptだとファイルサイズはある程度気になると思います。

この記事では、ファイルサイズの計測方法やボトルネックとなってるライブラリの見つけ方についてできるだけ簡単な方法をまとめます。

ファイルサイズ

ファイルサイズと一言にいっても、ブラウザでは大体minifyしてから配布するのでminify後のファイルサイズも重要です。

  • ソースコード自体のファイルサイズ
  • minifyしたファイルサイズ
  • minify + gzipしたファイルサイズ

コメントの多いソースコードはminifyするとかなり小さくなったりすることが多いので、ソースコード自体のファイルサイズでは比較しにくいです。
また、ソースコードにおいて assert モジュールを使っているとファイルサイズが10kb弱程度minify後で変わります。
assertモジュールは通常外しても問題ないので、unassertでビルド時に取り除きます。
色々ライブラリを使っているプロジェクトだとunassertするだけで5%程度ファイルサイズが減りました。
何がいいたいかというとminifyやビルドの方法でもサイズが異なります。
そのため、プロジェクトにおいてのファイルサイズは計測が結構面倒くさいという話を後半します。

minify後のファイルサイズを取得

minify後のファイルを得るにはbundle-sizeというツールを使うのが簡単です。

bundle-sizeでは指定したパッケージやentry pointをminifyしたファイルサイズを環境変数毎に一覧できます。

# bundle-size lib/index.js みたいなentry pointもいける
❯ bundle-size almin -e development -e production
almin@0.9.0

env          bundle  minify   gzip
--           116 kB  60.5 kB  16.6 kB
development  116 kB  60.5 kB  16.6 kB
production   116 kB  60.5 kB  16.6 kB

bundle-sizeはbundle後のファイルサイズのみで、依存ツリーを見ることはできません。(いまのところ)

一方、package-size-analyzerを使うと、パッケージや指定したentry pointでビルドした結果の依存ツリーを見ることができます。(逆にこちらはminifyした結果が見られない)

# -e でentry point 、 -j でstats.json
❯ package-size-analyzer -p almin
__ROOT__: 111.46 KB
  <self>: 17 B
  almin: 57.81 KB
    <self>: 55.86 KB
    object-assign: 1.95 KB
      <self>: 1.95 KB
  package-size-analyzer: 5.17 KB
    <self>: 0 B
    process: 5.17 KB
      <self>: 5.17 KB
  assert: 11.43 KB
    <self>: 11.43 KB
  util: 15.4 KB
    <self>: 15.4 KB
  inherits: 672 B
    <self>: 672 B
  events: 8 KB
    <self>: 8 KB
  lru-map-like: 7.84 KB
    <self>: 7.84 KB
  map-like: 5.13 KB
    <self>: 5.13 KB

ファイルサイズは本家だと単位付けてくれないので、PRを出しています。
(READMEもなくてアレなので、forkするかもしれないです)

bundle-sizeはBrowserifyを内部的に使いますが、package-size-analyzerは内部的にwebpackを使っています。

これらは、どちらかというライブラリのサイズを分析する向けとなっています。
実際のプロジェクトだと複雑なビルドが絡まっていたりするため、設定なしで使えるツールには限界がありそうです。

プロジェクトのライブラリ依存ツリーを見る

プロジェクトでは色々なライブラリを使うので、無駄にファイルサイズの大きいものがうっかり混ざっている事があります。dedupeされてないとかで二重に入ってしまうなどもありえます。
そういう場合は実際にbundleしているツールを使って、その結果から分析してみると分かりやすいです。

Browserifyを使っているプロジェクトで依存ツリーを見る

Browserifyで依存ツリーをみるにはdiscを使うのが簡単です。

$(npm bin)/browserify --full-paths src/index.js | discify --open

で依存ツリーを可視化して見ることができます。

webpackを使っているプロジェクトで依存ツリーを見る

webpackはプロジェクトの依存ツリーを分析するためのファイルをJSONで入手できます。
具体的に依存してるモジュールでどれが大きいのかを調べるには、webpackのstats.jsonを使った方法が分かりやすいです。

webpackでは--jsonでbundleしたモジュールの解析結果をJSONとして取得できます。

$(npm bin)/webpack --json --profile > stats.json

この結果取得できる stats.json を以下のツールなどに投げて見ると依存ツリーを可視化してみることができます。

詳しくはSurviveJS - Analyzing Build Statisticsを見ると良いです。

毎回jsonを吐いて、ブラウザで見るのは大変なのでコマンドラインで依存ツリーを見る方法としてwebpack-bundle-size-analyzerを使う方法が有名です。

次のようにパイプでstats.jsonとして吐いていたものを渡すだけで依存ツリーのファイルサイズを出してくれます。(ただしminify前のソースコードとしてのサイズです)

❯ $(npm bin)/webpack -p --json | webpack-bundle-size-analyzer
react: 581.8 KB (78.8%)
almin: 57.81 KB (7.83%)
  object-assign: 1.95 KB (3.37%)
  <self>: 55.86 KB (96.6%)
fbjs: 32.32 KB (4.38%)
util: 15.4 KB (2.09%)
assert: 11.43 KB (1.55%)
events: 8 KB (1.08%)
lru-map-like: 7.84 KB (1.06%)
map-like: 5.13 KB (0.695%)
process: 2.01 KB (0.272%)
object-assign: 896 B (0.119%)
inherits: 672 B (0.0889%)
react-dom: 63 B (0.00833%)
<self>: 14.85 KB (2.01%)

おわりに

webpack-bundle-size-analyzerのリポジトリにも書いてありますが、webpackのstats.jsonを使った方法は、minify後ではなくminify前のファイルサイズが表示されます。

Consequently the stats shown by webpack-bundle-size-analyzer will report sizes before minification. This should still give a pretty good idea of what contributes to your bundle size but some libraries will compress better than others, so they can be misleading.
-- webpack-bundle-size-analyzer

そのため、minify後のファイルサイズと依存ツリーを得る方法が今のところよく分かっていません。(stats.json自体にも入らない)

minify後の依存ツリーをみる方法やツールがあるならお知らせください。

この辺のツールはAlminのファイルサイズをビルド後 gzipで10KB以下にするため、計測する方法を調べてやりました。

追記(2019-02-06): 現在はwebpack-bundle-analyzerという優れたビジュアライズツールがあるので、最初はこれを利用することをおすすめします。
もっと詳細なデータをみたい、フィルターしたい場合はwebpackのstats.jsonファイルを見ていくと良さそうです。

おまけ

GitHubリポジトリの指定したファイルのサイズを表示してくれるbadgeサービスもあります。

Badge URL
Normal size
Gzipped size
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
106
Help us understand the problem. What are the problem?