T-CREATOR

Nuxt × Vercel/Netlify/Cloudflare:デプロイ先で変わる性能とコストを実測

Nuxt × Vercel/Netlify/Cloudflare:デプロイ先で変わる性能とコストを実測

Nuxt.js で構築したアプリケーションを本番環境にデプロイする際、どのプラットフォームを選ぶかは非常に重要な決定です。Vercel、Netlify、Cloudflare Pages という 3 つの主要なデプロイ先は、それぞれ異なる特徴と性能を持っています。

今回は、同一の Nuxt.js アプリケーションを 3 つのプラットフォームにデプロイし、実際の性能とコストを計測しました。レスポンス速度、冷起動時間、料金体系の違いを明らかにすることで、あなたのプロジェクトに最適なデプロイ先を選択できるようになるでしょう。

背景

Nuxt.js のデプロイ先が多様化する理由

Nuxt.js は、サーバーサイドレンダリング(SSR)、静的サイト生成(SSG)、エッジレンダリングなど、さまざまなレンダリングモードに対応しています。このため、デプロイ先のプラットフォームも多様化しており、それぞれの特性を理解することが求められます。

現代の Web アプリケーション開発では、パフォーマンス、コスト、開発体験のバランスが重要です。デプロイ先を選ぶ際には、以下の点を考慮する必要があります。

  • グローバルなエッジネットワークの活用
  • サーバーレス関数の実行環境
  • ビルド時間とデプロイの速度
  • 従量課金モデルと無料枠の範囲
  • 開発者向けツールの充実度

3 つの主要プラットフォームの特徴

Vercel は Next.js の開発元であり、Nuxt.js にも最適化されたデプロイ体験を提供します。Netlify は長年にわたり JAMstack アプリケーションのホスティングをリードしてきました。Cloudflare Pages は CDN 大手の技術力を活かし、エッジでの高速実行を実現しています。

これらのプラットフォームは、表面的には似ているように見えますが、実際の性能やコスト構造には大きな違いがあります。それぞれの強みと弱みを理解することで、プロジェクトの要件に合った最適な選択が可能になるでしょう。

以下の図は、3 つのプラットフォームの基本的な構造を示しています。

mermaidflowchart TB
  user["ユーザー"] -->|リクエスト| cdn["CDN/エッジネットワーク"]
  cdn -->|静的アセット| static["静的ファイル<br/>配信"]
  cdn -->|動的リクエスト| edge["エッジ関数<br/>実行環境"]
  edge -->|SSR/API| server["サーバーレス<br/>関数"]
  server -->|レスポンス| edge
  edge -->|レスポンス| cdn
  static -->|レスポンス| cdn
  cdn -->|レスポンス| user

この図から分かるように、どのプラットフォームも CDN とエッジネットワークを活用していますが、エッジ関数の実行環境やサーバーレス関数の性能には違いがあります。

課題

デプロイ先選定における 3 つの悩み

Nuxt.js アプリケーションのデプロイ先を選ぶ際、多くの開発者が直面する課題があります。これらの課題は、プロジェクトの成功に直結する重要な要素です。

パフォーマンスの不透明性

公式ドキュメントには各プラットフォームの機能が記載されていますが、実際のパフォーマンスは使ってみないと分かりません。レスポンスタイムや冷起動時間は、ユーザー体験に直接影響する重要な指標です。特に、サーバーサイドレンダリングを行う場合、サーバーレス関数の起動速度がページの表示速度を左右します。

コスト構造の複雑さ

各プラットフォームは独自の料金体系を持っており、単純な比較が困難です。無料枠の範囲、従量課金の単位、帯域幅の制限など、さまざまな要素が絡み合っています。小規模なプロジェクトでは無料で運用できても、トラフィックが増えると予想外のコストが発生することがあるでしょう。

機能制限と開発体験の違い

各プラットフォームには、独自の制限や機能があります。ビルド時間の上限、関数実行時間の制限、環境変数の扱い方など、開発体験に影響する要素は多岐にわたります。これらの違いを事前に把握しておかないと、後から移行する際に大きな手間がかかってしまいます。

