このポエムで言いたいこと
- いらなくなったコード、リソースはいらないと分かった瞬間に消すのがもっとも低コストである
- 不要なコンフィグ、コードは確実に後の世代の枷になる
だから、適切なタイミングで、ごみはごみ箱に捨てましょう。
原因編
不要コードはどう生まれるか
コードは書いた瞬間から技術負債になりえる、ということが言われるように、エンジニアの日常運用・開発のいたるところで不要なコード、リソースは誕生しています。
例えば、
- 関数Aがわかりにくかったので作り変えて関数Bに変更した
- 関数Aが不要になる
- すぐもどせるように一部コメントアウトして動作確認した。確認が取れたのでコメントアウトもろともコミット、マージした
- コメントアウト行が不要である
- アーキテクチャ変更としてEC2インスタンスで動いていたサーバをECSで稼働するように変更した
- EC2やEC2に付随していたIAMロール・セキュリティグループなどが不要になる
- 内製ツールで頑張っていたが、便利なSaaSを見つけたのでそちらに乗り換えた
- 内製ツールが不要になる
などといった具合ですね。
1行なのか、1ファイルなのか、1ディレクトリなのか、あるいは複数なのか。
それは場合によって違うけれど、日常タスクのいたるところで実は不要なコードはたくさん誕生しているのではないかな、と考えています。
不要コードはどう生きながらえるか
以下3つが主な要因かなと考えますが、端的には
ビジネス的リターンがほぼ皆無であるという理由に集約されるのではないでしょうか。
別に消さなくても動く
ビジネスサイドが考えることで、プロダクトの挙動という観点では不要物があろうとなかろうと問題なく動いているのだからいいじゃん、ということ。
たしかに間違ってはいないですね。
対応コストが必要
消すことはただではない。
「不要なコードを削除する」ための工数が必要となります。しかしプロジェクトも佳境、リリースに向けてタスクがたくさん積まれている中では、なかなか削除作業に工数を払うことができないのが実情でしょう。
リスクテイクが必要
「ほんとうにここを消して問題ないのか?」
不要だと感じても、確証を得るのには調査も必要ですし、もししくった場合の影響は少なからず考えなければなりません。
コード削除のリスクなり、機能削除のリスクなり、だれかしらプロダクトオーナーと合意をとって進めないといけないことが多いでしょう。その際にリスク度合いの説明等も必要になります。
後で消します / 削除タスクを積みます = ほぼ消えない
自分もコードレビューの際に、「このコードは不要なのでは?」というコメントを残したことが少なからずあります。
そのときによく返ってきたのが、
- いまは動作確認を先にやりたいのであとで消します
- 削除タスクのIssueを作っているのでそちらでやるようにします
というコメントでした。
理屈は間違っていないですね。
しかし、自分の経験上、「後で消します」と言われたコードの大半は消えません。
理由は前述している通りで、結局不要物の削除という対応は優先度が低くなり、ほかのタスクに押しつぶされることが往々にしてあるからです。
影響編
割を食うのはだれか
未来の自分とチームメンバー全員が影響を受けます。
開発する機能やコードの場所は違っても、既存コードは少なからず参照するものです。不要なコードが残っていると、既存コードや既存リソースを理解するための認知負荷が上がってしまいます。
とにかく認知負荷が上がってしまっている状態になります。
ちなみにconfig系に無駄な設定(つないでもいないのに、Saasやインフラリソースのエンドポイント設定)が残っていると、インフラ・プラットフォーム・SREあたりが割りを食うことがあります。
まさに自分はこれによって結構な時間を持っていかれています。
また、あるいはコードの残し方によってはユーザーへのパフォーマンス影響が出ることもあるかもしれません。
どうしてすぐに消すのがいいと考えるか
その瞬間こそ、一番認知レベルが高いと考えられるからです。
不要だと判断できる情報を一定量持っている人がいる、ということが間違いない状態ですね。
これが、たとえば2ヶ月くらい放置して別の人が不要そうだなと気付いたとしても「まず不要そうだけど、ほんとうに不要なのか調べる」ためのアクションが追加で必要になります。
不要だと気づいた・わかったときが一番情報確度としては高いはずです。
未然対処編
ここでは不要コード、リソースをできるだけ生み出さないこと、および運用負荷をできるだけ下げるためにできることをいくつか考えてみました。
コード
- リンター・静的解析ツールの活用
未使用の変数、関数、importなどを自動検出するツール(ESLint、Knipなど)を導入し、CI/CDパイプラインに組み込みましょう。
機械的に検出できるものは自動化することで、レビュー負荷も下がります。
- コードレビューでの不要コード削除の徹底
レビュー時に不要なコードを見つけたら、その場で削除を依頼しましょう。
AIレビューの観点に、使われていないコードがあればこれを指摘する、などといれると効果的だと思います。
- 不要だとあたりが付いている部分にコメントをいれる
これは運用負荷を下げる目的です。
理由と統一的なprefixをコメントしておくと良いと思います。
コメントがあったところで意味がないのではという意見もありますが、自分的にはあってくれたほうが嬉しいものです。もちろん消えてくれている方が良いのですが。
// deprecated: funcBに移行されたので使われていないはず
func A()
リソース
- IaC(Infrastructure as Code)の徹底
手動で作ったリソースは消し忘れます。
不要インフラリソースが残ってしまった理由の大半がこちらでしょう。
コードで管理(Terraform等)することで、変更PR内に削除変更が組み込まれて残る確率が減ると想定されます。
- タグを付ける
すぐには消しづらいというケースの場合は、タグにその旨を記録しましょう。
タグの追記であれば影響を及ぼすことはなく、検索時にこのタグを条件にいれることで一覧化することが可能です。
- 明らかにテスト用のリソースは名称のprefixで見分けがつくようにする
開発環境においてもごみが残るのはよろしくないです。
前述のタグでも問題ないですが、deletable-やtest-などというような名称prefixをつけておくとよりわかりやすくなるかなと思います。
- 不要となるリソースは削除する、または検証用リソース削除までのタスクを積む
タスクの完了条件に不要なリソースを残さないことを明記しましょう。
強い効果はないですが、この対処が効いたケースもありました。
事後対処編
あとから不要だとわかったケースで有効じゃないかと考えていることです。
今回ここが主張点ではないので、簡単に流して書いてあります。
コード
いくつか分析手法があるのでこれを組み合わせてみるのが良いと思います。
実際過去の現場では、以下のうちの1と2は定期的に行っていました(実際に消したかどうかはまた別問題)。
- 言語別に静的解析ツールを利用(ex. TypeScript: Knip)
- 異常に低いカバレッジで観測
- エディタの機能によって観測
- GitHub Dependenciesグラフなどの依存グラフによって観測
- AIツール(ClaudeCodeなど)によって推測
リソース
主にインフラストラクチャリソース。こちらはより労力がかかるところです。が、リソースによっては立っているだけでコストになるようなものもあるため、できるだけ削除したいところ。
しかし困った。コードよりもリスクが高い。慎重にやらないといけない。
例えばデータベースが不要そうであれば、
- ソースコードのConfig一式を確認して、当該エンドポイントを設定しているサービスはないか
- モニタリング項目で流れたクエリ数やCPUなどで稼働している可能性有無を確認
- いざというときにすぐに戻せる状態で削除試行できないかを考える
- 実施とモニタリングを一定期間継続する
- 完全削除実行
とざっくりでも結構な手順と労力がかかってしまうことは致し方ないと思います。
自分もインフラ周りを担当するため、この手のことはやってきたのですが、実際削除するまでにはそこそこの工数を要してしまいます。
とはいえコスト削減という効能はあるので、多少は工数交渉がしやすいです。
まとめ
ということで、少しずつでいいのでいらないものはちゃーんとごみ箱に捨てましょう。
蛇足
これを聞いていて、ふと思いついただけなのですばらしく低クオリティ。