Middleware compression

Middleware de compresión para Node.js.

Las siguientes codificaciones de compresión están soportadas:

  • deflate
  • gzip
  • br (brotli)

Nota Brotli está soportado solo desde las versiones de Node.js v11.7.0 y v10.16.0.

Instalar

Este es un módulo de Node.js disponible a través del registro npm. La instalación se hace usando el comando npm install:

Ventana de terminal
npm install compression

API

var compression = require('compression');

compression([options])

Devuelve el middleware de compresión usando las options dadas. El middleware intentará comprimir los cuerpos de respuesta para todas las peticiones que pasen a través del middleware, basándose en las options dadas.

Este middleware nunca comprimirá respuestas que incluyan una cabecera Cache-Control con la directiva no-transform, ya que comprimir transformaría el cuerpo.

Opciones

compression() acepta estas propiedades en el objeto options. Además de las listadas abajo, se pueden pasar opciones de zlib al objeto options u opciones de brotli.

chunkSize

Tipo: Number
Por defecto: zlib.constants.Z_DEFAULT_CHUNK, o 16384.

Consulta la documentación de Node.js respecto a su uso.

filter

Tipo: Function

Una función para decidir si la respuesta debe ser considerada para compresión. Esta función se llama como filter(req, res) y se espera que devuelva true para considerar la respuesta para compresión, o false para no comprimir la respuesta.

La función de filtro por defecto usa el módulo compressible para determinar si res.getHeader('Content-Type') es comprimible.

level

Tipo: Number
Por defecto: zlib.constants.Z_DEFAULT_COMPRESSION, o -1

El nivel de compresión zlib a aplicar a las respuestas. Un nivel más alto resultará en mejor compresión, pero tardará más en completarse. Un nivel más bajo resultará en menos compresión, pero será mucho más rápido.

Este es un entero en el rango de 0 (sin compresión) a 9 (compresión máxima). El valor especial -1 se puede usar para significar “nivel de compresión por defecto”, que es una compensación por defecto entre velocidad y compresión (actualmente equivalente al nivel 6).

  • -1 Nivel de compresión por defecto (también zlib.constants.Z_DEFAULT_COMPRESSION).
  • 0 Sin compresión (también zlib.constants.Z_NO_COMPRESSION).
  • 1 Compresión más rápida (también zlib.constants.Z_BEST_SPEED).
  • 2
  • 3
  • 4
  • 5
  • 6 (actualmente a lo que apunta zlib.constants.Z_DEFAULT_COMPRESSION).
  • 7
  • 8
  • 9 Mejor compresión (también zlib.constants.Z_BEST_COMPRESSION).

Nota en la lista anterior, zlib es de zlib = require('zlib').

memLevel

Tipo: Number
Por defecto: zlib.constants.Z_DEFAULT_MEMLEVEL, o 8

Esto especifica cuánta memoria se debe asignar para el estado interno de compresión y es un entero en el rango de 1 (nivel mínimo) y 9 (nivel máximo).

Consulta la documentación de Node.js respecto a su uso.

brotli

Tipo: Object

Esto especifica las opciones para configurar Brotli. Consulta la documentación de Node.js para una lista completa de las opciones disponibles.

strategy

Tipo: Number
Por defecto: zlib.constants.Z_DEFAULT_STRATEGY

Esto se usa para ajustar el algoritmo de compresión. Este valor solo afecta la relación de compresión, no la corrección de la salida comprimida, incluso si no se establece apropiadamente.

  • zlib.constants.Z_DEFAULT_STRATEGY Usar para datos normales.
  • zlib.constants.Z_FILTERED Usar para datos producidos por un filtro (o predictor). Los datos filtrados consisten principalmente en valores pequeños con una distribución algo aleatoria. En este caso, el algoritmo de compresión se ajusta para comprimirlos mejor. El efecto es forzar más codificación Huffman y menos coincidencia de cadenas; es algo intermedio entre zlib.constants.Z_DEFAULT_STRATEGY y zlib.constants.Z_HUFFMAN_ONLY.
  • zlib.constants.Z_FIXED Usar para prevenir el uso de códigos Huffman dinámicos, permitiendo un decodificador más simple para aplicaciones especiales.
  • zlib.constants.Z_HUFFMAN_ONLY Usar para forzar solo codificación Huffman (sin coincidencia de cadenas).
  • zlib.constants.Z_RLE Usar para limitar las distancias de coincidencia a una (codificación run-length). Esto está diseñado para ser casi tan rápido como zlib.constants.Z_HUFFMAN_ONLY, pero dar mejor compresión para datos de imágenes PNG.

