開発におけるジャンクとは — ジャンクコードの害と除去方法

著者: IT Sectr 公開日: 2026-07-27 読了時間: 10 分

ジャンクコード(junk code)とは、プロジェクトに利益をもたらさないが、そのサイズ、ビルド時間、チームの認知負荷を増大させるコードと依存関係を指します。決して実行されないデッドコードとは異なり、ジャンクは動作する可能性がありますが、非効率的または冗長に動作します。重複ライブラリ、未使用のインポート、コメントアウトされたブロック、古いポリフィル、装飾的な抽象化などです。CodeScene Code Health Report(2025)によると、モバイルプロジェクトの依存関係の平均15パーセントは直接使用されておらず、推移的なパッケージを引き込むだけです。ジャンクコードはプロジェクトの“余分な重み”であり、コードベースを厚くするだけで強くはしません。定期的な依存関係の監査と冗長な抽象化の削除は、ビルド速度とコード品質を直接向上させます。

重要なポイント

  • ジャンクとは、利益なくプロジェクトサイズを増大させる役に立たないまたは冗長なコードと依存関係です。
  • ジャンクの種類:デッド依存関係、重複ライブラリ、コメントアウトされたコード、空の抽象化。
  • ジャンク依存関係は攻撃対象領域を増やし、CIパイプラインを遅くします。
  • 監査ツール:Gradle dependencies(Android)、SwiftPM audit(iOS)、depcheck(Node.js)。
  • 定期的なジャンクの掃除は、新しいコードを書くのと同じくらいプロジェクトメンテナンスの一部です。

ジャンクコードとは?

ジャンク(junk code)とは、プロジェクトに存在するが機能的価値を提供しないコード、設定、依存関係を指す包括的な用語です。ジャンクは必ずしも壊れていたり未使用だったりするわけではありません — 問題は、その存在が適切な正当化なしにプロジェクトのメトリクスを悪化させることです。

ジャンクは4つのカテゴリーに分類されます。1つ目は冗長な依存関係:標準ツールで実装できる単一機能のために追加されたライブラリ。2つ目はデッドウェイト:コメントアウトされたブロック、チケットなしのTODO、空のメソッド、スタブクラス。3つ目は重複ソリューション:同じことを行う2つのライブラリ(例:1つのプロジェクトにGsonとKotlin Serializationの両方)。4つ目は過剰エンジニアリング:使用されていないが「念のため」維持されているアーキテクチャ層。

Stripe Engineering Productivity(2025)の調査によると、典型的なプロジェクトから10パーセントのジャンクを削除すると、完全ビルド時間が平均22パーセント短縮されます。理由:余分な依存関係はビルドグラフを増やし、空の抽象化は理解に時間を要し、コメントアウトされたブロックは注意を散らします。

ジャンクとの戦いにおける主な困難は、即時の結果がないことです。ジャンクコードのあるプロジェクトはコンパイルされ動作します。問題は徐々に蓄積されます:ビルドが遅くなり、推移的依存関係の数が増え、1年後には新機能の追加に必要な時間の2倍かかるようになります。

ジャンク依存関係とその特定方法

ジャンク依存関係とは、プロジェクトに追加されたがコードで直接使用されていない、または標準APIで実装する方が簡単な単一機能にのみ使用されているライブラリとパッケージです。

典型的な例:プロジェクトが既にKotlin Serializationを使用している場合のJSON処理ライブラリ(2つのパーサーはジャンク);Kotlin拡張isNullOrBlankで置き換え可能な単一のStringUtils.isEmpty呼び出しのためのApache Commons Langライブラリ;10モジュール中1モジュールで使用され、他は手動でコンストラクタ経由で依存関係を受け取るDIライブラリ。

余分な依存関係は単にバイナリ内の余分なコードだけではありません。脆弱性に対する攻撃対象領域を増やします:GitHub Advisory Database(2025)によると、モバイルプロジェクトの重大なCVEの40パーセントは、開発者が制御できない推移的依存関係から来ています。依存関係が少なければ少ないほど、攻撃対象領域は小さくなります。

Androidプロジェクトの依存関係分析

groovy
// View Gradle dependency tree
./gradlew app:dependencies --configuration releaseRuntimeClasspath

// Find unused dependencies (Gradle plugin)
plugins {
    id "com.autonomousapps.dependency-analysis" version "2.0.0"
}

// Generate unused library report
./gradlew buildHealth

