Перейти к статье
Производительность25 июн. 2025 г.3 минуты чтения

HTTP/2 и Brotli в Next.js: настройка и проверка

Проверьте протокол и сжатие ответов в Next.js. Разберитесь в различиях HTTPS и HTTP/2, предзагрузки и Server Push, затем измерьте результат.

HTTP/2 и Brotli в Next.js: настройка и проверка

HTTP/2 и сжатие могут сократить передачу ресурсов и помочь загрузке, в том числе LCP. Сами по себе они не устраняют сдвиги макета и не гарантируют роста позиций в поиске. Отдельно измеряйте передачу данных, отрисовку и поведение страницы.

HTTP/2, HTTPS и размещение приложения

HTTP/2 передаёт несколько потоков запросов по одному соединению, уменьшая блокировку на уровне HTTP/1.1. При этом он использует TCP: потеря пакета может задержать все потоки на транспортном уровне. HTTP/3 уже применяется и иначе организует транспорт. Выбирайте протокол по измерениям и возможностям размещения.

Браузеры используют HTTP/2 через TLS. На управляемом хостинге, например Vercel, проверяйте протокол соединения с пограничным сервером. При самостоятельном размещении TLS и HTTP/2 можно завершать на обратном прокси или CDN перед сервером Next.js. Обычный Node.js-сервер с модулем https не становится HTTP/2-сервером только из-за HTTPS.

Для локального эксперимента с HTTPS можно создать сертификат для localhost. Это не сертификат для production:

openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365 -subj '/CN=localhost' -addext 'subjectAltName=DNS:localhost'

Следующий пример показывает HTTPS с HTTP/1.1, а не развёртывание HTTP/2. Нужен существующий проект Next.js, а в production-режиме — готовая сборка. Если особых требований нет, используйте стандартный сервер Next.js за прокси.

import next from 'next'
import fs from 'node:fs'
import https from 'node:https'

const app = next({ dev: process.env.NODE_ENV !== 'production', port: 3000 })
const handle = app.getRequestHandler()

async function startServer() {
	await app.prepare()

	https
		.createServer(
			{
				cert: fs.readFileSync('./cert.pem'),
				key: fs.readFileSync('./key.pem'),
			},
			async (request, response) => {
				await handle(request, response)
			},
		)
		.listen(3000)

	console.info(`Ready on https://localhost:3000`)
}

startServer()

Проверьте фактический протокол и сжатие

Посмотрите столбец Protocol на вкладке Network в Chrome DevTools. В сборке curl с поддержкой HTTP/2 первая команда выведет фактически выбранную версию: запрос HTTP/2 допускает откат на другой протокол. Вторая команда проверяет заголовки GET-ответа с заявленной поддержкой Brotli и gzip.

curl --http2 -sS -o /dev/null -w '%{http_version}\n' https://your-site.com
curl -sS -D - -o /dev/null -H 'Accept-Encoding: br, gzip' https://your-site.com

Brotli и gzip

При запуске через next start Next.js по умолчанию использует gzip. Brotli может сильнее сжать текст, но результат зависит от данных и настроек: универсального выигрыша 20–25% нет. На управляемом хостинге проверяйте реальные ответы. При самостоятельном размещении настройте Brotli на поддерживающем его прокси или CDN.

Отключайте сжатие Next.js только после настройки сжатия на другом уровне. Иначе сохраните значение по умолчанию. Эта настройка передаёт ответственность другому серверу, а не включает Brotli:

// next.config.mjs
export default {
  compress: false,
}

Пример заголовков ответа, сжатого Brotli:

Content-Encoding: br
Vary: Accept-Encoding

Не выставляйте Content-Encoding вручную для несжатого тела. Проверьте сжатый и резервный варианты ответа, а также учёт Accept-Encoding в кеше.

Числа ниже — учебный пример, а не измерение или гарантированный коэффициент сжатия:

ФорматИсходный JavaScriptСжатый размер в примере
Gzip100 KB30 KB
Brotli100 KB22 KB

Предзагрузка и Server Push — разные механизмы

Компонент Link в Next.js может заранее загружать ресурсы маршрута. Это запрос браузера, а не HTTP/2 Server Push. Начиная с Chrome 106 поддержка Server Push отключена по умолчанию; не делайте современную оптимизацию зависимой от неё.

import Link from 'next/link'

export default function AboutLink() {
  return <Link href="/about" prefetch>About</Link>
}

Для действительно критичного шрифта может подойти preload. Замените путь на реальный ресурс и согласуйте тип и настройки cross-origin:

<link rel="preload" href="/fonts/site.woff2" as="font" type="font/woff2" crossorigin>

Prefetch и preload расходуют пропускную способность. Универсального ограничения в пять или шесть ресурсов нет: добавляйте подсказки там, где измерения подтверждают пользу для загрузки или перехода.

Оптимизация изображений

next/image может отдавать оптимизированные форматы с учётом настроек и заголовка Accept браузера. Формат по умолчанию — WebP; для AVIF нужна соответствующая настройка. Указывайте размеры, чтобы резервировать место и уменьшать сдвиги макета.

import Image from 'next/image'

export default function ExampleImage() {
  return <Image src="/example.jpg" alt="Example" width={800} height={600} quality={75} />
}

Размеры файлов ниже иллюстративны. Результат зависит от изображения, разрешения и качества. Проверяйте браузеры своей аудитории вместо фиксированных процентов поддержки.

ФорматПример для 1920 × 1080Проверка поддержки
JPEG200 KBЦелевые браузеры
WebP120 KBЦелевые браузеры
AVIF80 KBЦелевые браузеры

Частые ошибки и сравнение результата

ПроблемаЧто проверить
Нет действительного TLS-сертификатаНастройте доверенный сертификат для production, например через Let’s Encrypt.
Ожидали Brotli, но ответ без негоПроверьте заголовки запроса и ответа, тип содержимого и настройки прокси.
Слишком много ранних запросовУберите бесполезные prefetch/preload и повторите сравнение.

Повторяйте измерения на той же странице с одинаковыми условиями устройства, сети и кеша. Speed Scanner и WebPageTest помогают сравнивать загрузку; само название протокола не доказывает улучшения. Сохраните настройки и результаты и повторяйте проверку после значимых изменений.

Проверка скорости

Узнайте, что замедляет ваш сайт

Проверьте страницу в Milten: получите показатели Core Web Vitals и рекомендации по ускорению загрузки.

Проверить сайт
Cookies

Мы используем Cookies

Мы используем куки, чтобы обеспечить вам лучший опыт на нашем сайте. Подробнее о том, как мы используем cookies, вы можете узнать в нашей политике конфиденциальности.