Next.jsのサイト表示速度を向上させるCloudflare Workers導入法

現在、主流となりつつあるインフラ構築を意識せずにサーバーを利用できるサーバーレス環境。CDN環境を提供するサービスとして有名なCloudflareでもサーバーレス環境を構築できるCloudflare Workersという機能があります。

今回は、このCloudflare Workersを使ってNext.jsプロジェクトをデプロイする方法を紹介していきます。

Cloudflare Workersのメリットとは

Cloudflare workersは、他のサーバレス環境とは異なりホットスタンバイ環境のため、アクセスから起動までがゼロタイムで実行されます。

他のコールドスタンバイ環境では、アクセスがあってからサーバーを立ち上げるため処理実行までにタイムラグが発生します。Cloudflare Workersでは、それがないため非常に早くページへアクセスが可能になります。

ローカルにCloudflare Workersの環境を構築する

Cloudflare WorkersをNext.jsで使用するためには、 @opennextjs/cloudflare というパッケージをプロジェクトに追加する必要があります。
> yarn add @opennextjs/cloudflare@latest
また、ローカル環境で実行するためのパッケージ wrangler を開発依存として追加します。
> yarn add -D wrangler@latest

次に、wranglerと連携するための設定ファイルをルートディレクトリに設置します。

// wrangler.jsonc
{
  "main": ".open-next/worker.js",
  "name": "my-app",
  "compatibility_date": "2025-03-25",
  "compatibility_flags": [
    "nodejs_compat"
  ],
  "assets": {
    "directory": ".open-next/assets",
    "binding": "ASSETS"
  }
}

OpenNextで実行するための設定ファイルを設置

Next.jsは、異なるプラットフォーム(AWS, Cloudflare, Netlifyなど)でセルフホストする手段がないため、OpenNextを使ってそれを構築することができます。

// open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";

export default defineCloudflareConfig();

最後に、package.jsonにローカル環境でOpenNextを実行するためのコマンドを追加します。

  • preview : ローカル環境でOpenNextを使ってプロジェクト実行することができます。
  • deploy : Cloudflare環境にプロジェクトをデプロイします。
  • cf-typegen : プロジェクト内にenvのtypeファイルであるcloudflare-env.d.tsを生成します
"preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview",
"deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
"cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"

ローカルでOpenNextを実行

以下のコマンドを実行してOpenNextサーバーでプロジェクトを起動します。

> yarn run preview
yarn run v1.22.21
warning ../../package.json: No license field
$ opennextjs-cloudflare build && opennextjs-cloudflare preview

┌─────────────────────────────┐
│ OpenNext — Cloudflare build │
└─────────────────────────────┘

App directory: /xxxx/xxxx/xxxx/xxxx
Next.js version : 15.3.3
@opennextjs/cloudflare version: 1.2.1
@opennextjs/aws version: 3.6.5

┌─────────────────────────────────┐
│ OpenNext — Building Next.js app │
└─────────────────────────────────┘

warning ../../package.json: No license field
$ next build
Using vars defined in .dev.vars
Using vars defined in .dev.vars
   ▲ Next.js 15.3.3

   Creating an optimized production build ...
Using vars defined in .dev.vars
Using vars defined in .dev.vars
Using vars defined in .dev.vars
 ✓ Compiled successfully in 8.0s
 ✓ Linting and checking validity of types    
 ✓ Collecting page data    
 ✓ Generating static pages (5/5)
 ✓ Collecting build traces    
 ✓ Finalizing page optimization    

Route (app)                                 Size  First Load JS    
┌ ○ /                                    5.63 kB         107 kB
└ ○ /_not-found                            977 B         102 kB
+ First Load JS shared by all             101 kB
  ├ chunks/4bd1b696-67ee12fb04071d3b.js  53.2 kB
  ├ chunks/684-c85650275c47a38c.js       45.9 kB
  └ other shared chunks (total)          1.89 kB