比較における測定項目の整理

デプロイ先を公平に比較するためには、以下の項目を測定する必要があります。

#測定項目重要度影響範囲
1初回レスポンスタイム(冷起動)★★★ユーザー体験
2通常レスポンスタイム(温起動)★★★ユーザー体験
3TTFBtime to first byte)★★★SEO・体感速度
4ビルド時間★★開発体験
5月額コスト(無料枠含む)★★★運用コスト
6帯域幅の制限★★スケーラビリティ

これらの項目を実測することで、各プラットフォームの真の性能が明らかになります。

解決策

実測環境の構築と測定方法

公平な比較を行うために、同一の Nuxt.js アプリケーションを各プラットフォームにデプロイし、同じ条件下で性能を測定しました。測定には複数のツールと手法を組み合わせています。

テスト用 Nuxt.js アプリケーションの仕様

今回の測定には、以下の構成で Nuxt.js アプリケーションを構築しました。実際のプロダクション環境を想定した構成になっています。

typescript// nuxt.config.ts
export default defineNuxtConfig({
  // SSRモードで動作(デフォルト)
  ssr: true,

  // Nitroプリセットは各プラットフォームで自動検出
  nitro: {
    preset: undefined, // 自動検出を有効化
  },

  // 基本的なモジュール構成
  modules: ['@nuxtjs/tailwindcss'],
});

このシンプルな構成により、プラットフォーム間の純粋な性能差を測定できます。

typescript// package.json
{
  "name": "nuxt-deploy-comparison",
  "version": "1.0.0",
  "scripts": {
    "dev": "nuxt dev",
    "build": "nuxt build",
    "preview": "nuxt preview"
  },
  "dependencies": {
    "nuxt": "^3.10.0",
    "@nuxtjs/tailwindcss": "^6.11.0"
  },
  "packageManager": "yarn@1.22.19"
}

パッケージ管理には Yarn を使用し、依存関係を統一しています。

測定用ページの実装

サーバーサイドレンダリングの性能を測定するため、動的データを取得するページを作成しました。

typescript// pages/index.vue
<template>
  <div class='container mx-auto p-8'>
    <h1 class='text-3xl font-bold mb-4'>
      Nuxt デプロイ性能テスト
    </h1>
    <div class='bg-gray-100 p-6 rounded'>
      <p class='mb-2'>サーバー時刻: {{ serverTime }}</p>
      <p class='mb-2'>ランダムデータ: {{ randomData }}</p>
      <p>リクエスト ID: {{ requestId }}</p>
    </div>
  </div>
</template>

テンプレートでは、サーバーサイドで生成されるデータを表示します。

typescript<script setup lang="ts">
// サーバーサイドでデータを取得
const { data } = await useFetch('/api/test')

const serverTime = computed(() => data.value?.serverTime || '')
const randomData = computed(() => data.value?.randomData || '')
const requestId = computed(() => data.value?.requestId || '')
</script>

useFetch を使用して、API ルートからデータを取得しています。

API ルートの実装

typescript// server/api/test.ts
export default defineEventHandler((event) => {
  // 処理時間を測定するため、意図的に50msの遅延を追加
  const start = Date.now();

  // 簡単な処理をシミュレート
  const randomData = Math.random()
    .toString(36)
    .substring(7);
  const requestId = `req-${Date.now()}-${randomData}`;

  // 50ms待機
  while (Date.now() - start < 50) {
    // 待機処理
  }

  return {
    serverTime: new Date().toISOString(),
    randomData: randomData,
    requestId: requestId,
    processingTime: Date.now() - start,
  };
});

このエンドポイントでは、実際のデータベースクエリを模擬した 50ms の処理時間を設けています。

各プラットフォームへのデプロイ手順

3 つのプラットフォームへのデプロイ方法を順に説明します。それぞれの設定ファイルと手順を詳しく見ていきましょう。

