5 分から 1 分に! yarn install の時間を劇的に短縮した話
yarn install (フロントエンドの依存ライブラリインストール) の時間が長くなってしまった原因の調査と、解決した記録です。
(今回はyarn v1を使用していますが、npmでは yarn why
の代わりに npm ls
を用いることで同様に調査可能です)
背景
とあるプロダクトで、いつの間にかyarn install (フロントエンドの依存ライブラリインストール) の時間に5分ほどかかるようになってしまいました。
一見はローカル環境での初回インストール時しか影響がなく感じるので気にしなくていいやと思いがちですが、よく考えると結構大きな問題です。
- ローカル環境の構築に時間がかかることにより、オンボーディングの手間が増加
- dependencies更新時に各ローカル環境でyarn installが必要なため、開発効率の低下
- CIの結果がすぐに分からないことにより、レビューの速度が低下
- CDの時間がかかることにより、マージからリリースまでの速度が低下
- CI / CDのコストが増大
そこで、時間をかけて調査と修正をすることにしました。
インストールに時間がかかるライブラリの特定
すべてのライブラリを再インストールするため、 node_modulesをまるごと削除します。
rm -rf node_modules
そして、再度インストールします。
yarn install --immutable
インストール中はターミナルを目視で眺めます。
そして、 Building fresh packages...
というステータスになったら注視します。今回のプロダクトでは次の画面の状態で2分かかっていました。
[4/4] Building fresh packages...
[-/11] waiting...
[2/11] fsevents
[-/11] waiting...
[-/11] waiting...
[8/11] node-sass
その後、次の画面になり、さらに2分ほどかかっていました。
[4/4] Building fresh packages...
[-/11] waiting...
[-/11] waiting...
[-/11] waiting...
[-/11] waiting...
[10/11] grpc
以上の結果から、 node-sass
と grpc
のビルドに4分かかっていることがわかります。
verboseモードにしてログを保存して分析することも最初は考えていたのですが、インストールに時間のかかるライブラリは目視で十分確認できました。
node-sass
については node-sass@4.13.1
がdependenciesに指定されていました。
しかし、 grpc
は指定していません。そのため、どのライブラリの依存関係になっているのか調べました。
yarn why grpc
yarn why v1.22.19
[1/4] Why do we have the module "grpc"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "grpc@1.24.2"
info Reasons this module exists
- "firebase#@firebase#firestore" depends on it
- Hoisted from "firebase#@firebase#firestore#grpc"
Done in 0.44s.
firebase
が依存していることがわかりますね。たしかに firebase@7.8.1
はインストールしています。
該当ライブラリの README の確認
原因は node-sass@4.13.1
と firebase@7.8.1
であることがわかったところで、ライブラリ該当のバージョンのREADMEを見に行ってみましょう。何かヒントがあるかもしれません。
node-sass
まずはnode-sassを調べてみます。
当時の README を参照すると、次のように記載があります。
Supported Node.js versions vary by release, please consult the releases page.
リリースページを要確認とのことで、リリースページを見てみると原因がわかりました。つい最近Nodeを14系にアップデートしたばかりだったのです。
Supported Environments
Node 0.10, 0.12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
Install runs only two Mocha tests to see if your machine can use the pre-built LibSass which will save some time during install. If any tests fail it will build from source.
通常はビルド済みのものをコピーするだけですが、今回サポート外のNodeバージョンだったため、毎回ソースコードからビルドしていたことがわかりました。
今回、影響を最小限度にするべく、Node 14をサポートしている最も近いバージョン4.14.1へアップデートすることにしました。プロダクトに影響のある差分がなかったので、もっと早く動いていれば良かったと反省しました。
firebase
次にgrpcに依存しているfirebaseのリリースノートを調べてみます。
7.14.0に次のようなリリースノートがありました。
Replaced grpc with @grpc/grpc-js in the Node.js builds. As a result, the minimum supported NodeJS version is now 8.13.0.
7.14.0未満は grpc
のソースコードを毎回ビルドしていましたが、7.14.0以降はビルド済みの @grpc/grpc-js
へ依存するようになったようです。
こちらも、7.14.0へアップデートすることにしました。
まとめ
yarn installの時間が5分から1分に短縮できました 🎉!
特にCIの速度が速くなったことによる恩恵が大きかったです。開発効率を大きく向上させることができました。
node-sassからdart-sassの移行など、他にも改善が必要なため着々と進めていく所存です。
Discussion