
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 365Customization in Next.js:
-
Vercel (default): HTTP/2 is automatically enabled when deploying to Vercel.
-
Self-hosting: Use a Node.js server with the
httpsmodule:
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.comCompression 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
compressionwith 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: brCompression efficiency by JS example
| Format | Source File Size | Compressed Size (JS) |
|---|---|---|
| Gzip | 100 KB | 30 KB |
| Brotli | 100 KB | 22 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:
| Format | Size (1920×1080) | Support |
|---|---|---|
| JPEG | 200 KB | Все |
| WebP | 120 KB | 95%+ |
| AVIF | 80 KB | 70% |
Frequent errors
| Error | Solution |
|---|---|
| Lack of TLS certificate | Use Let's Encrypt for production. |
| Incorrect setting of Brotli | Check the response headers via curl. |
| Push resource overload | Limit 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: