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 | All |
| 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 Speed Scanner 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:



