Пошук уроків, статей та іншого контенту
Порівняйте Edge Runtime і Node.js Runtime та оберіть середовище виконання для різних частин Next.js-застосунку.
Runtime — це середовище, у якому виконується серверний код Next.js:
Server Components;
Route Handlers;
Server Actions;
інші серверні частини застосунку.
Next.js підтримує два основні середовища виконання:
Node.js Runtime — повноцінне середовище Node.js.
Edge Runtime — легше середовище, побудоване навколо Web API та призначене для виконання ближче до користувача.
За замовчуванням Next.js використовує Node.js Runtime. Edge Runtime потрібно вказати явно для відповідного маршруту або сегмента.
Node.js Runtime надає стандартні можливості Node.js та підходить для більшості серверного коду в Next.js.
У Node.js Runtime можна використовувати:
модулі Node.js, наприклад fs, path, os, crypto;
більшість npm-пакетів;
бібліотеки, які використовують Node.js API;
драйвери баз даних;
файлову систему;
довгі або складні серверні операції;
повноцінний доступ до змінних середовища та серверної інфраструктури.
Наприклад, Route Handler може прочитати файл із файлової системи:
// app/api/server-info/route.ts
import { hostname } from 'node:os';
import { readFile } from 'node:fs/promises';
export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';
export async function GET() {
const packageJson = await readFile(
process.cwd() + '/package.json',
'utf-8',
);
const packageInfo = JSON.parse(packageJson);
return Response.json({
runtime: 'nodejs',
nodeVersion: process.version,
hostname: hostname(),
appName: packageInfo.name,
});
}Такий маршрут залежить від Node.js API, тому він не може виконуватися в Edge Runtime.
Edge Runtime — це легше серверне середовище, яке використовує переважно стандартні Web API:
Request;
Response;
fetch;
URL;
URLPattern;
Web Crypto API;
ReadableStream;
WebSocket у середовищах, де він підтримується.
Edge Runtime часто запускається на периферійних серверах, географічно ближчих до користувача. Це може зменшити затримку для простих запитів.
Приклад Route Handler для Edge Runtime:
// app/api/edge-info/route.ts
export const runtime = 'edge';
export async function GET(request: Request) {
const url = new URL(request.url);
return Response.json({
runtime: 'edge',
pathname: url.pathname,
requestId: crypto.randomUUID(),
currentTime: new Date().toISOString(),
});
}У цьому прикладі використовуються Web API, доступні в Edge Runtime. Node.js-модулі тут не потрібні.
Runtime задається експортом runtime у серверному файлі Next.js:
export const runtime = 'edge';або:
export const runtime = 'nodejs';Наприклад, для Route Handler структура може виглядати так:
app/
└── api/
├── edge-info/
│ └── route.ts
└── server-info/
└── route.tsФайл app/api/edge-info/route.ts працює в Edge Runtime, а app/api/server-info/route.ts — у Node.js Runtime.
Якщо runtime не вказано, використовується Node.js Runtime.
Runtime також можна вказувати в інших серверних файлах сегмента, наприклад у сторінці:
// app/profile/page.tsx
export const runtime = 'edge';
export default function ProfilePage() {
return <h1>Профіль</h1>;
}Налаштування сегмента впливають на серверний код відповідного маршруту. Важливо перевірити, що всі імпорти цього сегмента сумісні з вибраним runtime.
Node.js Runtime підтримує Node.js API:
import { readFile } from 'node:fs/promises';
import path from 'node:path';Edge Runtime не підтримує більшість вбудованих Node.js-модулів:
import { readFile } from 'node:fs/promises';
// Такий імпорт не сумісний з Edge RuntimeEdge Runtime натомість використовує Web API:
const response = await fetch('https://api.example.com/data');
const data = await response.json();Пакет можна використовувати в Edge Runtime лише тоді, коли він сумісний із цим середовищем.
Проблеми виникають, якщо бібліотека:
імпортує fs, net, tls або інші Node.js-модулі;
використовує require;
залежить від native-модулів;
очікує повноцінне середовище Node.js;
виконує операції з локальною файловою системою.
Навіть якщо проблемний код не викликається безпосередньо, імпорт несумісного пакета може спричинити помилку під час збірки або запуску.
Edge Runtime може бути корисним для коротких запитів, які потрібно обробляти ближче до користувача:
перевірка заголовків;
перенаправлення;
перевірка токена;
просте визначення регіону;
персоналізація відповіді;
отримання даних із зовнішнього HTTP API.
Однак Edge Runtime не гарантує автоматично меншу затримку. Результат залежить від:
хостинг-провайдера;
регіонів, у яких розгорнуто застосунок;
розташування бази даних;
розташування зовнішніх API;
кількості мережевих запитів.
Якщо Edge-функція працює близько до користувача, але щоразу звертається до бази даних в іншому континенті, перевага від близького розташування може зникнути.
Edge-функції зазвичай розраховані на швидкий запуск і короткі операції. Це особливо корисно для невеликих endpoint-ів і запитів із високою кількістю звернень.
Node.js Runtime краще підходить для важчих серверних операцій і бібліотек, яким потрібне повне середовище Node.js.
Не варто обирати Edge Runtime лише через його назву. Спочатку потрібно перевірити сумісність коду, залежностей і розташування даних.
fetch доступний в обох runtime, тому простий запит до зовнішнього HTTP API може працювати в обох середовищах.
Edge-версія:
// app/api/weather/route.ts
export const runtime = 'edge';
export async function GET() {
const response = await fetch('https://api.example.com/weather', {
headers: {
Accept: 'application/json',
},
});
if (!response.ok) {
return Response.json(
{ error: 'Не вдалося отримати дані про погоду' },
{ status: 502 },
);
}
const weather = await response.json();
return Response.json(weather);
}У цьому прикладі немає Node.js-специфічних API, тому код може підходити для Edge Runtime. Проте конкретний зовнішній API повинен підтримувати запити з обраного середовища.
Edge Runtime доречний, коли серверний код:
використовує лише Web API;
виконує коротку операцію;
працює із fetch;
перевіряє заголовки або cookies;
виконує просту авторизацію;
робить перенаправлення;
потребує низької затримки для користувачів у різних регіонах;
не використовує Node.js-модулі;
не потребує native-залежностей.
Прикладом може бути endpoint, який перевіряє заголовок запиту:
// app/api/check-access/route.ts
export const runtime = 'edge';
export async function GET(request: Request) {
const token = request.headers.get('authorization');
if (!token) {
return Response.json(
{ error: 'Потрібна авторизація' },
{ status: 401 },
);
}
return Response.json({
authorized: true,
});
}Node.js Runtime потрібен, коли код:
читає або записує файли;
використовує Node.js-модулі;
працює з бібліотекою, яка вимагає Node.js;
підключається до бази даних через Node.js-драйвер;
використовує native-модулі;
виконує складні серверні обчислення;
потребує повної екосистеми Node.js;
обробляє великі або довгі операції.
Для нового серверного маршруту Node.js Runtime часто є безпечним початковим вибором. Переходити на Edge Runtime варто після перевірки сумісності та вимірювання реальної потреби.
Для кожного серверного маршруту можна пройти такий список:
Чи використовує код fs, path, net, tls або інші Node.js-модулі?
Чи використовують імпортовані npm-пакети Node.js API?
Чи потрібен доступ до файлової системи або native-модулів?
Чи складається операція переважно з коротких HTTP-запитів?
Чи важливо виконувати код ближче до користувача?
Де розташована база даних або зовнішній сервіс?
Чи підтримує обраний хостинг потрібний runtime?
Якщо на перші три запитання відповідь «так», використовуйте Node.js Runtime.
Якщо код складається з Web API, короткий за виконанням і виграє від географічно близького виконання, можна розглянути Edge Runtime.
Уявімо застосунок із такими маршрутами:
/api/check-session перевіряє cookie;
/api/catalog отримує товари з бази даних;
/api/export формує файл для завантаження;
/api/currency звертається до зовнішнього HTTP API.
Можливий вибір:
/api/check-session — Edge Runtime, якщо використані лише cookies, заголовки та Web API;
/api/catalog — Node.js Runtime, якщо драйвер бази даних потребує Node.js;
/api/export — Node.js Runtime, якщо використовуються файлові операції або Node.js-бібліотека;
/api/currency — Edge Runtime або Node.js Runtime залежно від бібліотек, розташування сервісу та вимог до затримки.
Runtime можна вибирати окремо для різних маршрутів. Не потрібно переводити весь застосунок на Edge Runtime лише тому, що один endpoint добре для нього підходить.
// app/api/file/route.ts
import { readFile } from 'node:fs/promises';
export const runtime = 'edge';Цей код несумісний, оскільки Edge Runtime не має повноцінної файлової системи Node.js.
Виправлення:
змінити runtime на nodejs;
або замінити файлову операцію на сумісне зовнішнє сховище та HTTP API.
Edge Runtime не усуває мережеві затримки. Якщо endpoint звертається до віддаленої бази даних, основна затримка може виникати саме під час цього запиту.
Потрібно враховувати весь ланцюжок:
користувач → Edge Runtime → база даних → Edge Runtime → користувачБлизькість Edge Runtime до користувача не означає близькість до бази даних.
Пакет може працювати в Node.js Runtime, але не працювати в Edge Runtime. Перевіряйте документацію пакета та його залежності перед зміною runtime.
Якщо Edge-маршрут імпортує модуль, який усередині імпортує Node.js API, маршрут також може стати несумісним. Слід перевіряти весь ланцюжок імпортів, а не лише код Route Handler.
Не потрібно без причини додавати runtime = 'edge'. Якщо маршрут не має конкретної потреби в Edge Runtime, Node.js Runtime за замовчуванням часто спрощує розробку та сумісність.
Node.js Runtime — стандартне та сумісне середовище для більшості серверного коду Next.js.
Edge Runtime — легше середовище з Web API, яке може виконувати код ближче до користувача.
Node.js Runtime підтримує файлову систему, Node.js-модулі та ширший набір бібліотек.
Edge Runtime не підтримує більшість Node.js API та native-залежності.
Runtime задається через export const runtime = 'edge' або export const runtime = 'nodejs'.
Вибирайте runtime окремо для кожного маршруту або серверного сегмента.
Для Edge Runtime перевіряйте весь граф імпортів і підтримку залежностей.
Розташування бази даних і зовнішніх сервісів часто важливіше за саме розташування runtime.
Якщо немає чіткої потреби в Edge Runtime, Node.js Runtime є практичним початковим вибором.