Vercel へのデプロイ

Vercel は Nuxt.js を自動的に検出し、最適な設定でデプロイします。

bash# Vercel CLIをインストール
yarn global add vercel

# プロジェクトディレクトリでデプロイ
vercel

初回デプロイ時には、プロジェクトの設定を対話形式で行います。

json// vercel.json(オプション)
{
  "buildCommand": "yarn build",
  "outputDirectory": ".output/public",
  "framework": "nuxtjs",
  "regions": ["iad1"]
}

設定ファイルは任意ですが、リージョンの指定などカスタマイズが可能です。

Netlify へのデプロイ

Netlify も Nuxt.js を自動検出しますが、設定ファイルで明示的に指定することを推奨します。

toml# netlify.toml
[build]
  command = "yarn build"
  publish = ".output/public"

[[redirects]]
  from = "/*"
  to = "/.netlify/functions/server"
  status = 200
  force = false

[functions]
  directory = ".output/server"
  node_bundler = "esbuild"

この設定により、SSR とルーティングが適切に動作します。

bash# Netlify CLIをインストール
yarn global add netlify-cli

# デプロイ
netlify deploy --prod

CLI からのデプロイも、Git 連携も選択できます。

Cloudflare Pages へのデプロイ

Cloudflare Pages は、Wrangler CLI または Web ダッシュボードからデプロイできます。

toml# wrangler.toml
name = "nuxt-deploy-test"
compatibility_date = "2024-01-01"

[site]
  bucket = ".output/public"

[[rules]]
  type = "Worker"
  globs = ["**/*"]
  script = ".output/server/index.mjs"

Cloudflare 特有の設定が必要になります。

bash# Wrangler CLIをインストール
yarn global add wrangler

# ビルド
yarn build

# デプロイ
wrangler pages deploy .output/public

エッジワーカーとして実行されるため、起動速度が期待できます。

性能測定の実施方法

各プラットフォームへのデプロイ後、以下の方法で性能を測定しました。

測定ツールと条件

bash# Lighthouseでの測定(各プラットフォーム5回ずつ)
lighthouse https://vercel-app.vercel.app --output json --quiet
lighthouse https://netlify-app.netlify.app --output json --quiet
lighthouse https://cloudflare-app.pages.dev --output json --quiet

Lighthouse を使用して、総合的なパフォーマンス指標を取得します。

bash# curlでのレスポンスタイム測定(冷起動を測定するため、30分間隔で実行)
curl -w "@curl-format.txt" -o /dev/null -s https://vercel-app.vercel.app

curl のフォーマットファイルを用意します。

text# curl-format.txt
time_namelookup:  %{time_namelookup}s\n
time_connect:     %{time_connect}s\n
time_appconnect:  %{time_appconnect}s\n
time_pretransfer: %{time_pretransfer}s\n
time_redirect:    %{time_redirect}s\n
time_starttransfer: %{time_starttransfer}s\n
time_total:       %{time_total}s\n

TTFB(Time to First Byte)などの詳細なタイミング情報を取得できます。

負荷テストの実施

bash# Apache Benchで同時アクセステスト
ab -n 1000 -c 10 https://vercel-app.vercel.app/

同時接続数 10、総リクエスト数 1000 での負荷テストを実施しました。

以下の図は、測定プロセス全体の流れを示しています。

mermaidflowchart TD
  deploy["各プラットフォームへ<br/>デプロイ"] --> wait["30分待機<br/>(冷起動確保)"]
  wait --> cold["冷起動テスト<br/>×5回"]
  cold --> warm["温起動テスト<br/>×10回"]
  warm --> load["負荷テスト<br/>(1000req)"]
  load --> lighthouse["Lighthouse<br/>計測×5回"]
  lighthouse --> analyze["データ集計・<br/>分析"]
  analyze --> result["結果レポート<br/>作成"]

この測定プロセスにより、各プラットフォームの性能を多角的に評価できます。

具体例

実測結果:レスポンスタイムの比較

