
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
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: