Introduction
In modern web applications, API response sizes can significantly impact performance, especially when dealing with large datasets, nested objects, or extensive user listings. Response payload compression is a critical optimization technique that can reduce bandwidth usage by up to 70-90% and improve application responsiveness.
This tutorial demonstrates how to implement response compression using Node.js built in package for compression with Brotli compression.
require('zlib')
Why Response Compression Matters
When APIs return large datasets containing:
- Extensive user listings with nested properties
- Complex object hierarchies
- Large JSON responses with repetitive data structures
- File content or base64-encoded data
Uncompressed responses can lead to:
- Increased bandwidth costs
- Slower page load times
- Poor user experience on mobile networks
- Higher server resource utilization
Implementation Overview
Core Implementation with Brotli Compression
Here’s a practical implementation using Node.js and the zlib package:
This is a handler which returns the list of users lets consider we have to return a complex nested object which will increase the payload size.
const { ResponseHelper } = require('./ResponseClass')
async function handler() {
let options = {}
options.compress = true
const response = new ResponseHelper(options)
const res = await response.ok({
message: "Success",
data: {
users: [
{
id: 1,
name: "Jack Thompson",
email: "jack.thompson@company.com",
profile: {
avatar: "https://cdn.company.com/avatars/jack_1024x1024.jpg",
bio: "Senior Software Engineer with 8+ years of experience in full-stack development",
skills: ["JavaScript", "Python", "React", "Node.js", "AWS", "Docker"],
certifications: [
{ name: "AWS Solutions Architect", issuer: "Amazon", year: 2023 },
{ name: "Kubernetes Administrator", issuer: "CNCF", year: 2022 }
]
},
employment: {
department: "Engineering",
position: "Senior Software Engineer",
level: "L5",
salary: 95000,
startDate: "2019-03-15",
manager: { id: 15, name: "Sarah Wilson" },
team: {
name: "Platform Engineering",
members: 12,
projects: ["API Gateway", "Microservices Migration", "DevOps Pipeline"]
}
},
permissions: {
roles: ["developer", "code_reviewer", "mentor"],
accessLevels: ["production_read", "staging_write", "development_admin"],
repositories: ["frontend-app", "backend-api", "shared-components"]
},
activity: {
lastLogin: "2024-06-25T14:30:00Z",
projectsCount: 23,
commitsThisMonth: 47,
reviewsCompleted: 15,
mentoringSessions: 8
}
},
{
id: 2,
name: "Olivia Rodriguez",
email: "olivia.rodriguez@company.com",
profile: {
avatar: "https://cdn.company.com/avatars/olivia_1024x1024.jpg",
bio: "Product Marketing Manager driving user acquisition and retention strategies",
skills: ["Product Marketing", "Analytics", "A/B Testing", "SQL", "Figma", "Salesforce"],
certifications: [
{ name: "Google Analytics Certified", issuer: "Google", year: 2023 },
{ name: "Product Marketing Core", issuer: "Product Marketing Alliance", year: 2022 }
]
},
employment: {
department: "Marketing",
position: "Product Marketing Manager",
level: "M3",
salary: 78000,
startDate: "2021-08-20",
manager: { id: 8, name: "Michael Chen" },
team: {
name: "Growth Marketing",
members: 8,
projects: ["Q3 Campaign Launch", "User Onboarding Optimization", "Competitive Analysis"]
}
},
permissions: {
roles: ["marketer", "analyst", "campaign_manager"],
accessLevels: ["analytics_full", "crm_write", "social_media_admin"],
tools: ["Google Analytics", "Salesforce", "HubSpot", "Figma", "Looker"]
},
activity: {
lastLogin: "2024-06-26T09:15:00Z",
campaignsLaunched: 12,
reportsGenerated: 28,
meetingsAttended: 35,
presentationsGiven: 6
}
},
})
return res;
}
handler()
So let’s try to implement this using the HTTPS Response Helper class where we can control the compression of data if its required.
ResponseHelper Implementation
The ResponseHelper class handles compression internally:
//ResponseClass
const zlib = require('zlib')
class ResponseHelper {
constructor(options = {}) {
this.compress = options.compress || false
}
async ok(data) {
const jsonResponse = JSON.stringify(data)
if (this.compress) {
const compressed = await this.compressResponse(jsonResponse)
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Content-Encoding': 'br'
},
body: compressed.toString('base64'),
isBase64Encoded: true
}
}
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json'
},
body: jsonResponse
}
}
compressResponse(data) {
return new Promise((resolve, reject) => {
zlib.brotliCompress(data, (err, compressed) => {
if (err) reject(err)
else resolve(compressed)
})
})
}
}
The key’s isBase64Encoded: true helps the browser understand that the content is encoded in base64 and 'Content-Encoding': 'br' helps the browser in understand the Compression used for the content.
Compression Techniques Comparison
Brotli Compression
- Best compression ratio: Up to 20% better than gzip
- Optimized for web content: Particularly effective with JSON and HTML
- Browser support: Modern browsers (Chrome 50+, Firefox 44+)
- Use case: Production APIs with modern client support
Gzip Compression
- Universal support: Supported by all browsers
- Good compression ratio: Standard web compression
- Fast processing: Lower CPU overhead
- Good for Dynamic Content: If you need to compress content on the fly, Gzip might be a better choice due to its faster compression speed.
- Use case: Legacy browser support required
Deflate Compression
- Basic compression: Older standard
- Minimal overhead: Fastest processing
- Limited effectiveness: Lower compression ratios
- Use case: Resource-constrained environments
Best Practices
When to Enable Compression
- Large JSON responses (>1KB)
- Repetitive data structures
- High-traffic APIs
- Mobile-first applications
When to Avoid Compression
- Very small responses (<500 bytes)
- Already compressed content (images, videos)
- Real-time applications requiring minimal latency
- CPU-constrained environments
Conclusion
Response payload compression is a powerful optimization technique that can significantly improve API performance with minimal implementation effort. By leveraging Brotli compression in Node.js applications you can achieve substantial bandwidth savings and improved user experience.