npm installとnpm ciの動作確認を簡単にやっておいた

先週、npm installnpm ciについて調べて考えたことを書いたのだけど、ドキュメントを読んで、頭の中で考えたことをまとめただけなので、これだけだとちょっと気持ち悪いなと思って。簡単ではあるけど実際の動作を確認することにした。

bufferings.hatenablog.com

結果

だいたい想像どおりだった。今回のサンプルプロジェクトで実験した結果は次のとおり。

(1)と(2)は、キャッシュがない場合のnpm cinpm installの速さ。想像では「npm ciの方が多少速いのかな?」と考えていたけどほぼ同じだった。node_modulesがない状態から始まるので、npm cinpm_modulesを削除する必要がない。一方で、npm installも既存のnode_modulesをチェックする必要がなくて、package.jsonpackage-lock.jsonの内容をチェックするだけ。だから、やることがお互いにそんなに違わないってことなのかな。

(3)はnpm cinode_modulesのキャッシュにヒットした場合。これはキャッシュのリストアが終われば終わりなので、いちばん速い。ただし、フォールバックは効かないので、キャッシュにヒットしなかった場合に、違うバージョンのキャッシュを利用することができず、no cacheの場合の(1)と同じだけの時間がかかることになる。

(4)はnpm installnode_modulesのキャッシュにヒットした場合。フォールバックを考慮する場合、npm installを実行しておかないといけないので、その実行分の時間がかかる。今回は10秒程度。フォールバックを考慮しないなら、(3)と同じになる。

(5)はnpm installでフォールバックにヒットした場合を想定したもの。キャッシュとちょっと差分のあるpackage-lock.jsonを持たせてみたのだけど、差分が少なすぎてあまり(4)と時間に差がでなかった。もし、もっと差分がある場合は(4)より多少遅くなると思う。

(6)はnpm ci~/.npmのキャッシュにヒットした場合。今回、動作確認をしてみて気づいたのだけど、~/.npmの中はtar.gzで圧縮されているので容量が小さい。そのため、展開後のnode_modulesのキャッシュからのリストア(20秒くらい)よりも展開前の~/.npmのリストア(5秒弱)の方が速い。その後の、npm ciの実行は想像してたとおり多少時間がかかる。

(7)はnpm ci~/.npmのフォールバックにヒットした場合。これも差分が少ないからか(6)との差は見られなかった。

実験環境

適当にpackage.jsonを書いてpackage-lock.jsonを生成しただけのプロジェクトを用意して

CircleCIで実行して確認した。

最初はデフォルトのリソースクラス(medium)を使ってたのだけど、それだと処理が速くて差が分かりにくかったので、もうちょっとゆっくり確認したくてsmallに変えた。

まとめ

前回の記事と特に変わらず

  • プロジェクトが小さいうちは、特に何も気にしなくていい
  • プロジェクトが大きくなってきたら、npm ci+~/.npmキャッシュでスピードと安全性の両方をとっておくといい
  • プロジェクトが大きくて、ちょっとでも速くしたいならnpm install+node_modulesキャッシュを使ってもいいけど、安全性の担保(lockが更新されるリスクを回避)は自分でやる必要がある

個人的にはnpm installが好みだけど、素直にnpm ciを選んでおくのが、将来的にプロジェクトを受け取った人に優しいんだろうなと思うので、仕事ならnpm ciを選ぶかなと思った。

おまけ

CircleCIのNode.jsのOrbを参考にしたんだけど、install-packagesコマンドを使うと、~/.npmをキャッシュしてnpm ciを実行するみたいなので、これを使っておけばフォールバックもいい感じにやっておいてくれるので楽かな。

https://circleci.com/developer/ja/orbs/orb/circleci/node?version=5.0.3#commands-install-packages

すっきりした。