Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

セッションの再利用

最終更新 Markdown で表示Agent セットアップ

既定では、Browser Sessions のリクエストごとに新しいブラウザーインスタンスが起動します。セッションを再利用すると、既存のブラウザーに再接続するため、コールドスタート時間をなくし、性能を高められます。

この機能は Browser Sessions(PuppeteerPlaywrightCDP)に適用されます。Quick Actions はセッションのライフサイクルを自動で扱います。

セッションを再利用する方法は 2 つあります。

  • 切断して再接続する(このページで説明します): browser.close() ではなく browser.disconnect() を使い、ブラウザーを生かしたまま次のリクエストで再接続します。利用可能なブラウザーセッションであればよい、ステートレスなワークロードに向いています。
  • Durable Objects: Durable Object 内に長時間稼働するブラウザーを保持し、ステートフルにセッションを管理します。リクエストをまたいで状態を保つ、または特定のユーザーを特定のブラウザーインスタンスへ振り分けたい場合に向いています。

1. Worker プロジェクトを作成する

Cloudflare Workers は、インフラの設定や運用なしに新しいアプリケーションを作ったり、既存のものを拡張したりできるサーバーレス実行環境です。Worker アプリケーションは、スクリーンショット取得などの操作をヘッドレスブラウザーと行うための入れ物です。

次のコマンドで、browser-worker という新しい Worker プロジェクトを作成します。

npm create cloudflare@latest -- browser-worker

セットアップでは、次のオプションを選びます。

  • What would you like to start with? では、Hello World example を選びます。
  • Which template would you like to use? では、Worker only を選びます。
  • Which language do you want to use? では、TypeScript を選びます。
  • Do you want to use git for version control? では、Yes を選びます。
  • Do you want to deploy your application? では、No を選びます(デプロイ前にいくつか変更します)。

2. Puppeteer をインストールする

browser-worker ディレクトリで、Cloudflare の Puppeteer フォーク をインストールします。

npm i -D @cloudflare/puppeteer

3. Wrangler 設定ファイル を構成する

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "browser-worker",
	"main": "src/index.ts",
	// Set this to today's date
	"compatibility_date": "2026-09-20",
	"compatibility_flags": ["nodejs_compat"],
	"browser": {
		"binding": "MYBROWSER",
	},
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "browser-worker"
main = "src/index.ts"
# Set this to today's date
compatibility_date = "2026-09-20"
compatibility_flags = [ "nodejs_compat" ]

[browser]
binding = "MYBROWSER"

4. コード

次のスクリプトは、まず現在稼働中のセッションを取得します。Worker がまだ接続していないセッションがあれば、ランダムなセッション ID を選び、puppeteer.connect(..) で接続を試みます。失敗した場合、または稼働中のセッションがなかった場合は、puppeteer.launch(..) で新しいブラウザーセッションを起動します。その後、Web サイトへ移動して DOM を取得します。完了したら browser.disconnect() で切断し、ほかの Worker が接続できるようにします。

ブラウザーがアイドル(コマンドを受け取らない状態)のまま、現在の 上限 を超えると自動で閉じます。セッションを維持するには、1 分あたり十分なリクエスト数が必要です。

import puppeteer from "@cloudflare/puppeteer";

export default {
	async fetch(request, env) {
		const url = new URL(request.url);
		let reqUrl = url.searchParams.get("url") || "https://example.com";
		reqUrl = new URL(reqUrl).toString(); // normalize

		// Pick random session from open sessions
		let sessionId = await this.getRandomSession(env.MYBROWSER);
		let browser, launched;
		if (sessionId) {
			try {
				browser = await puppeteer.connect(env.MYBROWSER, sessionId);
			} catch (e) {
				// another worker may have connected first
				console.log(`Failed to connect to ${sessionId}. Error ${e}`);
			}
		}
		if (!browser) {
			// No open sessions, launch new session
			browser = await puppeteer.launch(env.MYBROWSER);
			launched = true;
		}

		sessionId = browser.sessionId(); // get current session id

		// Do your work here
		const page = await browser.newPage();
		const response = await page.goto(reqUrl);
		const html = await response.text();

		// All work done, so free connection (IMPORTANT!)
		browser.disconnect();

		return new Response(
			`${launched ? "Launched" : "Connected to"} ${sessionId} \n-----\n` + html,
			{
				headers: {
					"content-type": "text/plain",
				},
			},
		);
	},

	// Pick random free session
	// Other custom logic could be used instead
	async getRandomSession(endpoint) {
		const sessions = await puppeteer.sessions(endpoint);
		console.log(`Sessions: ${JSON.stringify(sessions)}`);
		const sessionsIds = sessions
			.filter((v) => {
				return !v.connectionId; // remove sessions with workers connected to them
			})
			.map((v) => {
				return v.sessionId;
			});
		if (sessionsIds.length === 0) {
			return;
		}

		const sessionId =
			sessionsIds[Math.floor(Math.random() * sessionsIds.length)];

		return sessionId;
	},
};
import puppeteer from "@cloudflare/puppeteer";

interface Env {
	MYBROWSER: Fetcher;
}

export default {
	async fetch(request: Request, env: Env): Promise<Response> {
		const url = new URL(request.url);
		let reqUrl = url.searchParams.get("url") || "https://example.com";
		reqUrl = new URL(reqUrl).toString(); // normalize

		// Pick random session from open sessions
		let sessionId = await this.getRandomSession(env.MYBROWSER);
		let browser, launched;
		if (sessionId) {
			try {
				browser = await puppeteer.connect(env.MYBROWSER, sessionId);
			} catch (e) {
				// another worker may have connected first
				console.log(`Failed to connect to ${sessionId}. Error ${e}`);
			}
		}
		if (!browser) {
			// No open sessions, launch new session
			browser = await puppeteer.launch(env.MYBROWSER);
			launched = true;
		}

		sessionId = browser.sessionId(); // get current session id

		// Do your work here
		const page = await browser.newPage();
		const response = await page.goto(reqUrl);
		const html = await response!.text();

		// All work done, so free connection (IMPORTANT!)
		browser.disconnect();

		return new Response(
			`${launched ? "Launched" : "Connected to"} ${sessionId} \n-----\n` + html,
			{
				headers: {
					"content-type": "text/plain",
				},
			},
		);
	},

	// Pick random free session
	// Other custom logic could be used instead
	async getRandomSession(endpoint: puppeteer.BrowserWorker): Promise<string> {
		const sessions: puppeteer.ActiveSession[] =
			await puppeteer.sessions(endpoint);
		console.log(`Sessions: ${JSON.stringify(sessions)}`);
		const sessionsIds = sessions
			.filter((v) => {
				return !v.connectionId; // remove sessions with workers connected to them
			})
			.map((v) => {
				return v.sessionId;
			});
		if (sessionsIds.length === 0) {
			return;
		}

		const sessionId =
			sessionsIds[Math.floor(Math.random() * sessionsIds.length)];

		return sessionId!;
	},
};

puppeteer.sessions() 以外にも、セッション管理 を助けるメソッドを追加しています。

5. テストする

npx wrangler dev を実行し、Worker をローカルでテストします。

テストするには、次の URL を開きます。

<LOCAL_HOST_URL>/?url=https://example.com

6. デプロイする

npx wrangler deploy を実行して Worker を Cloudflare のグローバルネットワークへデプロイし、次の URL を開きます。

<YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.dev/?url=https://example.com

役に立ちましたか?