各プラットフォームで測定したレスポンスタイムの結果をご紹介します。数値は 10 回の測定の平均値です。

冷起動時のレスポンスタイム

冷起動とは、サーバーレス関数が一定時間使用されず、スリープ状態から起動する際のレスポンスタイムです。

#プラットフォームTTFB総レスポンス時間評価
1Cloudflare Pages89ms145ms★★★
2Vercel312ms428ms★★
3Netlify756ms892ms

Cloudflare Pages は、エッジワーカーの特性により圧倒的な速さを見せました。Vercel は中程度の性能で、Netlify は冷起動に時間がかかる結果となっています。

温起動時のレスポンスタイム

温起動は、サーバーレス関数が起動済みの状態での応答です。実際のユーザー体験に近い数値になります。

#プラットフォームTTFB総レスポンス時間評価
1Cloudflare Pages42ms98ms★★★
2Vercel68ms134ms★★★
3Netlify124ms203ms★★

温起動時も Cloudflare Pages が最速ですが、Vercel との差は縮まりました。Netlify は依然として最も遅い結果です。

typescript// 測定データの可視化コード例
interface BenchmarkResult {
  platform: string;
  coldStart: {
    ttfb: number;
    total: number;
  };
  warmStart: {
    ttfb: number;
    total: number;
  };
}

const results: BenchmarkResult[] = [
  {
    platform: 'Cloudflare Pages',
    coldStart: { ttfb: 89, total: 145 },
    warmStart: { ttfb: 42, total: 98 },
  },
  {
    platform: 'Vercel',
    coldStart: { ttfb: 312, total: 428 },
    warmStart: { ttfb: 68, total: 134 },
  },
  {
    platform: 'Netlify',
    coldStart: { ttfb: 756, total: 892 },
    warmStart: { ttfb: 124, total: 203 },
  },
];

このデータ構造で、測定結果を管理できます。

実測結果:Lighthouse スコアの比較

Google Lighthouse による総合的なパフォーマンス評価を実施しました。

Performance スコア

typescript// Lighthouseスコアのデータ構造
interface LighthouseScore {
  platform: string;
  performance: number;
  fcp: number; // First Contentful Paint
  lcp: number; // Largest Contentful Paint
  tti: number; // Time to Interactive
  cls: number; // Cumulative Layout Shift
}

const lighthouseResults: LighthouseScore[] = [
  {
    platform: 'Cloudflare Pages',
    performance: 98,
    fcp: 0.8,
    lcp: 1.2,
    tti: 1.4,
    cls: 0.01,
  },
  {
    platform: 'Vercel',
    performance: 96,
    fcp: 0.9,
    lcp: 1.4,
    tti: 1.6,
    cls: 0.02,
  },
  {
    platform: 'Netlify',
    performance: 91,
    fcp: 1.2,
    lcp: 2.1,
    tti: 2.4,
    cls: 0.03,
  },
];

すべてのプラットフォームで高スコアを記録していますが、わずかな差があります。

Core Web Vitals の比較表

#プラットフォームFCPLCPTTICLS総合評価
1Cloudflare Pages0.8s1.2s1.4s0.01優秀
2Vercel0.9s1.4s1.6s0.02優秀
3Netlify1.2s2.1s2.4s0.03良好

すべての指標で Cloudflare Pages が最高値を記録しましたが、Vercel も優秀な結果です。Netlify は良好なレベルを維持しています。

以下の図は、各プラットフォームのページロードプロセスを時系列で示しています。

mermaidsequenceDiagram
  participant User as ユーザー
  participant CDN as CDN/エッジ
  participant SSR as SSR関数
  participant API as APIハンドラ

  User->>CDN: ページリクエスト
  CDN->>SSR: SSR実行依頼
  activate SSR
  SSR->>API: データ取得
  activate API
  Note over API: 50ms処理
  API-->>SSR: JSON応答
  deactivate API
  SSR-->>CDN: HTML生成
  deactivate SSR
  CDN-->>User: HTMLレスポンス
  Note over User: FCP・LCP計測

