or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

Compression

Compression is a Node.js middleware that provides HTTP response compression for Express.js and other Connect-compatible frameworks. It automatically compresses response bodies using gzip, deflate, or brotli algorithms, improving bandwidth utilization and response times while maintaining compatibility with HTTP standards.

Package Information

  • Package Name: compression
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install compression

Core Imports

const compression = require('compression');

Basic Usage

const compression = require('compression');
const express = require('express');

const app = express();

// Enable compression for all responses
app.use(compression());

// Add routes
app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(3000);

Architecture

The compression middleware operates by:

  • Content Negotiation: Examines client Accept-Encoding headers to determine supported compression algorithms
  • Response Filtering: Uses configurable filter functions to determine which responses should be compressed
  • Stream-based Compression: Creates compression streams (gzip, deflate, or brotli) that process response data in chunks
  • Header Management: Automatically sets appropriate Content-Encoding and Vary headers
  • Threshold Control: Only compresses responses above a configurable size threshold
  • Back-pressure Support: Handles stream back-pressure for optimal memory usage

Capabilities

Main Compression Middleware

Creates compression middleware with configurable options for automatic HTTP response compression.

/**
 * Creates compression middleware for HTTP responses
 * @param {Object} [options] - Configuration options
 * @returns {Function} Express middleware function
 */
function compression(options);

Options Configuration:

interface CompressionOptions {
  /** Custom filter function to determine compression eligibility */
  filter?: (req, res) => boolean;
  /** Minimum response size for compression (default: 1024 bytes) */
  threshold?: number | string;
  /** Default encoding when client doesn't specify (default: 'identity') */
  enforceEncoding?: 'gzip' | 'deflate' | 'br' | 'identity';
  /** Compression level 0-9 (default: -1) */
  level?: number;
  /** Buffer chunk size for compression (default: 16384) */
  chunkSize?: number;
  /** Window bits parameter (default: 15) */
  windowBits?: number;
  /** Memory level 1-9 (default: 8) */
  memLevel?: number;
  /** Compression strategy constant */
  strategy?: number;
  /** Brotli-specific configuration options */
  brotli?: {
    params?: Object;
    [key: string]: any;
  };
  /** Additional zlib options passed through to compression streams */
  [key: string]: any;
}

Usage Examples:

// Basic usage with default options
app.use(compression());

// Custom threshold
app.use(compression({
  threshold: '2kb'
}));

// Custom filter function
app.use(compression({
  filter: (req, res) => {
    if (req.headers['x-no-compression']) {
      return false;
    }
    return compression.filter(req, res);
  }
}));

// Custom compression level
app.use(compression({
  level: 6,  // Balanced compression/speed
  threshold: 1024
}));

// Brotli configuration
app.use(compression({
  brotli: {
    params: {
      [require('zlib').constants.BROTLI_PARAM_QUALITY]: 6
    }
  }
}));

Default Filter Function

The default filter function used to determine if responses should be compressed based on Content-Type.

/**
 * Default filter function for determining compression eligibility
 * @param {Object} req - HTTP request object
 * @param {Object} res - HTTP response object
 * @returns {boolean} True if response should be compressed
 */
compression.filter(req, res);

Usage Example:

// Extend the default filter
function shouldCompress(req, res) {
  if (req.headers['x-no-compression']) {
    // Don't compress responses with this request header
    return false;
  }
  
  // Fallback to standard filter function
  return compression.filter(req, res);
}

app.use(compression({ filter: shouldCompress }));

Response Flush Method

The middleware adds a flush method to response objects for forcing partially-compressed data to be sent to clients.

/**
 * Forces partially-compressed response to be flushed to client
 * Added to response object by compression middleware
 */
res.flush();

Usage Example (Server-Sent Events):

app.use(compression());

app.get('/events', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');

  // Send periodic data
  const timer = setInterval(() => {
    res.write('data: ping\\n\\n');
    
    // Force flush to ensure data reaches client immediately
    res.flush();
  }, 2000);

  res.on('close', () => {
    clearInterval(timer);
  });
});

Compression Algorithms

The middleware supports multiple compression algorithms with automatic negotiation:

  • gzip: Widely supported, good compression ratio
  • deflate: Universal support, slightly less efficient than gzip
  • brotli: Modern algorithm with better compression (Node.js v10.16.0+ and v11.7.0+)
  • identity: No compression (passthrough)

The middleware automatically selects the best algorithm based on:

  1. Client Accept-Encoding header preferences
  2. Server-configured algorithm priorities
  3. Node.js version capabilities (for brotli support)

Behavior and Limitations

Automatic Compression Triggers

Responses are compressed when:

  • Content-Type is compressible (determined by the compressible package)
  • Response size meets or exceeds the threshold (default: 1KB)
  • Client accepts compression via Accept-Encoding header
  • Response doesn't have Cache-Control: no-transform directive
  • Response isn't already encoded (no existing Content-Encoding header)

Automatic Skipping Scenarios

Compression is skipped for:

  • HEAD requests
  • Responses already with Content-Encoding set
  • Responses below the size threshold
  • Content types deemed non-compressible
  • Responses with Cache-Control: no-transform header
  • Clients not accepting any supported compression algorithms

Headers Modified

The middleware automatically manages these headers:

  • Content-Encoding: Set to the chosen compression algorithm
  • Content-Length: Removed (replaced with chunked transfer encoding)
  • Vary: Set to "Accept-Encoding" for proper caching behavior

Error Handling

The compression middleware follows Express.js conventions:

  • Compatible with standard Express error handling middleware
  • Stream errors are handled internally without crashing the application
  • Respects existing error handling patterns in your application
  • Calls next() to continue to the next middleware

Performance Considerations

  • Memory Usage: Configurable via memLevel and chunkSize options
  • CPU vs Bandwidth Trade-off: Adjustable via level option (0-9)
  • Streaming: Processes data in chunks, suitable for large responses
  • Back-pressure: Automatically handles client connection speed variations
  • Threshold: Avoids compression overhead for small responses

Integration Patterns

Express.js Applications

const express = require('express');
const compression = require('compression');

const app = express();

// Apply compression before other middleware
app.use(compression());
app.use(express.static('public'));
app.use(express.json());

Raw HTTP Server

const http = require('http');
const compression = require('compression')({ threshold: 0 });

const server = http.createServer((req, res) => {
  compression(req, res, (err) => {
    if (err) {
      res.statusCode = err.status || 500;
      res.end(err.message);
      return;
    }
    
    // Your application logic
    res.setHeader('Content-Type', 'text/plain');
    res.end('Hello World!');
  });
});

Connect-compatible Frameworks

The middleware works with any Connect-compatible framework:

const connect = require('connect');
const compression = require('compression');

const app = connect();
app.use(compression());