yarn install の時間を 5 分から 1 分に削減した話

目次

はじめに

yarn install (フロントエンドの依存ライブラリインストール) の時間が長くなってしまった原因の調査と、解決した記録です。
(yarn v1 を使用していますが、npm でも同様の方法で調査可能です)

背景

とあるプロダクトで、いつの間にか yarn install (フロントエンドの依存ライブラリインストール) の時間に 5 分ほどかかるようになってしまいました。
一見はローカル環境での初回インストール時しか影響がなく感じるので後回ししがちですが、よくよく考えると結構大きな問題です。
  • ローカル環境の構築に時間がかかることにより、オンボーディングの手間が増加
  • dependencies 更新時に各ローカル環境で yarn install が必要なため、開発効率の低下
  • CI の結果がすぐに分からないことにより、レビューの速度が低下
  • CD の時間がかかることにより、マージからリリースまでの速度が低下
  • CI / CD のコストが増大
そこで、時間をかけて調査と修正をすることにしました。

インストールに時間がかかるライブラリの特定

まずは、ブラックホールこと node_modules をまるごと削除します。
rm -rf node_modules
そして、再度インストールします。
yarn install --frozen-lockfile
インストール中はターミナルを目視で眺めてみましょう。verbose モードにしてログを保存して分析するのも良いですが、インストールに時間のかかるライブラリは目視で発見できるレベルで遅いのですぐに分かると思います。
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-sassgrpc のビルドに 4 分かかっていることがわかります。
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.1firebase@7.8.1 とわかったところで、ライブラリ該当のバージョンの README を見に行ってみましょう。何かヒントがあるかもしれません。

node-sass

まずは node-sass を調べてみます。
sass/node-sass at v4.13.1
https://github.com/sass/node-sass/tree/v4.13.1
当時の README を参照すると、
Supported Node.js versions vary by release, please consult the releases page.
と書いてあります。リリースノートを見てみると
Release v4.13.1 · sass/node-sass
https://github.com/sass/node-sass/releases/tag/v4.13.1
Supported Environments Node 0.10, 0.12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
となっています。ここで察しました。Node を 14 系にアップデートしたばかりだったのです。
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 にアップデートすることにしました。
Comparing v4.13.1...v4.14.1 · sass/node-sass
https://github.com/sass/node-sass/compare/v4.13.1...v4.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.
Firebase JavaScript SDK Release Notes
https://firebase.google.com/support/release-notes/js#version_7140_-_april_9_2020
7.14.0 未満は grpc のソースコードを毎回ビルドしていましたが、7.14.0 以降はビルド済みの @grpc/grpc-js に依存するようになったようです。
こちらも、7.14.0 にアップデートすることにしました。

結果

yarn install の時間が 5 分から 1 分に短縮することができました 🎉
特に CI の速度が速くなったことによる恩恵が大きかったです。開発効率を大きく向上させることができました。

まとめ

  • yarn install の時間がかかると思ったより影響が大きいです
  • ライブラリの README をよく読みましょう
  • ライブラリは定期的にアップデートしましょう
  • Dart Sass に移行しなければ

シェア

Twitter
Facebook
はてブ
LinkedIn
LINE
Pocket