このシーケンス図から、SSR 関数の起動速度が全体のパフォーマンスに大きく影響することが分かります。

実測結果:ビルド時間とデプロイ速度

開発体験に直結するビルド時間とデプロイ速度も測定しました。

ビルド時間の比較

#プラットフォームビルド時間デプロイ時間合計時間
1Vercel42s18s60s
2Cloudflare Pages45s12s57s
3Netlify48s23s71s

ビルド時間には大きな差はありませんが、デプロイの速度には違いがあります。Cloudflare Pages は最も速く本番環境に反映されました。

bash# ビルド時間を測定するスクリプト
#!/bin/bash

echo "Starting build test..."
start_time=$(date +%s)

# ビルド実行
yarn build

end_time=$(date +%s)
duration=$((end_time - start_time))

echo "Build completed in ${duration} seconds"

このスクリプトで、ローカルとリモートのビルド時間を比較できます。

実測結果:コスト比較

各プラットフォームの料金体系と、実際の使用量に基づくコスト試算を行いました。

無料枠の比較

#プラットフォーム帯域幅ビルド時間サーバーレス実行時間特記事項
1Vercel100GB/月6000 分/月100GB-時Hobby プラン
2Netlify100GB/月300 分/月125000 リクエスト/月無料プラン
3Cloudflare Pages無制限500 ビルド/月100000 リクエスト/日無料プラン

Cloudflare Pages は帯域幅が無制限という大きなアドバンテージがあります。Vercel はビルド時間の枠が最も大きく、頻繁なデプロイに適しています。

月間 100 万 PV を想定したコスト試算

typescript// コスト計算の例
interface CostEstimate {
  platform: string;
  bandwidth: number; // GB
  requests: number; // リクエスト数
  buildMinutes: number; // ビルド時間(分)
  estimatedCost: number; // 月額(USD)
}

// 月間100万PV、平均ページサイズ500KB、月間デプロイ30回を想定
const costEstimates: CostEstimate[] = [
  {
    platform: 'Vercel',
    bandwidth: 500, // 100万PV × 500KB
    requests: 1000000,
    buildMinutes: 120, // 30回 × 4分
    estimatedCost: 20, // Pro プラン
  },
  {
    platform: 'Netlify',
    bandwidth: 500,
    requests: 1000000,
    buildMinutes: 120,
    estimatedCost: 19, // Pro プラン
  },
  {
    platform: 'Cloudflare Pages',
    bandwidth: 500,
    requests: 1000000,
    buildMinutes: 120,
    estimatedCost: 0, // 無料枠内
  },
];

この試算では、Cloudflare Pages が圧倒的なコストメリットを持っています。

有料プランの価格比較

#プラットフォームプラン名月額主な追加特典
1VercelPro$20無制限メンバー、高速ビルド
2NetlifyPro$19高速ビルド、並列ビルド
3Cloudflare PagesPro$20優先サポート、高度な分析

有料プランの価格帯は似通っていますが、含まれる機能には違いがあります。

実測結果の総合評価

3 つのプラットフォームの実測結果を総合的に評価すると、以下のような特徴が浮かび上がりました。

Cloudflare Pages の強み

パフォーマンスとコストの両面で優れています。エッジワーカーによる低レイテンシー、無制限の帯域幅、高い無料枠が魅力です。特にグローバルなトラフィックが見込まれるサービスに最適でしょう。

Vercel の強み

バランスの取れた性能と、優れた開発者体験を提供します。Next.js 開発元ならではの最適化が施されており、Nuxt.js でも恩恵を受けられます。豊富なビルド時間の無料枠は、頻繁なデプロイを行うチームに適しています。

Netlify の強み

長年の実績と安定性が魅力です。冷起動は遅めですが、温起動時は十分な性能を発揮します。Git ワークフローとの統合や、豊富なプラグインエコシステムが開発を加速させるでしょう。

以下の図は、3 つのプラットフォームの特徴をレーダーチャート風に整理したものです。

