【技術解説】Vercelを賢く使う - ビルド時間短縮とデプロイ効率化の実践術

この記事で解決できること
- Vercelのビルド時間を80%短縮する具体的なテクニックがわかる
- デプロイ失敗を93%削減する開発フローを構築できる
- Hobbyプラン(非商用)とProプラン(商用可)の違いを正しく理解できる
- 商用利用時のProプラン移行判断基準が明確になる
「ビルドが遅い」「ローカルでは動くのにVercelで失敗する」という方は、この記事を読めばビルド時間を10分→2分に短縮できます。
⚠️ 重要: Hobbyプランは非商用利用のみ
Vercel Hobbyプラン(無料)は個人・非商用プロジェクト専用です。スタートアップや商用サービスでの利用にはProプラン($20/月)への移行が必須です。本記事のテクニックはProプランでも有効ですが、商用利用の場合はProプランへの移行をご検討ください。
きっかけ:ビルド失敗の連続と長いビルド時間
個人プロジェクトでVercelを使い始めた頃、こんな問題に直面しました:
❌ Build failed: Module not found: Can't resolve '@/components/...'
「ローカルでは動くのに、なんでVercelで失敗する?」
さらに、ビルドが通っても毎回8-10分かかる。
当時の開発スタイルは非効率でした:
- 小さな修正ごとにcommit & push(ビルド確認なし)
- 全てのブランチでプレビューデプロイ(不要なビルド多発)
- ローカルビルド確認せずにpush(Vercelで初めてエラー発覚)
- npm installが毎回フルで走る(キャッシュ効かず)
結果:
- デプロイ失敗率18%
- ビルド時間8分超
- 待ち時間のストレス
そこで、Claude Codeに相談してみました。
Claude Codeへの相談
実際に送ったプロンプト
Vercelでビルドが遅くて困ってる。
ローカルでは動くのにVercelで失敗することも多い。
要件:
- ビルド時間を短縮したい
- デプロイ失敗を減らしたい
- 開発速度は落としたくない
Claude Codeの回答(要約)
以下の3つのアプローチで大幅改善できます:
1. **ビルドキャッシュの最適化**
- Node.jsバージョン固定で安定化
- pnpm移行でキャッシュ効率UP
2. **開発フローの改善**
- ローカルでビルド確認してからpush(pre-push hook)
- Vercelで初めて失敗を防ぐ
3. **プレビューデプロイの制御**
- 必要なブランチのみプレビュー生成
- 不要なビルドを削減
これらを組み合わせれば、ビルド時間80%短縮、失敗率93%削減が可能です。
「なるほど、ビルド環境と開発フローの両方を見直すのか」と納得。
早速、実装を開始しました。
Vercel Hobbyプラン(無料枠)の正確な理解
まず、Hobbyプランの制限を正確に把握することが重要です。
⚠️ 最重要:商用利用不可
| プラン | 料金 | 商用利用 | 対象 |
|---|---|---|---|
| Hobby | 無料 | ❌ 不可 | 個人・趣味プロジェクト |
| Pro | $20/月 | ✅ 可 | 商用・チーム開発 |
| Enterprise | カスタム | ✅ 可 | 大規模・高可用性要求 |
Hobbyプランは非商用・個人利用専用です。収益を得るサービスやスタートアップでの利用はライセンス違反となります。
デプロイ・ビルド制限
| 項目 | Hobby制限値 | Pro制限値 | 備考 |
|---|---|---|---|
| デプロイ数 | 100回/日 | 6,000回/日 | 日単位でリセット |
| ビルド実行時間 | 6,000分/月 | 30,000分/月 | 月合計 |
| 同時ビルド数 | 1ビルド | 12ビルド | Proは並列可能 |
| Function最大実行時間 | 10秒(最大60秒) | 15秒(最大300秒) | 設定で変更可 |
リソース制限
| 項目 | Hobby制限値 | 備考 |
|---|---|---|
| Function呼び出し | 100万回 | 十分な量 |
| 帯域幅 | 100 GB/月 | 画像・動画が多いサイトは注意 |
| Image Optimization | 1,000枚 | next/image使用時 |
| Analytics Events | 50,000イベント | Speed Insights含む |
なぜビルド最適化が重要か
ビルド実行時間6,000分/月は、1回10分のビルドなら600回/月で使い切ります。
例:
- ビルド時間10分 × 1日20回 = 200分/日 × 30日 = 6,000分(ギリギリ)
- ビルド時間2分 × 1日20回 = 40分/日 × 30日 = 1,200分(余裕)
つまり、ビルド時間を短縮すれば、同じ回数デプロイしても余裕が生まれます。
構築中に遭遇した問題と解決策
実際の最適化作業で直面した問題と、Claude Codeとのやり取りを紹介します。
問題1:vercel.jsonの設定がドキュメント通りに動かない
症状:vercel.jsonにgit.deploymentEnabled: falseを設定したのに、全ブランチでデプロイされる
Claude Codeとのやり取り:
私:「vercel.jsonでデプロイ無効化したのに、全ブランチでデプロイされる」
Claude:「vercel.jsonの設定は一部廃止されています。
現在は Vercelダッシュボード > Settings > Git で設定する必要があります。
具体的には:
1. Production Branch: main のみ
2. Preview Deployments: 無効化 または 特定ブランチのみ
vercel.json では制御できなくなりました(2024年以降)」
解決策:ダッシュボードで設定を変更
Vercel Dashboard > Project Settings > Git
↓
Production Branch: main
Preview Deployments: Ignored Build Step (特定条件のみビルド)
この変更で、不要なプレビューデプロイが80%削減されました。
問題2:ローカルビルドが通るのに本番デプロイで失敗
症状:npm run buildは成功するのに、Vercelデプロイでビルドエラー
Claude Codeとのやり取り:
私:「ローカルでは成功するのに、Vercelで `Module not found: Can't resolve '@/components/...'` エラー」
Claude:「Next.jsの `tsconfig.json` の `paths` 設定と、
Vercelのビルド環境の差異が原因です。
Vercelは node_modules を完全にクリーンインストールするため、
ローカルのキャッシュに依存している場合にエラーになります。
解決策:
1. `package.json` の依存関係を明示的に追加
2. `next.config.js` で webpack の resolve.alias を設定
3. `vercel.json` で NODE_ENV=production を明示」
解決策:next.config.jsにエイリアス追加
// next.config.js
const path = require('path');
module.exports = {
webpack: (config) => {
config.resolve.alias['@'] = path.resolve(__dirname, 'src');
return config;
},
};
これで、ローカルとVercelのビルド結果が一致するようになりました。
問題3:ビルドキャッシュが効かず、毎回フルビルド
症状:デプロイのたびにnpm installが走り、ビルド時間が5-10分かかる
Claude Codeとのやり取り:
私:「毎回 npm install で時間かかる。キャッシュ効かせられない?」
Claude:「Vercelは自動でキャッシュしますが、以下の場合は無効化されます:
キャッシュが無効化される条件:
1. package.json または package-lock.json が変更された
2. Node.js バージョンが変わった
3. 環境変数 VERCEL_FORCE_NO_BUILD_CACHE=1 が設定されている
最適化策:
1. package.json の変更をまとめる(依存追加は一度に)
2. .nvmrc でNode.jsバージョンを固定
3. pnpm に移行してキャッシュ効率UP」
解決策:.nvmrcでNode.jsバージョン固定
# .nvmrc
20.10.0
さらに、pnpmに移行して、キャッシュ効率を大幅改善:
// package.json
{
"packageManager": "pnpm@8.15.0"
}
結果:
- ビルド時間:10分 → 2分
- キャッシュヒット率:30% → 85%
デプロイ数を削減する3つの戦略
上記の問題解決を踏まえ、最終的に確立した3つの戦略を紹介します。
戦略1:プレビューデプロイの厳格な制御
設定内容
Vercel Dashboard > Settings > Git
Production Branch: main
Preview Deployments: Custom Configuration
- feature/* : デプロイしない
- fix/* : デプロイしない
- release/* : デプロイする(本番前最終確認)
Ignored Build Stepの活用
さらに、条件付きビルドスキップを設定:
# vercel-build.sh
#!/bin/bash
# コミットメッセージに [skip vercel] が含まれる場合はビルドスキップ
if git log -1 --pretty=%B | grep -q "[skip vercel]"; then
echo "Skipping build (commit message contains [skip vercel])"
exit 0
fi
# ドキュメントのみの変更はスキップ
if git diff HEAD^ HEAD --name-only | grep -qvE '.(md|txt)$'; then
echo "Building..."
npm run build
else
echo "Skipping build (documentation changes only)"
exit 0
fi
package.json
{
"scripts": {
"build": "bash vercel-build.sh && next build"
}
}
効果
| Before | After | 改善 |
|---|---|---|
| 全ブランチでプレビュー生成 | mainとrelease/*のみ | 不要ビルド80%削減 |
| ビルド待ち時間ストレス | 必要な時だけビルド | 開発体験向上 |
戦略2:ビルドキャッシュの徹底活用
Node.js環境の固定
# .nvmrc
20.10.0
// package.json
{
"engines": {
"node": ">=20.10.0"
}
}
pnpmでキャッシュ効率化
# pnpmに移行
npm install -g pnpm
pnpm install
// package.json
{
"packageManager": "pnpm@8.15.0",
"scripts": {
"dev": "pnpm dev",
"build": "pnpm build"
}
}
Next.jsビルドキャッシュの有効化
// next.config.js
module.exports = {
// ビルドキャッシュを有効化
compiler: {
removeConsole: process.env.NODE_ENV === "production",
},
// 増分ビルドを有効化
experimental: {
incrementalCacheHandlerPath: require.resolve('./cache-handler.js'),
},
};
効果
| 項目 | Before | After | 改善率 |
|---|---|---|---|
| ビルド時間 | 10分 | 2分 | 80%短縮 |
| キャッシュヒット率 | 30% | 85% | 55pt向上 |
戦略3:開発フローの改善
ローカルビルド確認の徹底
Git Hooksで強制
# .husky/pre-push
#!/bin/sh
# mainブランチへのpush前に必ずビルド確認
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "$BRANCH" = "main" ]; then
echo "Building before push to main..."
npm run build
if [ $? -ne 0 ]; then
echo "❌ Build failed. Fix errors before pushing."
exit 1
fi
fi
コミットのまとめ(Squash戦略)
# 作業ブランチでは小さなコミット
git commit -m "WIP: 機能A実装中"
git commit -m "WIP: 機能A実装中2"
git commit -m "WIP: 機能A実装中3"
# PRマージ前にSquash
git rebase -i HEAD~3
# → 3つのコミットを1つにまとめる
# または、GitHub PR設定で「Squash and merge」を使用
これにより、3回pushが1回のデプロイになります。
コミットメッセージでデプロイ制御
# デプロイしたくない変更
git commit -m "[skip vercel] ドキュメント修正"
# デプロイする変更
git commit -m "feat: 新機能追加"
効果
| 項目 | Before | After | 改善 |
|---|---|---|---|
| Vercelでの初エラー発覚 | 頻繁 | ほぼゼロ | ローカルで事前検出 |
| デプロイ失敗率 | 18% | 2% | 89%改善 |
アーキテクチャ全体像
最適化後のデプロイフローを図解します。
┌─────────────────────────────────────────────────────────────┐
│ 開発フロー │
└─────────────────────────────────────────────────────────────┘
┌─────────────┐
│ 開発作業 │
│ (feature/*) │
└──────┬──────┘
│ 小さなコミット(複数回)
↓
┌──────────────┐
│ ローカルビルド │ ← pre-push hookで強制確認
│ 確認 │
└──────┬───────┘
│ OK
↓
┌──────────────┐
│ Git Squash │ ← 複数コミットを1つにまとめる
│ (PR作成前) │
└──────┬───────┘
│
↓
┌──────────────────────┐
│ PR作成 │
│ → release/* ブランチ │ ← このブランチのみプレビューデプロイ
└──────┬───────────────┘
│ レビュー・承認
↓
┌────────────────────────┐
│ mainブランチにマージ │ ← Production Deploy (1カウント)
└────────────────────────┘
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
【ビルド効率化の効果】
Before: ローカル確認なし → Vercelで失敗 → 修正 → 再push → ビルド待ち...
After: ローカル確認 → 1回で成功 → 待ち時間最小
効果: ビルド失敗89%削減、ビルド時間79%短縮
技術スタック詳細
フロントエンド
| 技術 | バージョン | 選定理由 |
|---|---|---|
| Next.js | 14.2.x | App Router、Server Components対応 |
| TypeScript | 5.3.x | 型安全性、エディタサポート |
| Tailwind CSS | 3.4.x | ユーティリティファーストCSS |
ビルド・デプロイ
| 技術 | バージョン | 選定理由 |
|---|---|---|
| pnpm | 8.15.x | npmより高速、キャッシュ効率良好 |
| Vercel | - | Next.js公式推奨、自動デプロイ |
| Husky | 9.0.x | Git Hooks管理、pre-push確認 |
監視・分析
| 技術 | 用途 |
|---|---|
| Vercel Analytics | デプロイ数・ビルド時間監視 |
| Vercel Logs | デプロイエラーのトラブルシュート |
実装詳細:主要ファイル
vercel-build.sh(条件付きビルド)
#!/bin/bash
# コミットメッセージチェック
COMMIT_MSG=$(git log -1 --pretty=%B)
if echo "$COMMIT_MSG" | grep -q "[skip vercel]"; then
echo "🚫 Skipping Vercel build ([skip vercel] in commit message)"
exit 0
fi
# ドキュメントのみの変更チェック
CHANGED_FILES=$(git diff HEAD^ HEAD --name-only)
if echo "$CHANGED_FILES" | grep -qvE '.(md|txt)$'; then
echo "🔨 Building Next.js app..."
npm run build
else
echo "📝 Documentation changes only, skipping build"
exit 0
fi
.husky/pre-push(ローカルビルド強制)
#!/bin/sh
BRANCH=$(git rev-parse --abbrev-ref HEAD)
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "release/"* ]; then
echo "${GREEN}🔨 Building before push to $BRANCH...${NC}"
npm run build
if [ $? -ne 0 ]; then
echo "${RED}❌ Build failed! Fix errors before pushing.${NC}"
exit 1
fi
echo "${GREEN}✅ Build succeeded. Pushing...${NC}"
fi
next.config.js(ビルド最適化)
/** @type {import('next').NextConfig} */
const nextConfig = {
// コンパイラ最適化
compiler: {
removeConsole: process.env.NODE_ENV === "production",
},
// Webpack設定
webpack: (config, { isServer }) => {
// パスエイリアス
config.resolve.alias['@'] = path.resolve(__dirname, 'src');
// ビルドキャッシュ
config.cache = {
type: 'filesystem',
buildDependencies: {
config: [__filename],
},
};
return config;
},
// 実験的機能
experimental: {
// 増分ビルド
incrementalCacheHandlerPath: require.resolve('./cache-handler.js'),
},
};
module.exports = nextConfig;
package.json(スクリプト定義)
{
"name": "vercel-optimized-project",
"version": "1.0.0",
"packageManager": "pnpm@8.15.0",
"engines": {
"node": ">=20.10.0"
},
"scripts": {
"dev": "next dev",
"build": "bash vercel-build.sh && next build",
"start": "next start",
"lint": "next lint",
"prepare": "husky install"
},
"dependencies": {
"next": "14.2.3",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@types/node": "^20.10.0",
"@types/react": "^18.3.0",
"husky": "^9.0.11",
"typescript": "^5.3.3"
}
}
運用実績:個人プロジェクトでの数値データ
実際に上記の最適化を適用した結果を公開します。
ビルド時間の推移(最適化前後)
| 期間 | ビルド時間(平均) | 失敗率 | 備考 |
|---|---|---|---|
| 最適化前 | 8分32秒 | 18% | npm毎回フルインストール |
| pnpm移行後 | 5分12秒 | 12% | キャッシュ効き始め |
| Node.js固定後 | 3分05秒 | 8% | 安定化 |
| pre-push hook導入後 | 2分15秒 | 3% | ローカル確認で失敗減 |
| 全最適化完了 | 1分47秒 | 2% | 79%短縮 |
Before/After比較
| 項目 | Before | After | 改善率 |
|---|---|---|---|
| ビルド時間(平均) | 8分32秒 | 1分47秒 | 79%短縮 |
| デプロイ失敗率 | 18% | 2% | 89%改善 |
| キャッシュヒット率 | 30% | 85% | 55pt向上 |
| 待ち時間ストレス | 高 | 低 | 大幅改善 |
生産性向上効果
ビルド時間短縮による効果:
- 1回あたり6分45秒短縮
- 1日10回ビルド × 30日 = 300回/月
- 300回 × 6.75分 = 約34時間/月の待ち時間削減
デプロイ失敗削減による効果:
- 失敗→修正→再デプロイの無駄がなくなる
- 精神的ストレス軽減
検出した問題(デプロイ失敗の内訳)
| 原因 | 最適化前(11月) | 最適化後(12月) | 削減効果 |
|---|---|---|---|
| TypeScript型エラー | 12件 | 1件 | 92%削減 |
| ビルドタイムアウト | 8件 | 0件 | 100%削減 |
| 依存関係エラー | 5件 | 0件 | 100%削減 |
| 環境変数ミス | 3件 | 1件 | 67%削減 |
| 合計 | 28件 | 2件 | 93%削減 |
理由:ローカルビルド確認(pre-push hook)により、問題が本番デプロイ前に発見されるようになった。
対処法・ベストプラクティス
運用中に遭遇した問題と、その解決策をまとめます。
よくある問題1:「ローカルでは動くのにVercelでエラー」
原因:環境変数の設定漏れ
解決策:
# .env.example を作成(Gitにコミット)
NEXT_PUBLIC_API_URL=https://api.example.com
DATABASE_URL=your_database_url
# Vercelに環境変数を設定
vercel env add NEXT_PUBLIC_API_URL
vercel env add DATABASE_URL
# ローカルで確認
vercel env pull .env.local
npm run build
よくある問題2:「ビルドキャッシュが効かない」
原因:package-lock.jsonの差分が頻繁に発生
解決策:pnpmに移行
# npmからpnpmに移行
rm -rf node_modules package-lock.json
npm install -g pnpm
pnpm install
# package.jsonに追記
{
"packageManager": "pnpm@8.15.0"
}
効果:キャッシュヒット率が 30% → 85% に向上
よくある問題3:「Squashマージでコミット履歴が消える」
原因:GitHub PR設定で「Squash and merge」を使用
解決策:ブランチ戦略の見直し
feature/* ブランチ:
├─ 小さなコミット(開発中は自由にcommit)
├─ ローカルでSquash(git rebase -i)
└─ PRマージ時は「Rebase and merge」を使用
→ コミット履歴を保持しつつ、デプロイ数削減
よくある問題4:「[skip vercel]を忘れてデプロイしてしまう」
解決策:Git aliasで自動化
# .gitconfig
[alias]
cm-skip = commit -m "[skip vercel] "
cm-build = commit -m ""
# 使用例
git add README.md
git cm-skip "ドキュメント修正" # 自動で [skip vercel] が付く
Proプランへの移行判断基準
「いつProプランに移行すべきか?」の明確な基準を示します。
⚠️ 最重要:商用利用は即座にPro移行必須
以下に該当する場合、Hobbyプランは使用できません:
| ケース | 判断 |
|---|---|
| 収益を得るサービス | 即座にPro移行 |
| スタートアップのプロダクト | 即座にPro移行 |
| クライアントワーク | 即座にPro移行 |
| 広告収入があるサイト | 即座にPro移行 |
| 会社のコーポレートサイト | 即座にPro移行 |
Hobbyプランで商用利用はライセンス違反です。 本記事のテクニックはProプランでも有効なので、商用利用の場合はまずProに移行してから最適化を適用してください。
Hobbyプランで継続できるケース
以下の条件を全て満たす場合のみ、Hobbyプランで問題ありません:
- 完全に非商用(趣味・学習・ポートフォリオ)
- 収益なし(広告収入もなし)
- 個人利用(チーム開発でない)
- ビルド実行時間が6,000分/月以内
- 帯域幅が100GB/月以内
Proプラン($20/月)のメリット
| 項目 | Hobby | Pro |
|---|---|---|
| 商用利用 | ❌ | ✅ |
| チーム機能 | ❌ | ✅(無制限メンバー) |
| 同時ビルド | 1 | 12(高速化) |
| ビルド実行時間 | 6,000分/月 | 30,000分/月 |
| サポート | コミュニティ | メール |
| パスワード保護 | ❌ | ✅ |
Enterpriseプランが必要なケース
以下の場合はEnterpriseプラン(要見積もり):
- 99.99% SLA保証が必要
- SAML SSO、SOC 2認証が必要
- 専用サポート担当が必要
- マルチリージョンフェイルオーバーが必要
構築にかかった時間
最適化作業の内訳を公開します。
| 作業 | 所要時間 | 備考 |
|---|---|---|
| 調査・設計 | 2時間 | Vercelドキュメント確認、Claude Code相談 |
| vercel.json設定 | 30分 | → 実は不要だった(ダッシュボード設定に変更) |
| ダッシュボード設定 | 15分 | Git設定、ブランチ制御 |
| vercel-build.sh作成 | 1時間 | 条件分岐、テスト |
| Husky設定 | 45分 | pre-push hook、動作確認 |
| pnpm移行 | 1.5時間 | npm → pnpm、キャッシュ確認 |
| next.config.js最適化 | 1時間 | webpack設定、エイリアス |
| 動作確認・デバッグ | 2時間 | 各ブランチでのデプロイテスト |
| ドキュメント作成 | 1時間 | README、運用ガイド |
| 合計 | 約10時間 | 1日〜1.5日で完了 |
タイムライン
Day 1(午前):
├─ 調査・設計(2時間)
├─ vercel.json設定試行(30分) → 失敗
└─ ダッシュボード設定(15分) → 成功
Day 1(午後):
├─ vercel-build.sh作成(1時間)
├─ Husky設定(45分)
└─ 動作確認(1時間)
Day 2(午前):
├─ pnpm移行(1.5時間)
├─ next.config.js最適化(1時間)
└─ 最終動作確認(1時間)
Day 2(午後):
└─ ドキュメント作成(1時間)
まとめ
Vercelでの開発体験は、正しい設定と開発フローで劇的に改善できます。
この記事で紹介した手法のまとめ
-
ビルドキャッシュ最適化
- Node.jsバージョン固定(.nvmrc)
- pnpm移行でキャッシュ効率UP
- 効果:ビルド時間 79%短縮
-
開発フロー改善
- ローカルビルド確認(pre-push hook)
- Vercelで初めて失敗を防ぐ
- 効果:デプロイ失敗 89%削減
-
プレビューデプロイ制御
- 必要なブランチのみデプロイ(release/*)
- 条件付きビルドスキップ([skip vercel])
- 効果:不要ビルド 80%削減
実際の成果
- ビルド時間:8分32秒 → 1分47秒(79%短縮)
- デプロイ失敗率:18% → 2%(89%改善)
- 待ち時間削減:約34時間/月
⚠️ 最後に:プラン選択の重要性
Hobbyプラン(無料)は非商用・個人利用専用です。
- ✅ 趣味プロジェクト、学習、ポートフォリオ → Hobbyプラン
- ✅ スタートアップ、商用サービス、クライアントワーク → Proプラン($20/月)
本記事のテクニックはProプランでも有効です。商用利用の場合は、まずProプランに移行してから最適化を適用してください。
非エンジニアでもできる
この記事の手法は、Claude Codeと対話しながら実装しました。
「ビルドが遅い」「失敗が多い」と感じたら、まずは開発フローの見直しから。
少しの設定で、開発体験は劇的に改善します。
参考リンク
- Vercel公式ドキュメント - Deployment Limits
- Vercel公式ドキュメント - Git Integration
- Next.js公式ドキュメント - Build Configuration
- pnpm公式ドキュメント
- Husky公式ドキュメント
著者: てんちょー(合同会社QUEST 代表)
普段はSIerで経営企画部員として働きながら、週末起業で高校時代の友人と共同創業。Claude Codeを活用した業務効率化・システム開発を得意としています。
🌐 コーポレートサイト: https://llc-quest.com 🐦 Twitter (X): https://x.com/questceo_ai


