CIが「重い」は怠慢である:ESLint Performance Profilingでボトルネックを秒で特定する技術
「CIのLintチェックに5分以上かかる」。もしあなたのチームでそんな会話が聞こえてくるなら、それは開発環境のアーキテクチャが腐敗し始めている証拠です。
ESLintは強力ですが、プラグインが増え、巨大なモノレポを構築するにつれ、その解析コストは幾何級数的に増大します。多くのエンジニアは「ルールを減らす」という解決策に逃げますが、それは本質的ではありません。問題は「どのルールが、どのファイルを、どれだけの時間浪費しているか」を可視化できていないことにあります。
今日は、ESLintの隠された深淵、`–profile` オプションを駆使したパフォーマンスチューニングの真髄を伝授します。
—
1. 勘に頼るな:`–profile` でボトルネックを白日の下に晒す
ESLintには標準で実行時間をプロファイリングする機能が組み込まれています。これを使わずに「なんとなく遅い」と悩むのは、目隠しをしてデバッグするようなものです。
まずは、以下のコマンドを実行してください。
–format=table を指定することで、どのルールが時間を食っているか一目でわかる
npx eslint . –ext .ts,.tsx –format=table –profile
これを実行すると、ターミナル上にルールごとの実行時間が表示されます。ここで見るべきは「Total Time」と「Average Time」の乖離です。
- Total Timeが高い: 実行回数が多い、または重い処理が走っているルール。
- Average Timeが高い: そのルール自体が複雑な構文解析を要求している(正規表現が重い、ASTの探索が深いなど)。
実務での活用:CIボトルネックの特定
CI上で実行する場合、ログをファイルに吐き出させることが重要です。
CI環境で実行し、結果をレポートとして出力
npx eslint . –profile –format=json > eslint-report.json
このJSONをパースして、特定のルールが全体の実行時間の20%以上を占めている場合、そのルールは即座に「最適化」または「削除」の対象です。
—
2. なぜ「重い」プラグインが存在するのか?
多くのケースで、パフォーマンスを低下させているのは `eslint-plugin-import` や、特定の正規表現を多用した `custom rule` です。これらはファイルを開くたび、あるいはキャッシュを読み込むたびにファイルシステムのI/Oを激しく叩きます。
解決策:神プラグイン『eslint-plugin-perfectionist』とキャッシュ戦略
ルールを闇雲に増やすのではなく、AST(抽象構文木)を効率的に走査するプラグインを選定することが重要です。
絶対に入れるべき設定:
`eslint-plugin-import` の代わりに、最新の依存関係管理を効率的に行う仕組みを取り入れましょう。また、CI/CDパイプラインでは必ず `–cache` を有効化してください。
{
“//”: “CI環境では –cache オプションを必須とする”,
“eslint”: “eslint . –ext .ts –cache –cache-location .eslintcache –cache-strategy content”
}
- `–cache-strategy content`: ファイルのタイムスタンプではなく、ハッシュ値でキャッシュを判断します。CI環境で頻発する「キャッシュが効かない」問題を根絶します。
—
3. ベストプラクティス:設定のモジュール化と共有
チーム開発において、`.eslintrc.js` が1000行を超えているなら、それは設計の敗北です。以下の構成が、現代のフロントエンド開発におけるベストプラクティスです。
推奨される構成例:`.eslintrc.js` の分割定義
module.exports = {
// 拡張性を担保するためにベースを分離
extends: [
‘./config/base.js’,
‘./config/typescript.js’,
‘./config/performance.js’ // ここにパフォーマンス制御ルールを隔離する
],
rules: {
// 開発体験を損なうほど重いルールはここで個別に調整
‘@typescript-eslint/no-explicit-any’: ‘warn’,
}
};
パフォーマンス最適化のためのキー設定:
`config/performance.js` の中で、特定の重いルールに対して `off` にするのではなく、「特定のディレクトリだけ対象外にする」という制御を行ってください。
// override を活用し、重い解析を全ファイルに適用しない
overrides: [
{
files: [‘/__tests__//’],
rules: {
‘@typescript-eslint/no-floating-promises’: ‘off’ // テストコードでは厳格さを下げて速度を優先
}
}
]
—
4. 伝説のDevOpsリードが教える「極限の効率化」テクニック
最後に、IDE(VSCode)を最大限に活かすショートカットと設定を伝授します。
「lint-on-save」は捨てろ
ファイル保存のたびに全ファイルを解析するのは、現代のプロジェクト規模では狂気の沙汰です。以下の設定を `settings.json` に記述してください。
{
“eslint.validate”: [
“javascript”,
“javascriptreact”,
“typescript”,
“typescriptreact”
],
“eslint.run”: “onSave”,
“editor.codeActionsOnSave”: {
“source.fixAll.eslint”: true
}
}
ただし、さらに踏み込むなら 「Husky + lint-staged」によるコミット時限定解析 に切り替えるべきです。IDEのリアルタイム解析は「警告」を表示するだけに留め、重い「修正」はコミット時に集中させる。これが、脳のコンテキストスイッチを最小化する唯一の道です。
最後に
ESLintのチューニングは、単なる作業の時短ではありません。それは「フィードバックループの高速化」です。エンジニアがコードを書いてからCIが通るまでの時間が短ければ短いほど、思考の深さは増し、アウトプットの品質は高まります。
今日から `eslint –profile` を実行し、あなたのプロジェクトを「重いコードベース」から「高速で洗練された開発環境」へとアップデートしてください。準備はいいですか?