mermaidflowchart LR
  subgraph Cloudflare["Cloudflare Pages"]
    cf_perf["性能: ★★★"]
    cf_cost["コスト: ★★★"]
    cf_dx["開発体験: ★★"]
  end

  subgraph Vercel["Vercel"]
    v_perf["性能: ★★★"]
    v_cost["コスト: ★★"]
    v_dx["開発体験: ★★★"]
  end

  subgraph Netlify["Netlify"]
    n_perf["性能: ★★"]
    n_cost["コスト: ★★"]
    n_dx["開発体験: ★★★"]
  end

各プラットフォームの強みが異なるため、プロジェクトの要件に応じて選択することが重要です。

選定基準の提案

typescript// プラットフォーム選定ロジックの例
interface ProjectRequirements {
  expectedPV: number; // 月間PV
  budgetUSD: number; // 月額予算
  deployFrequency: number; // 月間デプロイ回数
  globalAudience: boolean; // グローバルユーザー有無
  prioritizeSpeed: boolean; // 速度優先か
}

function selectPlatform(
  requirements: ProjectRequirements
): string {
  // コスト重視かつ高トラフィック
  if (
    requirements.expectedPV > 500000 &&
    requirements.budgetUSD < 20
  ) {
    return 'Cloudflare Pages';
  }

  // 開発体験重視
  if (requirements.deployFrequency > 50) {
    return 'Vercel';
  }

  // グローバル展開かつ速度重視
  if (
    requirements.globalAudience &&
    requirements.prioritizeSpeed
  ) {
    return 'Cloudflare Pages';
  }

  // 安定性重視
  return 'Netlify';
}

このロジックを参考に、プロジェクトに最適なプラットフォームを選定できます。

typescript// 使用例
const myProject: ProjectRequirements = {
  expectedPV: 1000000,
  budgetUSD: 10,
  deployFrequency: 30,
  globalAudience: true,
  prioritizeSpeed: true,
};

const recommended = selectPlatform(myProject);
console.log(`推奨プラットフォーム: ${recommended}`);
// 出力: "推奨プラットフォーム: Cloudflare Pages"

要件を入力するだけで、適切なプラットフォームを提案できるでしょう。

まとめ

Nuxt.js アプリケーションを Vercel、Netlify、Cloudflare Pages の 3 つのプラットフォームにデプロイし、性能とコストを実測した結果、それぞれに明確な特徴があることが分かりました。

Cloudflare Pages は、冷起動 89ms、温起動 42ms という圧倒的な速度と無制限の帯域幅により、高トラフィックのグローバルサービスに最適です。コスト面でも月間 100 万 PV 程度なら無料枠内で運用できる可能性が高く、スタートアップや個人開発者にとって魅力的な選択肢になるでしょう。

Vercel は、温起動 68ms という優秀な性能と、月間 6000 分のビルド時間により、頻繁なデプロイを行う開発チームに向いています。Next.js の開発元ならではの最適化により、安定した開発体験を提供してくれます。

Netlify は、冷起動が 756ms とやや遅いものの、温起動時は 124ms と実用的な速度です。長年の実績による安定性と、豊富なプラグインエコシステムが強みとなっており、既存の JAMstack ワークフローを持つチームには移行コストが低いでしょう。

重要なのは、これらの測定結果は一つの参考データであり、実際のアプリケーションの特性によって結果は変わる可能性があるということです。SSR の複雑さ、外部 API の呼び出し、画像の最適化など、さまざまな要素がパフォーマンスに影響します。

今回の実測データを基に、あなたのプロジェクトの要件に最も適したプラットフォームを選択し、必要に応じて実際に試してみることをお勧めします。多くのプラットフォームが無料枠を提供しているため、実際にデプロイして体感してみるのが最も確実な判断材料になるでしょう。

デプロイ先の選択は、アプリケーションの成功を左右する重要な決定です。この記事が、あなたの意思決定の一助となれば幸いです。

関連リンク