INTEGRITY Документация

Повторное использование сеансов

По умолчанию каждый запрос Browser Sessions запускает новый экземпляр браузера. Повторное использование сессий устраняет время холодного старта и повышает производительность за счёт подключения к уже существующему браузеру вместо запуска нового.

Эта функция применяется к Browser Sessions (Puppeteer, Playwright, а также CDP). Быстрые действия автоматически управляют жизненным циклом сессии.

Есть два подхода к повторному использованию сеансов:

1. Создайте проект Worker

Cloudflare Workers предоставляет бессерверную среду выполнения, которая позволяет создавать новые приложения или дополнять существующие без настройки и обслуживания инфраструктуры. Ваше Worker-приложение служит контейнером для взаимодействия с headless-браузером и выполнения таких действий, как создание скриншотов.

Создайте новый проект Worker с именем browser-worker выполнив:

npm create cloudflare@latest -- browser-worker

Для настройки выберите следующие параметры:

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-08-28",
	"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-08-28"
compatibility_flags = [ "nodejs_compat" ]

[browser]
binding = "MYBROWSER"

4. Код

Приведённый ниже скрипт сначала получает список текущих активных сеансов. Если среди них есть сеансы без подключения от worker, скрипт выбирает случайный идентификатор сеанса и пытается подключиться (puppeteer.connect(..)) к нему. Если это не удаётся или изначально не было запущенных сеансов, запускается новый сеанс браузера (puppeteer.launch(..)). Затем он переходит на сайт и получает DOM. После этого он отключается (browser.disconnect()), делая соединение доступным для других Workers.

Учитывайте, что если браузер простаивает, то есть не получает никаких команд, дольше текущего лимит, она закроется автоматически, поэтому у вас должно быть достаточно запросов в минуту, чтобы поддерживать её активной.

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