実務・技術解説
非機能要件の最低ライン:本番化で最初に確認すること
本番化で確認すべき非機能要件の最低ラインを整理します。性能・可用性・セキュリティ・保守性ごとに具体的なチェック項目を解説。
「機能は全部動いている。でも本番に出せない」——このパターンは珍しくない。理由のほとんどは非機能要件の未対応だ。
非機能要件とは「何ができるか」ではなく「どれだけ安全・安定・快適に動くか」を保証する条件だ。AIで作ったプロトタイプは機能要件を素早く満たす一方で、非機能要件はほぼ必ず後回しになる。なぜなら、AIは「動くコードを作る」のは得意でも「壊れにくいシステムを設計する」のは苦手だからだ。
なぜAIコードは非機能要件を無視するのか
AIがコードを生成するとき、プロンプトに「高速で」「安全に」と書いても、それが実装に反映されるとは限らない。典型的なパターンを挙げる。
- N+1クエリ問題:ループの中でデータベースへの問い合わせが繰り返され、ページが遅くなる
- 認証チェックの漏れ:ログインしていないユーザーでもAPIにアクセスできる状態
- 環境変数のハードコード:APIキーがコードに直書きされている
- エラーログの欠如:何かが壊れても誰も気づかない
プロトタイプとして動かすだけなら問題にならないが、本番でユーザーが使い始めると一気に顕在化する。
4つの柱と最低ライン
性能:初回ロード3秒以内、API応答500ms以内
ユーザーがページを開いてから3秒以内に表示されなければ、多くのユーザーは離脱する。Googleのデータでは、表示に3秒かかるとモバイルユーザーの53%が離脱するとされている。
Next.js + Supabaseの構成で特に気をつける点は以下だ。
- Supabaseへのクエリ数:1ページの表示に10回以上クエリが走っていないか
- 画像の最適化:next/imageを使っているか、巨大な画像をそのまま表示していないか
- Edge Functionの配置:Vercelのサーバーレス関数のリージョンがユーザーの地域に近いか
簡単な確認方法は、ブラウザのDevToolsを開いてNetworkタブで各リクエストの応答時間を見ることだ。500msを超えているAPIがあれば要調査だ。
可用性:99.5%稼働 = 月4.4時間ダウンOK
「99.9%の稼働率」と聞くと高そうに聞こえるが、月に換算すると43.8分のダウンタイムが許容範囲になる。MVPの最低ラインとして現実的なのは99.5%、つまり月4.4時間のダウンは許容するという水準だ。
Vercelのフリープランでも、基本的にはこの水準は達成できる。ただし、Supabaseのフリープランには「1週間アクセスがないとプロジェクトが停止する」という制限がある。本番運用ではPro plan($25/月〜)への移行を前提にするべきだ。
可用性を上げるために最低限やること:
- Supabaseは本番ではProプランに移行する
- Vercelのステータスページをモニタリングに登録する
- 死活監視ツール(UptimeRobot等、無料プランあり)で5分おきに死活確認する
セキュリティ:この3つが最低限
RLS有効化、APIキーの環境変数化、HTTPSのみ——この3点が揃っていなければ本番公開すべきではない。
RLS(Row Level Security)の有効化
SupabaseのRLSが無効のテーブルは、APIキーを持つ人なら誰でも全データにアクセスできる状態だ。Supabaseダッシュボードの「Authentication → Policies」でRLSが有効かどうかを確認する。
APIキーの環境変数化
StripeのシークレットキーやSupabaseのservice role keyがソースコードに直書きされていないか確認する。GitHubにコードを公開している場合、キーが漏洩するリスクがある。.env.local に書き、Vercelの環境変数として登録する。
HTTPSのみ
Vercelにデプロイすれば自動的にHTTPSになるが、Supabaseへの接続もHTTPS経由かどうかを確認する。カスタムAPIサーバーを使っている場合は要注意だ。
保守性:「1人の開発者が去っても継続できるか」
AIで作ったコードは動くが、なぜそう書いたかがわからないことが多い。数ヶ月後に別の開発者が引き継いだとき、あるいは自分でも忘れたとき、最低限必要なドキュメントがある。
最低限用意しておくもの:
- README:プロジェクトの概要、ローカル開発の起動手順
- 環境変数一覧:どの環境変数が必要か、何に使うか
- デプロイ手順:本番へのデプロイ方法(Vercelなら「GitHubにpushするだけ」でも文章化する)
- 主要なコメント:特殊な処理やビジネスロジックには日本語コメントを入れる
プロトタイプとMVPの比較
| 観点 | vibe codingプロトタイプ | MVP(本番対応済み) |
|---|---|---|
| 性能 | 考慮なし(動けばいい) | 初回ロード3秒以内、API応答500ms以内 |
| 可用性 | Supabaseフリープラン(週次停止あり) | Supabase Proプラン、死活監視あり |
| セキュリティ | RLS未設定、APIキー直書きの可能性あり | RLS有効、環境変数管理、HTTPS強制 |
| 保守性 | コメントなし、手順書なし | README、環境変数一覧、デプロイ手順あり |
| エラー検知 | なし(気づかない) | Sentry等のエラー監視、アラート設定あり |
Next.js + Supabase + Vercelで特にはまるポイント
Supabaseのコネクションプール問題
サーバーレス環境(Vercel)からSupabaseに接続するとき、コネクションが枯渇する問題が起きやすい。対策は supabase-js クライアントをシングルトンで管理することと、必要に応じてSupabaseのPgBouncerを使うことだ。
Vercelのサーバーレス関数のコールドスタート
頻繁にアクセスされないAPIは、リクエストのたびに起動し直す「コールドスタート」が発生する。ロシア語の地域だと1〜2秒の遅延になることがある。Vercel Pro以上ではリージョンの選択が柔軟になる。
Next.jsのビルドエラーが本番でのみ発生
next build はローカルで通るのに、Vercelのビルドで失敗するケースがある。環境変数の設定漏れ、型エラーの見逃し、依存関係の問題が主な原因だ。デプロイ前にローカルで next build を実行するクセをつける。
30分でできる非機能要件の簡易監査
以下の手順で、既存のプロトタイプの非機能要件の状態を把握できる。
- (5分)Supabaseダッシュボードを開く:Authentication → PoliciesでRLSが有効なテーブルを確認。全テーブルのRLSが有効になっているか。
- (5分)GitHubのコードを検索:
.env、SECRET、API_KEYなどのキーワードでコードを検索。ハードコードされた認証情報がないか確認。 - (10分)ブラウザのDevToolsで性能確認:主要な画面を開いてNetworkタブで応答時間を確認。3秒を超えるものがあれば要対応。
- (5分)モバイルで確認:スマートフォンの4G回線で実際にアクセスしてみる。体感で問題がわかることが多い。
- (5分)README.mdを確認:プロジェクトを初めて見た人が、READMEだけでローカル起動できるか確認する。
非機能要件は「公開後に対応する」という判断が最もリスクを高める。ユーザーが使い始めてからパフォーマンス問題やセキュリティホールが発見されると、信頼の回復に倍の時間がかかる。最低限のラインをクリアしてから公開する、それだけのことだ。