iOSの場合は、swift package show-dependenciesコマンドを使用して完全な依存関係ツリーを表示します。Xcode Build Timelineツールは各ライブラリがビルドにどれだけの時間を追加するかを示します。ライブラリがコンパイル時間の30パーセントを占めているが単一画面でしか使用されていない場合、削除または置き換えの候補です。

Node.js(React Native)の場合は、depcheck — package.jsonで未使用の依存関係を見つけるユーティリティ、およびnpm-check — 古いバージョンも表示するユーティリティを使用します。「なぜ標準ツールが使えないのか」の正当化とともに、すべての新しい依存関係はコードレビューを通過するというルールを導入します。

デッドインポートとコメントアウトされたコード

デッドインポートは最も一般的なジャンクです。ランタイムには影響しませんが、コンパイル時間を増やします:コンパイラは未使用のものも含めてすべてのインポートを処理します。大規模プロジェクトでは、未使用のインポートを削除するとビルド時間が5–10パーセント短縮されます。

最新のIDEは未使用のインポートを自動的にグレーでハイライト表示します。ファイル保存時の自動クリーンアップを設定:IntelliJ IDEAではOptimize Imports on the fly、XcodeではEditor > Remove Unused Imports。CIにチェックを追加:リンターが未使用のインポートを含むコミットをブロックするようにします。

コメントアウトされたコードも別の種類のジャンクです。開発者はリファクタリング中に機能を「失わない」ためにブロックをコメントアウトします。しかし、gitは変更の完全な履歴を保存します:削除されたコードは1つのgit revertまたはgit log -S コマンドで復元できます。masterのコメントアウトされたコードはチームに対する軽蔑です:各開発者は「なぜこれがコメントアウトされていて、いつアンコメントすべきか」という質問に精神的エネルギーを費やします。

ルール:リポジトリにコメントアウトされたコードはありません。コードが不要な場合は完全に削除します。コードが必要だが一時的に無効化されている場合は、チケットと有効期限付きのフィーチャートグルを使用します。// TODO: remove after migrationのようなコメントは期限なしで残さないでください。日付を設定し、カレンダーで自分にリマインドします。

冗長な抽象化と過剰エンジニアリング

過剰エンジニアリングとは、現在の問題を解決しないがメンテナンスを必要とするアーキテクチャ層を作成することです。これは最も厄介なジャンクの1つです。なぜなら形式的にはコードは「正しく」、SOLIDに従い、テストでカバーされ、アーキテクチャに準拠しているからです。問題は不要であることです。

典型的な例は、単にリポジトリを呼び出す1つのinvokeメソッドを持つ抽象UseCaseクラスです。UseCaseがロジック(キャッシング、リトライ、変換)を追加せず、呼び出しを通過させるだけなら、それは余分なエンティティです。プロジェクト内のナビゲーションを増やします:開発者はUseCaseを開き、invoke → リポジトリを見て、閉じます。時間の無駄、利益ゼロ。

別の例は過剰なパラメータ化です。6つの型パラメータを持つジェネリックインターフェースが1か所でのみ使用されています。各型パラメータは認知負荷です:コードを読むとき、実際には2つしか使われていないのに6つの型を頭に入れておく必要があります。抽象化が再利用されない場合、それは冗長です。

判断基準:抽象化が3つの異なるコンテキストで再利用されない場合、削除します。抽象化は、実際に重複問題を解決する場合に正当化され、仮説的な将来シナリオを予測する場合には正当化されません。YAGNI(You Ain’t Gonna Need It)は過剰エンジニアリングを防ぐ最良の原則です。

ジャンク監査ツール

ジャンク監査には、静的解析、依存関係分析、手動レビューの組み合わせが必要です。冗長な抽象化の検出を完全に自動化することは不可能ですが、技術的なジャンク(デッドインポート、未使用ライブラリ、コメントアウトされたコード)はツールで見つけることができます。

カテゴリツールチェック内容
未使用の依存関係dependency-analysis(Gradle)コードで未使用のライブラリ
未使用の依存関係depcheck(Node.js)インポートなしのpackage.jsonパッケージ
未使用の依存関係swift package --show-dependenciesSwiftPM依存関係ツリー
デッドインポートIDE(Optimize Imports)未使用のimport文
コメントアウトされたコードgrep -r “//” / rg “^\s*//”コードを含むコメントブロック
空のメソッド/クラスSonarQube / CodeClimateボディなしまたは空ボディのメソッド
重複ライブラリGradle lint(duplicate classes)異なるライブラリからのクラス競合

完全な監査のために、スプリントごとにbuildHealth(Android)またはdepcheck(Node.js)を実行します。スプリントごとの依存関係数の推移を示すCIダッシュボードを作成します。数が増えているが機能が比例して増えていない場合、チームはジャンクを蓄積しています。

