Milten.ioMilten
Использование HTTP/2 и brotli в проектах на Next.js
Производительность

Использование HTTP/2 и brotli в проектах на Next.js

Next.js, как популярный фреймворк, предоставляет встроенные механизмы для оптимизации, но их эффективное использование требует понимания технологий. В этой статье мы разберем практические решения для внедрения HTTP/2 и сжатия в проекты на Next.js, основываясь на реальных кейсах.

Производительность веб-приложений напрямую влияет на пользовательский опыт и SEO. Согласно исследованиям Google, 53% пользователей покидают страницы, которые загружаются дольше 3 секунд. Современные протоколы, такие как HTTP/2, и эффективные методы сжатия данных становятся ключевыми инструментами для улучшения метрик вроде LCP (Largest Contentful Paint) и CLS (Cumulative Layout Shift).

HTTP/2 решает проблему "head-of-line blocking" HTTP/1.1, позволяя отправлять несколько запросов через один TCP-соединение. Это критично для страниц с множеством ресурсов.

Требования:

  • HTTPS: HTTP/2 требует TLS-шифрования. Для локальной разработки можно сгенерировать самоподписанный сертификат:
openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365

Настройка в Next.js:

  • Vercel (по умолчанию): При деплое на Vercel HTTP/2 включен автоматически.
  • Self-hosting: Используйте Node.js сервер с модулем https:
import next from 'next';
import fs from 'node:fs';
import https from 'node:https';
 
const app = next({ dev: process.env.NODE_ENV !== 'production', port });
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();

Проверка:

Используйте Chrome DevTools (вкладка Network) или команду:

curl -I --http2 https://your-site.com

Настройка сжатия: Brotli vs Gzip

Brotli обеспечивает на 20-25% лучшее сжатие, чем Gzip. Next.js поддерживает оба формата, но рекомендуется использовать Brotli для текстовых ресурсов (HTML, JS, CSS).

Активация Brotli в Next.js:

  • Vercel: Включено по умолчанию.
  • Self-hosting: Добавьте middleware compression с Brotli:
import compression from 'compression';
import next from 'next';
import fs from 'node:fs';
import https from 'node:https';
 
const app = next({ dev: process.env.NODE_ENV !== 'production', port });
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) => {
                compression({
                    brotli: {
                        enabled: true,
                        // params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 11 }
                    },
                });
 
                await handle(request, response);
            }
        )
        .listen(3000);
 
    console.info(`Ready on https://localhost:3000`);
}

Пример заголовков:

Content-Encoding: br

Эффективность сжатия на примере JS

ФорматРазмер исходного файлаСжатый размер (JS)
Gzip100 KB30 KB
Brotli100 KB22 KB

Использование Server Push

HTTP/2 Server Push позволяет отправлять ресурсы клиенту до его запроса. В Next.js это реализуется через компонент Link:

import Link from 'next/link';
 
<Link href="/about" prefetch>
    <a>About project</a>
</Link>;

Ручное управление Push:

Для критических ресурсов (например, шрифтов) можно использовать http2.pushStream:

server.get('/critical-page', (req, res) => {
    res.push('/_next/static/chunks/webpack.js', {}).end();
});

Минусы:

  • Перегрузка сети: Не пушите более 5-6 ресурсов.
  • Поддержка: Некоторые старые прокси могут не обрабатывать Push.

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

Next.js предоставляет компонент Image с автоматической конвертацией в WebP:

import Image from 'next/image';
 
<Image src="/example.jpg" alt="Example" width={800} height={600} quality={75} />;

Сравнение форматов:

ФорматРазмер (1920×1080)Поддержка
JPEG200 KBВсе
WebP120 KB95%+
AVIF80 KB70%

Частые ошибки

ОшибкаРешение
Отсутствие TLS-сертификатаИспользуйте Let's Encrypt для продакшена.
Неправильная настройка BrotliПроверьте заголовки ответа через curl.
Перегрузка Push-ресурсамиОграничьте количество пушей.

Заключение

HTTP/2 и сжатие остаются фундаментом оптимизации до прихода HTTP/3. Для Next.js-проектов важно сочетать встроенные механизмы с ручной настройкой сервера. Тестирование через Lighthouse и WebPageTest позволит точно оценить эффект.

Экспериментируйте с настройками, следите за обновлениями (например, эксперименты с HTTP/3 в Vercel), и помните: оптимизация — это процесс, а не разовая задача.

Источники:

Interaction to Next Paint
Проверка скорости интерактивности в режиме реального времениНачать сейчас
Мы используем Cookies

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

Использование HTTP/2 и brotli в проектах на Next.js