○  (Static)  prerendered as static content


┌──────────────────────────────┐
│ OpenNext — Generating bundle │
└──────────────────────────────┘

Bundling middleware function...
Bundling static assets...
Bundling cache assets...
Building server function: default...
Applying code patches: 4.757s
# copyPackageTemplateFiles
⚙️ Bundling the OpenNext server...

Applying code patches:
 - patching require
Worker saved in `.open-next/worker.js` 🚀

OpenNext build complete.

┌───────────────────────────────┐
│ OpenNext — Cloudflare preview │
└───────────────────────────────┘

Incremental cache does not need populating
Tag cache does not need populating
warning ../../package.json: No license field

Cloudflare collects anonymous telemetry about your usage of Wrangler. Learn more at https://github.com/cloudflare/workers-sdk/tree/main/packages/wrangler/telemetry.md

 ⛅️ wrangler 4.19.1
───────────────────
╭──────────────────────────────────────────────────────────────────────╮
│  [b] open a browser [d] open devtools [c] clear console [x] to exit  │
╰──────────────────────────────────────────────────────────────────────╯
Using vars defined in .dev.vars
Your Worker has access to the following bindings:
Binding                          Resource                  Mode
env.ASSETS                       Assets                    local
env.NEXTJS_ENV ("(hidden)")      Environment Variable      local

[wrangler:info] Ready on http://localhost:8787
⎔ Starting local server...
[mf:info] ✨ Parsed 1 valid header rule.
[wrangler:info] GET / 200 OK (304ms)
[wrangler:info] GET /_next/static/media/569ce4b8f30dc480-s.p.woff2 200 OK (73ms)
[wrangler:info] GET /_next/static/media/93f479601ee12b01-s.p.woff2 200 OK (71ms)
[wrangler:info] GET /_next/static/css/759b155474327f76.css 200 OK (71ms)
[wrangler:info] GET /next.svg 200 OK (19ms)
[wrangler:info] GET /_next/static/chunks/webpack-f029a09104d09cbc.js 200 OK (11ms)
[wrangler:info] GET /_next/static/chunks/4bd1b696-67ee12fb04071d3b.js 200 OK (14ms)
[wrangler:info] GET /_next/static/chunks/684-c85650275c47a38c.js 200 OK (80ms)
[wrangler:info] GET /_next/static/chunks/main-app-3b6c6040515531f7.js 200 OK (80ms)
[wrangler:info] GET /_next/static/chunks/app/page-e1249c665e4c9ed6.js 200 OK (71ms)
[wrangler:info] GET /_next/static/chunks/63-11f4d058746abff6.js 200 OK (82ms)
[wrangler:info] GET /vercel.svg 200 OK (71ms)
[wrangler:info] GET /window.svg 200 OK (63ms)
[wrangler:info] GET /file.svg 200 OK (224ms)
[wrangler:info] GET /globe.svg 200 OK (221ms)
[wrangler:info] GET /favicon.ico 200 OK (192ms)
すると以下のような画面がローカル環境で表示されるようになります。 cloudflare workers nextjs preview

実行時の注意点

Cloudflare Workersでは、CommonJSモードで動く一部の古いパッケージが使えないことがあります。基本的には、EMSモードで実装されたパッケージで動作しているためパッケージを置き換えるか、使わない形に実装を変える必要があります。

Cloudflare Workersへデプロイ

ローカル環境で動作確認ができたら、次は下記のコマンドでCloudflare Workersへデプロイしてみます。

> yarn run deploy

すると、ブラウザが開きCloudflare Workersにインスタンスを追加する許可を求められるので許可します。許可すると、ログの最後にURLが発行されるのでそこからページへアクセスすることができるようになります。

cloudflare workers deploy

Cloudflareのページからも確認できる

このデプロイは、CloudflrareのページからもWorkersタブを開くことで、下記のように確認することができます。 cloudflare workers home