Nota en la lista anterior, zlib es de zlib = require('zlib').

threshold

Tipo: Number o String
Por defecto: 1kb

El umbral de bytes para el tamaño del cuerpo de respuesta antes de que se considere la compresión para la respuesta. Este es un número de bytes o cualquier cadena aceptada por el módulo bytes.

Nota esto es solo un ajuste orientativo; si el tamaño de la respuesta no se puede determinar en el momento en que se escriben las cabeceras de respuesta, entonces se asume que la respuesta está por encima del umbral. Para garantizar que el tamaño de la respuesta se pueda determinar, asegúrate de establecer una cabecera de respuesta Content-Length.

windowBits

Tipo: Number
Por defecto: zlib.constants.Z_DEFAULT_WINDOWBITS, o 15

Consulta la documentación de Node.js respecto a su uso.

enforceEncoding

Tipo: String
Por defecto: identity

Esta es la codificación por defecto a usar cuando el cliente no especifica una codificación en la cabecera Accept-Encoding de la petición.

.filter

La función filter por defecto. Esto se usa para construir una función de filtro personalizada que es una extensión de la función por defecto.

var compression = require('compression');
var express = require('express');
var app = express();
app.use(compression({ filter: shouldCompress }));
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);
}

res.flush

Este módulo añade un método res.flush() para forzar que la respuesta parcialmente comprimida sea enviada al cliente.

Ejemplos

express

Cuando se usa este módulo con express, simplemente haz app.use del módulo tan alto como quieras. Las peticiones que pasen a través del middleware serán comprimidas.

var compression = require('compression');
var express = require('express');
var app = express();
// compress all responses
app.use(compression());
// add all routes

Servidor HTTP de Node.js

var compression = require('compression')({ threshold: 0 });
var http = require('http');
function createServer(fn) {
return http.createServer(function (req, res) {
compression(req, res, function (err) {
if (err) {
res.statusCode = err.status || 500;
res.end(err.message);
return;
}
fn(req, res);
});
});
}
var server = createServer(function (req, res) {
res.setHeader('Content-Type', 'text/plain');
res.end('hello world!');
});
server.listen(3000, () => {
console.log('> Listening at http://localhost:3000');
});

Server-Sent Events

Debido a la naturaleza de la compresión, este módulo no funciona tal cual con server-sent events. Para comprimir contenido, se necesita almacenar una ventana de la salida en búfer para obtener una buena compresión. Típicamente cuando se usan server-sent events, hay ciertos bloques de datos que necesitan llegar al cliente.

Puedes lograr esto llamando a res.flush() cuando necesites que los datos escritos lleguen realmente al cliente.

var compression = require('compression');
var express = require('express');
var app = express();
// compress responses
app.use(compression());
// server-sent event stream
app.get('/events', function (req, res) {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
// send a ping approx every 2 seconds
var timer = setInterval(function () {
res.write('data: ping\n\n');
// !!! this is the important part
res.flush();
}, 2000);
res.on('close', function () {
clearInterval(timer);
});
});

Contribuir

El proyecto Express.js da la bienvenida a todas las contribuciones constructivas. Las contribuciones toman muchas formas, desde código para correcciones de errores y mejoras, hasta adiciones y correcciones a la documentación, tests adicionales, clasificación de pull requests y issues entrantes, ¡y más!

Consulta la Guía de Contribución para más detalles técnicos sobre cómo contribuir.

Licencia

MIT