はじめに
Cloudflare でウェブアプリをデプロイしようとすると、最初に迷うのが「Pages と Workers、どっちを使えばいいのか」です。
どちらもエッジで動き、どちらも無料枠があり、Pages には Functions という Workers 互換の機能も用意されている。公式ドキュメントを読んでも境界が曖昧に感じられます。
この記事では両者の設計思想の違いを整理し、プロジェクトの特性に応じた選定指針を示します。
設計思想の違い
根本的な違いは「何を起点に設計されているか」です。
| Pages | Workers | |
|---|---|---|
| 起点 | 静的アセット の配信 | リクエスト の処理 |
| デプロイ単位 | Git リポジトリ(ビルド → 配信) | スクリプト(wrangler deploy) |
| ルーティング | ファイルシステムベース | fetch イベントハンドラ |
| プレビュー | ブランチごとに自動生成 | 自動ブランチプレビューなし |
Pages は「HTML/CSS/JS をビルドしてエッジに配る」のが主務で、動的処理は後から追加するオプションです。Workers は「リクエストを受けてレスポンスを返す」関数が出発点で、静的アセットの配信は後から追加する機能です。
Pages Functions の位置付け
Pages には Functions という機能があります。functions/ ディレクトリにファイルを置くと、Workers と同じランタイム(V8 Isolate)で動的処理を追加できます。
export const onRequestGet: PagesFunction = async (context) => { return new Response(JSON.stringify({ message: "Hello" }), { headers: { "Content-Type": "application/json" }, });};これが混乱のもとです。「Pages でも API が書けるなら Workers はいらないのでは?」と思えてきます。
この記事で登場する Cloudflare 用語
- Durable Objects: キー単位で状態を持てる耐久オブジェクト。強整合な少量データの保持や WebSocket セッションの管理に使う
- Static Assets: Workers に静的ファイル配信を任せる機能。Workers 単体で SPA + API の構成が組める
- バインド: 別リソース(KV、D1、他の Workers など)への参照を環境に紐付ける仕組み。環境変数のリソース版
- Wrangler: Workers/Pages 用の公式 CLI。
wrangler deployなどでデプロイを実行する- V8 Isolate: Chrome の JS エンジン V8 が提供する軽量なサンドボックス。Workers のランタイム基盤
しかし Pages Functions にはいくつかの制約があります。
- Cron Triggers が使えない。定期実行が必要なら Workers が必須
- Durable Objects を直接ホストできない。クラスの定義は Workers でしかできない(Pages Functions から別 Workers の Durable Objects へバインドは可能)
- デプロイがビルドと結合している。静的アセットと Functions は常に同時にデプロイされるため、API だけの更新でもビルドが走る
- ルーティングがファイルシステム固定。
_middleware.tsによる前処理や_routes.jsonでの制御はできるが、Workers のfetchハンドラのように URL パターンをコードで自由に振り分けたい構成には向かない
逆に言えば、これらに該当しなければ Pages Functions で十分です。
選定のフローチャート
flowchart TD
A["プロジェクトの種類は?"] --> B{"静的サイト / SSG が主体?"}
B -- Yes --> C{"API やサーバー処理は?"}
C -- 不要 --> D["Pages のみ"]
C -- 簡単な API --> E["Pages + Functions"]
C -- Cron / Durable Objects --> F["Pages + 別 Workers"]
B -- No --> G{"静的アセットは?"}
G -- なし --> H["Workers のみ"]
G -- あり --> I["Workers + Static Assets"]
実際の判断基準をもう少し具体的に書くと、こうなります。
- ブログ、ドキュメントサイト、LP: Pages のみ。ビルド → 配信のパイプラインがそのまま使えるので、これ以上シンプルな選択肢はない
- SSG + お問い合わせフォーム / 簡易 API: Pages + Functions。API のために別サービスを立てる必要がない
- SPA + バックエンド API: Workers(Static Assets 機能で SPA を配信しつつ、同じプロジェクトで API も処理)
- 定期バッチ、Webhook 受信、WebSocket: Workers 単体。Cron Triggers や Durable Objects は Workers でしか使えない
- SSG + 重めのバックエンド: Pages(フロント)+ Workers(API)の分離構成
統合の方向性
Cloudflare は 2024 年以降、Pages と Workers の統合を段階的に進めています。Workers に Static Assets 機能が追加され、Workers 単体で静的ファイルの配信が可能になりました。
長期的には Workers が統一プラットフォームになり、Pages は Workers の「静的サイト向けプリセット」という位置付けに寄っていく方向です。実際、公式の移行ガイドも Pages → Workers の経路を案内しています。ただし現時点では Pages のブランチプレビューや Git 連携ビルドは Workers にはなく、静的サイトなら Pages を選ぶ理由は十分にあります。
新規プロジェクトでの判断としては、以下の方針がおすすめです。
- 静的サイトが主体: Pages を選ぶ。Git 連携ビルドとブランチプレビューの価値が高い
- 動的処理が主体: Workers を選ぶ。制約が少なく、将来の拡張にも対応しやすい
- 迷ったら: Pages から始める。Pages Functions で足りなくなった時点で、その機能だけ Workers に切り出す
まとめ
- Pages は「静的アセットの配信」が起点、Workers は「リクエストの処理」が起点。設計思想が根本的に違う
- Pages Functions は Workers 互換のランタイムだが、Cron Triggers や Durable Objects は使えない
- 静的サイト + 簡易 API なら Pages + Functions、動的処理が主体なら Workers を選ぶ
- 長期的には統合が進むが、現時点では Pages のブランチプレビューと Git 連携が差別化ポイント
このブログ自体は Astro の SSG を Pages でホスティングしており、動的処理は一切使っていません。Pages のみで完結する最もシンプルな構成です。
Pages そのものの仕組みや機能を詳しく知りたい方は、Cloudflare Pages とは何か:静的サイトホスティングの実力も参考にしてください。