Представьте ситуацию: ваша статья внезапно попала на главную страницу Hacker News или Reddit. Сотни, а то и тысячи посетителей одновременно заходят на ваш сайт. Готов ли он к такому сценарию? Недавно Martijn Hols решил не полагаться на догадки и провёл реальные замеры того, сколько трафика способен выдержать статически сгенерированный сайт на Next.js. Результаты тестов оказались неожиданными и заставили задуматься о реальных возможностях «статики».
🌟 Эксперимент автора: готовимся к "объятиям смерти"
Автор блога, Мартейн Холс, регулярно слышал утверждения, что статически сгенерированный сайт легко справится с сотнями пользователей. Чтобы проверить это на практике, он запустил простой тест на собственном проекте на базе Next.js, размещённом на VPS-сервере от TransIP. Для тестирования использовался популярный инструмент k6 (современный инструмент для нагрузочного тестирования и мониторинга производительности веб-приложений и API).
Итоги первых тестов оказались неожиданными:
🛑 193 запроса в секунду – максимально достижимый результат на VPS с одним контейнером. Причём только 63% запросов выполнялись менее чем за 500 мс. И это были «лёгкие» запросы только HTML-страницы, без дополнительных изображений или JavaScript-файлов.
Это означает, что всего несколько посетителей, открывших страницу одновременно (учитывая, что одна страница обычно создаёт около 60 дополнительных запросов), способны легко приблизить сервер к критической отметке.
📑 Почему один визит генерирует так много запросов?
Обычное посещение страницы на Next.js-сайте Холса выглядит примерно так:
🔍 DNS-запрос и SSL-хендшейк – стандартные операции, которые занимают считанные миллисекунды.
📄 Первичный HTML-документ (20 кБ) – главное, что загружает браузер.
🎨 CSS-стили (1.6 кБ) – страница уже становится визуально понятной и готова к базовому взаимодействию.
🖼️ Изображения «выше линии прокрутки» (около 7 кБ) – к этому моменту посетитель видит уже практически полноценную страницу и может с ней взаимодействовать.
🕒 Отложенные запросы – JavaScript, аналитика, иконки, предварительная загрузка других ресурсов – в сумме это ещё 60+ запросов на общую сумму ~435 кБ.
Несмотря на кажущуюся лёгкость каждого запроса, их огромное количество оказывает сильное влияние на сервер и пропускную способность сети.
📌 Вывод: статический Next.js-сайт – не такой уж лёгкий. Он намного сложнее стандартной статики (например, сайта на Hugo или Jekyll), так как подразумевает динамичную загрузку JS-файлов и изображений.
📈 Попытка масштабирования
Автор попытался увеличить производительность, запустив второй Docker-контейнер (по одному процессу Node.js на каждый процессор):
🐳 С двумя контейнерами результат увеличился до 275 RPS (+42%), что всё равно далеко от желаемого.
Проблема в том, что Next.js уже частично использует многопоточность для компрессии GZIP даже в одном процессе. Это значит, что просто добавляя дополнительные контейнеры, вы не получите линейный прирост производительности.
📊 Сравнение с серверным рендерингом (SSR)
Интересный поворот – автор также сравнил статическую генерацию с SSR (серверным рендерингом React-страниц):
🔻 Результаты SSR оказались намного хуже:
- Статическая страница: 193 RPS
- SSR-страница: всего лишь ~34 запроса в секунду на том же сервере.
Это значит, что серверный рендеринг снизил производительность почти в 6 раз.
🔥 Неожиданный стресс-тест
Судьба оказалась ироничной: на следующий день после проведения тестов статья Холса про проблемы с Google Translate попала на главную страницу Hacker News. Посетители полились на сайт, но, к счастью, трафик не оказался настолько большим, чтобы «уронить» сервер. Автор признался, что испытывал стресс, зная, что сервер работает на пределе своих возможностей.
🛠️ Переход на выделенный сервер
Разочарованный результатами VPS, автор решил перейти на выделенный сервер:
💻 Характеристики сервера:
- CPU: Intel Xeon-E 6 ядер, 12 потоков.
- SSD: NVMe 2×SSD.
- Пропускная способность сети: 500 Мбит/с.
После миграции он запустил 12 экземпляров приложения (по одному на каждый поток CPU), и результат оказался впечатляющим:
🔥 2 330 запросов в секунду вместо прежних 193 на VPS – прирост производительности в 12 раз!
Это доказывает, что мощность процессора играет огромную роль в Next.js, особенно при обслуживании большого количества запросов. И всё же сетевой канал (500 Мбит) стал новым ограничением, которое может проявиться при очень высоком трафике.
💬 Личное мнение автора статьи
На мой взгляд, результаты эксперимента Холса – ценный урок для всех разработчиков. Мы часто полагаемся на общие утверждения и считаем, что «статика выдержит любые нагрузки». Но важно понимать, что «статика» Next.js – это не просто HTML-файлы, это целый набор JavaScript, CSS и дополнительных ресурсов, которые серьёзно нагружают сервер даже при относительно небольшом количестве посетителей.
Несмотря на это, статическая генерация по-прежнему гораздо более производительна, чем SSR. Но чтобы быть действительно готовым к крупным всплескам трафика, нужно продуманно подходить к инфраструктуре и иметь запас мощности.
🔥 Вывод: что делать?
Вот несколько советов по итогам прочитанного:
✅ Используйте статическую генерацию для проектов, которые могут внезапно «выстрелить».
🚦 Проверяйте производительность заранее – например, с помощью k6.
🔧 Имейте план масштабирования на случай резкого увеличения трафика.
☁️ Рассмотрите использование CDN или кеширующих решений типа Cloudflare, если вам важна устойчивость к всплескам трафика.
🔗 Оригинальная статья: