Milten.ioMilten
Using HTTP/2 and brotli in NextJS
Prestazioni

Using HTTP/2 and brotli in NextJS

Next.js, as a popular framework, provides built-in mechanisms for optimization, but their effective use requires an understanding of the technologies. In this article, we will explore practical solutions for implementing HTTP/2 and compression in Next.js projects based on real cases.

Web application performance has a direct impact on user experience and SEO. According to Google research, 53% of users abandon pages that take longer than 3 seconds to load. Modern protocols like HTTP/2 and efficient data compression techniques are becoming key tools to improve metrics like LCP (Largest Contentful Paint) and CLS (Cumulative Layout Shift).

HTTP/2 solves the “head-of-line blocking ” problem of HTTP/1.1 by allowing multiple requests to be sent over a single TCP connection. This is critical for pages with multiple resources.

Requirements:

  • HTTPS: HTTP/2 requires TLS encryption. A self-signed certificate can be generated for local development:
openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365

Customization in Next.js:

  • Vercel (default): HTTP/2 is automatically enabled when deploying to Vercel.

  • Self-hosting: Use a Node.js server with the https module:

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();

Verification:

Use Chrome DevTools (Network tab) or command:

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

Compression settings: Brotli vs Gzip

Brotli provides 20-25% better compression than Gzip. Next.js supports both formats, but it is recommended to use Brotli for text resources (HTML, JS, CSS).

Brotli activation in Next.js:

  • Vercel: Enabled by default.

  • Self-hosting: Add middleware compression with 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`);
}

Example headers:

Content-Encoding: br

Compression efficiency by JS example

FormatSource File SizeCompressed Size (JS)
Gzip100 KB30 KB
Brotli100 KB22 KB

Using Server Push

HTTP/2 Server Push allows you to send resources to the client before the client requests them. In Next.js this is implemented through the Link component:

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

Manual Push Control:

For critical resources (such as fonts), you can use http2.pushStream:

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

Cons:

  • Network overload: Don't fluff more than 5-6 resources.

  • Support: Some older proxies may not be able to handle Push.

Image Optimization

Next.js provides an Image component with automatic conversion to WebP:

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

Format Comparison:

FormatSize (1920×1080)Support
JPEG200 KBВсе
WebP120 KB95%+
AVIF80 KB70%

Frequent errors

ErrorSolution
Lack of TLS certificateUse Let's Encrypt for production.
Incorrect setting of BrotliCheck the response headers via curl.
Push resource overloadLimit the number of pooches.

Conclusion

HTTP/2 and compression remain the foundation of optimization until the arrival of HTTP/3. For Next.js projects, it is important to combine built-in mechanisms with manual server configuration. Testing via Lighthouse and WebPageTest will allow you to accurately assess the effect.

Experiment with settings, keep an eye on updates (e.g. experiments with HTTP/3 in Vercel), and remember: optimization is a process, not a one-time task.

Resources:

Debugger INP
Verifica in tempo reale l'interazione al prossimo disegno
Per iniziare
Usiamo i cookie

Usiamo i cookie per assicurarti la migliore esperienza sul nostro sito web. Per ulteriori informazioni su come usiamo i cookie, consulta la nostra politica sui cookie.

Using HTTP/2 and brotli in NextJS