重複クラスに注意してください — 2つのライブラリが同じクラスを含む場合に発生するエラーです。これはジャンクであるだけでなく、ビルド競合の直接的な原因です。Gradleでは、これらの競合はforceまたはexcludeで解決されますが、そのような解決のたびにどちらかのライブラリが不要であるシグナルとなります。

定期的なプロジェクト掃除プロセス

ジャンクの掃除は一度きりの行動ではなく、定期的なプロセスです。手順がなければ、ジャンクは2–3スプリント以内に戻ってきます。ベストプラクティスは、各スプリントの容量の10–15パーセントをジャンク監査を含む技術的クリーンアップに割り当てることです。

プロセスは4つのステップで構成されます。1つ目は診断:ツールを実行し、レポートを取得し、優先順位を付けます。高優先度:既知のCVEがある依存関係と重複ライブラリ。中優先度:デッドインポートとコメントアウトされたコード。低優先度:冗長な抽象化(手動分析が必要)。

2つ目はクリーンアップ:デッド依存関係を削除し、重複ライブラリを1つに置き換え、コメントアウトされたコードを削除します。各変更は明確なメッセージとともに個別のコミットにする必要があります:「remove unused dependency: gson (replaced by kotlinx.serialization)」、「delete commented code in LoginViewModel」。

3つ目は検証:プロジェクトをビルドし、テストを実行し、UIを確認します。依存関係を削除した後にテストが通れば、その依存関係は本当に不要でした。テストが失敗した場合、静的解析器が検出しなかった隠れた参照がどこかに残っています。

4つ目は予防:コードレビューチェックリストを更新し、Definition of Doneに「正当化なしの新規依存関係禁止」ルールを追加し、CIに自動チェックを設定します。予防こそがジャンクの再蓄積を防ぐ唯一の方法です。

よくある質問

ジャンクと技術的負債の違いは?

技術的負債は意識的な妥協(速いが品質が低い)であり、修正が計画されています。ジャンクは意識的な決定ではなく、蓄積されたゴミです:誰も計画しておらず、維持したがっていない余分な依存関係、コメントアウトされたコード、空の抽象化。

どのくらいの頻度でジャンクを掃除すべき?

最適なリズムは各スプリントの10パーセントを技術的クリーンアップに割り当てることです。これにより、クリティカルマスを蓄積せずにジャンクを制御下に置けます。プロジェクトにジャンクが多い場合は、1回の大掃除スプリントから始め、その後定期的なリズムに移行します。

チームにジャンク削除を納得させるには?

数値を測定して示します:3–5の余分な依存関係を削除する前後のビルド時間を測定します。ビルドあたり15–30秒の短縮に1日あたりのビルド数を掛けると、チームの節約時間が何時間にもなります。数値は抽象的な清潔さの呼びかけよりも説得力があります。

プロジェクトが安定している場合でも依存関係からジャンクを削除すべき?

はい、特に依存関係にCVEがある場合。プロジェクトが安定していても、推移的依存関係の脆弱性はセキュリティリスクです。さらに、SDKや言語を更新する際、古い依存関係が互換性を失う可能性があり、アップグレード前に削除することで移行の時間を節約できます。

コード内のTODOはどうする?

チケットのないTODOはすべてジャンクです。ルールを設定:TODOは// TODO(PROJECT-1234): fixの形式でトラッカーのタスクにリンクしてのみ書かれます。定期的にTODOを確認し、関連性を失ったものをクローズします。期限切れのTODOは削除します — 問題が6ヶ月間顕在化しなければ、それは重要ではありません。

まとめ

  • ジャンクは、利益なくプロジェクトを増大させる役に立たないコード、未使用の依存関係、冗長な抽象化です。
  • 4つのカテゴリ:冗長な依存関係、デッドウェイト、重複ライブラリ、過剰エンジニアリング。
  • 余分な依存関係はビルド時間、攻撃対象領域、認知負荷を増加させます。
  • 監査ツール:dependency-analysis(Gradle)、depcheck(Node.js)、SonarQube、コメントアウトされたコードのgrep。
  • 定期的なクリーンアップ:スプリントの10–15パーセントを技術作業に、依存関係監査はスプリントごとに1回。
  • 予防:新しい依存関係チェック付きコードレビュー、設計におけるYAGNI、インポートの自動クリーンアップ。
  • ルール:正当化なしの新規依存関係禁止、チケットなしのTODO禁止、masterにコメントアウトされたコードの行なし。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください