nodejs-performance について
Node.js エンジニア向けの性能改善ワークフローです。実行経路への効果と動作の安全性を重視し、測定可能でレビューしやすい小規模な PR につなげます。
主な機能
- 01効果に基づく改善候補の順位付け
- 02変更前後のベンチマーク
- 03動作互換性を保つ最小限の修正
- 04対象を絞ったテストと回帰確認
- 05性能データとリスクの記録
活用シーン
- 01リクエスト経路の遅延改善を優先
- 02メモリやイベントループの負荷調査
- 03測定結果を添えた性能 PR の作成
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ microlinkhq/ skills --skill nodejs-performanceインストール後、Claude Code で/nodejs-performanceを入力して読み込まれたか確認します。
詳細
Node.js のパフォーマンス
このワークフローを使用して、Node.js のパフォーマンスやリソースに関する調査結果を、安全でレビューしやすい PR に変換します。
目標
- まず実行時間を改善します。意図された動作を変えずに、p50/p95/p99 レイテンシを低減し、スループットを向上させます。
- 実行時間の改善につながる場合は、CPU、メモリ、イベントループの遅延、I/O 負荷、ロック競合を低減します。
- 測定可能な効果のある、小規模で独立した変更をリリースします。
運用ルール
- 1 つの PR につき、最適化は 1 つにします。
- 常に、期待される効果が最も大きいタスクを最初に選びます。
- 意図された動作を確認し、変更時にはそれを尊重します。
- 高頻度で実行されるパスでは、リスクの低い変更を優先します。
- 起動が大規模環境でクリティカルパスに該当しない限り、初期化/起動時のマイクロ最適化より、リクエスト/ジョブの実行パスに関する作業を優先します。
- エビデンスを含めます。対象を絞ったテストと、変更前後のベンチマークが必要です。
効果を重視した選定
コーディングの前に、次のスコアを使って候補を順位付けします。
priority = (frequency x blast_radius x expected_gain) / (risk x effort)
各要素を 1~5 で評価します。
frequency:本番環境でそのパスが実行される頻度。blast_radius:影響を受けるリクエスト/ジョブ/ユーザーの数。expected_gain:見込まれるレイテンシ/リソースの改善度。risk:動作が退行する可能性。effort:エンジニアリングにかかる時間と変更範囲。
最も順位の高い候補を選び、ベースラインの測定で検証します。
スコアが近い候補が 2 つある場合は、エンドツーエンドの実行時間への効果がより明確なものを選びます。
優先順位の対象
まず、すべてのリクエスト/ジョブ/タスクで実行されるコードに取り組みます。
- リクエスト/ジョブのラッパーとミドルウェア。
- リトライ/タイムアウト/サーキットブレーカーのコード。
- 接続プール(DB/Redis/HTTP)とソケットの再利用。
- ストリーム/パイプラインの変換とバッファリング。
- シリアライズ/デシリアライズのホットパス(JSON、パーサー、スキーマ検証)。
- キューコンシューマー、スケジューラー、ワーカーディスパッチ。
- イベントリスナーの登録/解除のライフサイクルとクリーンアップロジック。
本番環境のプロファイルで正当化されない限り、優先度を下げます。
- 一度だけ実行される初期化/ブートストラップコード。
- まれにしか実行されない、管理/デバッグ専用の処理。
- 定常状態のクリティカルパスに含まれないティアダウン処理。
よくあるホットパスの問題
- 呼び出しのたびに不変の値を再計算する。
- コード/AST を繰り返し解析する。
- 同じ値を返す非同期検索を重複して行う。
- 一般的なケースの解析で、呼び出しごとに重いオブジェクトを割り当てる。
- ティアダウン/クローズ/破棄のパスで不要な await を行う。
- 大半を占める入力形式に対する高速処理経路がない。
- 依存先の状態が悪化したとき、リトライが無制限に続く、またはリトライストームが発生する。
- 同時実行数が過剰になり、メモリの急増や下流システムの飽和を引き起こす。
- 無効になっている場合でも、ログ/テレメトリー/メトリクスのフォーマット処理を行う。
実行ワークフロー
- 候補を1つ選ぶ
- 候補に優先順位を付け、優先度スコアが最も高いものを選びます。
- 問題を1文で説明します。
- 想定される影響(CPU、レイテンシー、メモリ、イベントループの遅延、I/O、競合)を示します。
- 実際に負荷がかかっていることを証明する
- 対象を絞ったマイクロベンチマークまたはシナリオベンチマークを追加します。
- 編集前のベースラインの数値を記録します。
- 実行時間の改善が目的の場合は、実際のリクエスト/ジョブのフローを含むシナリオベンチマークを優先します。
- リソースの問題では、プロセスのメトリクス(
rss、ヒープ、FD 数、イベントループの遅延)を記録します。
- 最小限の修正を設計する
- 動作に互換性のあるデフォルトを維持します。
- エッジケース用のフォールバックパスを追加します。
- 同じ PR で広範なリファクタリングを行わないようにします。
- 実装する
- 繰り返しの処理をなくす最小限のパッチにします。
- 変更が必要でない限り、インターフェースを安定した状態に保ちます。
- テストする
- 新しい動作とリグレッションを対象とするテストを追加/調整します。
- 関連するパッケージのテストを実行します(デフォルトではモノレポ全体のテストだけにしないでください)。
- バグが負荷時にのみ発生する場合は、並行処理/性能劣化に関するテストを追加します。
- ベンチマークを再実行する
- 同じパラメーターで同じベンチマークを再実行します。
- 絶対値と相対値の差分を報告します。
- まずレイテンシーの差分(p50/p95/p99、スループット)を示し、該当する場合は次にリソースの差分を示します。
- PR を作成する
- ブランチ名:
codex/perf-<area>-<change>。 - コミットメッセージ:
perf(<package>): <what changed>。 - リスクに関する注記と、ロールバックの容易さを含めます。
- 繰り返す
- レビューを待ってから、次の個別の改善に進みます。
ベンチマークのガイダンス
- 変更を1つに限定して切り分けられるよう、ベンチマークの範囲を絞ります。
- ウォームアップの反復を行います。
- 次の両方を測定します。
micro:操作単位のオーバーヘッド。scenario:リクエスト/ジョブのフロー、並行処理、依存関係の性能劣化条件。- 実行時間に関する作業では、判断の基準となるのはシナリオの数値です。マイクロの数値は補足的な根拠です。
- 必ず次の項目を出力します。
- 合計時間
- 1操作あたりの時間
- 該当する場合は p50/p95/p99 のレイテンシー
- 高速化率
- 反復回数とワークロードの形状
- 該当する場合はリソースのカウンター(
rss、ヒープ、ハンドル、イベントループの遅延)
リソース枯渇チェックリスト
- 各境界(イングレス、キュー、下流のクライアント)で並行処理数に上限を設けます。
- タイムアウトとキャンセルがエンドツーエンドで連携していることを確認します。
- リトライに上限があり、ジッターが加えられていることを確認します。
- リスナー/タイマー/インターバルが必ずクリーンアップされることを確認します。
- 成功時とエラー時の両方でストリームがクローズ/破棄されることを確認します。
- オブジェクトキャッシュにサイズ/TTL の制御があることを確認します。
CI/フレークへの対応
- CI でのみ失敗が発生する場合は、テストに一時的な診断ペイロードを追加します。
- リソース競合が原因の場合は、影響を受けるフレークテストのみをシリアル化します。
- 決定性の改善は、必要な場合を除き、本番コードではなくテストコードに加えます。
出力テンプレート
各 PR について、次の項目を報告します。
- 修正する問題。
- 負荷時に重要となる理由。
- 変更したコードの場所。
- 実行したテストと結果。
- ベンチマークの変更前/変更後の数値(実行時間を先に記載:p50/p95/p99 とスループット)。
- リスク評価。
- 次に最適化する候補。
コメント
Markdown 対応