Reactの「再レンダリング地獄」を静的解析で封じ込める:ESLintを用いたパフォーマンス防衛術
こんにちは。現場の最前線で開発環境を磨き上げているエンジニアです。
React開発をしていると、ふとした瞬間に「なぜか画面が重い」「入力しただけで全体がカクつく」という現象に遭遇しませんか?その犯人の多くは、不要な再レンダリングです。
多くの人は「後からProfilerで計測して直そう」と考えがちですが、それは「火災報知器が鳴ってから消火器を探す」のと同じです。真のプロフェッショナルは、「火を出さない建築基準法」をコードベースに埋め込みます。
今回は、ESLintを使って、Reactのパフォーマンスを損なうコードを「書かせない」ための攻めの設定を伝授します。これをマスターすれば、あなたのコードはリリースされた瞬間から高パフォーマンスを維持します。
—
1. なぜ「静的解析」でパフォーマンスを最適化するのか
Reactの再レンダリングは、以下のメカニズムで発生します。
- Propsの参照透明性の破壊: 親がレンダリングされるたびに、新しいオブジェクトや関数が生成され、子コンポーネントが「Propsが変わった」と勘違いする。
- コンポーネントの肥大化: 複雑すぎる構造が一度の更新で広範囲なレンダリングを引き起こす。
これらは、開発者が「記憶」や「気合」で防ぐには限界があります。ESLintという機械の目に、「おっと、その書き方はパフォーマンスを破壊するよ」とリアルタイムで指摘させることこそが、開発効率を劇的に高める唯一の解です。
—
2. 必須の武器を装備する
まずは、ReactのHooksの依存関係を厳格に管理するためのプラグインをインストールします。
必要なライブラリをインストール
eslint-plugin-react-hooks: Hooksのルールを強制(依存配列の漏れを防ぐ)
eslint-plugin-react: React特有のベストプラクティスを強制
npm install –save-dev eslint-plugin-react-hooks eslint-plugin-react
—
3. 「攻め」のESLint設定:パフォーマンスの聖域を守る
ただインストールするだけでは意味がありません。以下の設定を `.eslintrc.js` に追加してください。これが、あなたのプロジェクトを「重くならないコード」へと導く防波堤になります。
module.exports = {
plugins: [
‘react’,
‘react-hooks’
],
rules: {
// 【重要】Hooksの依存配列を強制。これを怠ると、無限ループや古いStateを参照するバグが量産されます
‘react-hooks/rules-of-hooks’: ‘error’,
‘react-hooks/exhaustive-deps’: ‘warn’,
// 【重要】不要な再レンダリングを防ぐための独自ルール
// 関数コンポーネント内での関数定義を制限し、useCallbackの使用を促すための布石
‘react/jsx-no-bind’: [‘error’, {
allowArrowFunctions: false, // インライン関数を渡すと子コンポーネントが毎回再レンダリングされるのを防ぐ
allowBind: false,
}],
// コンポーネントのPropsの型定義を強制し、不要なPropsの伝播(Prop Drilling)を防ぐ
‘react/prop-types’: ‘off’, // TypeScriptを使うならoffでOK
}
};
なぜ `jsx-no-bind` を厳格にするのか?
多くの初心者がやりがちな `onClick={() => doSomething()}` という書き方。これはレンダリングのたびに新しい関数インスタンスを生成します。React.memoをかけていても、これでは無意味です。「インライン関数を禁止する」という制約を設けることで、必然的に `useCallback` を使う設計へと誘導されます。
—
4. HelloWorld的な動作確認:警告が「教えてくれる」体験
設定が効いているか確認しましょう。わざと「重くなるコード」を書いてみます。
// 悪い例:このコンポーネントは親がレンダリングされるたびに、
// 子コンポーネント(Button)が再レンダリングされます
const MyComponent = () => {
const handleClick = () => console.log(‘Clicked’);
// ESLintがここで「jsx-no-bind」ルールをトリガーし、エラーを出します
return
IDE(VSCodeなど)上でこのコードを書いた瞬間、`onClick={() => handleClick()}` の下に赤い波線が出ます。
これが「現場の知見」です。
開発者は、コードを完成させる前に、コンパイラから「その設計は効率が悪いよ」と指摘を受けるのです。これにより、後からProfilerで頭を抱える必要が完全になくなります。
—
5. さらに高みを目指す:アーキテクトからの助言
今回紹介した設定は、いわば「初動のガード」です。さらに突き詰めるのであれば、以下のステップを検討してください。
1. eslint-plugin-import: 巨大なライブラリの不要なインポートを制限し、バンドルサイズを小さく保つ。
2. TypeScriptとの併用: 型定義が正しくあれば、不要なPropsの受け渡しが型エラーとして可視化され、コンポーネントの疎結合が自然と促進されます。
開発環境を整えることは、「自分自身がミスをする隙を削る」という行為です。最初はルールに縛られているように感じるかもしれませんが、一度この快適さに慣れてしまうと、もうルールなしのプロジェクトには戻れなくなります。
明日からのコーディングで、赤い波線を「煩わしいもの」ではなく「守護天使」だと思って付き合ってみてください。あなたのコードは、驚くほど軽快で、堅牢なものに変わるはずです。
もし設定で詰まったら、いつでも戻ってきてください。また次の高みへご案内します。