Open xingbofeng opened 6 years ago
一般情况下Node.js使用zlib模块的使用gzip()压缩,但有一个坏处是,大文件会使V8缓冲区爆掉,原因是由于gzip()使用缓存,而V8的缓存区最大不超过0x3FFFFFFF字节(约为1GB),一般不使用缓存的方式压缩与解压缩数据,而使用Stream,原因可见Coding with Streams:
Node.js
zlib
gzip()
V8
0x3FFFFFFF
Stream
const zlib = require('zlib'); const fs = require('fs'); fs.readFile(__dirname + '/hello.txt', 'utf-8', (readFileErr, readFileData) => { if (readFileErr) { return console.error('readFileErr error:' + readFileErr.message); } zlib.gzip(readFileData, (gzipErr, gzipData) => { if (gzipErr) { return console.error('gzipErr error:' + gzipErr.message); } fs.writeFile(__dirname + '/hello.txt.gz', gzipData, (writeFileErr) => { if (writeFileErr) { return console.error('writeFile error:' + writeFileErr.message); } }); }); });
zlib模块同样支持gzipSync()同步方法进行压缩:
gzipSync()
const zlib = require('zlib'); const fs = require('fs'); let readFileData; try { readFileData = fs.readFileSync(__dirname + '/hello.txt', 'utf-8'); } catch (readFileErr) { console.error('readFileErr error:' + readFileErr.message); } let gzipData; try { gzipData = zlib.gzipSync(readFileData); } catch (gzipErr) { return console.error('gzipErr error:' + gzipErr.message); } try { fs.writeFileSync(__dirname + '/hello.txt.gz', gzipData); } catch (writeFileErr) { return console.error('writeFile error:' + writeFileErr.message); }
Node.js使用zlib模块的createGzip()创建并返回一个带有给定options的新的Gzip对象,通过这种方法,并配合Stream模块可以实现文件压缩,使用流的好处是可以实现大文件压缩,提升空间效率和时间效率:
createGzip()
options
Gzip
const fs = require('fs'); const zlib = require('zlib'); const gzip = zlib.createGzip(); const readableStream = fs.createReadStream('./hello.txt'); const writeableStream = fs.createWriteStream('./hello.txt.gz'); readableStream.pipe(gzip).pipe(writeableStream);
反过来,zlib模块的createGunzip()方法可以实现解压缩:
createGunzip()
const fs = require('fs'); const zlib = require('zlib'); const gunzip = zlib.createGunzip(); const readableStream = fs.createReadStream('./hello.txt.gz'); const writeableStream = fs.createWriteStream('./hello2.txt'); readableStream.pipe(gunzip).pipe(writeableStream);
要实现高性能的http服务,可以使用gzip对返回的静态文件进行压缩,判断HTTP报文头部是否含有accept-encoding首部,并且其值为gzip:
http
gzip
HTTP
accept-encoding
const http = require('http'); const zlib = require('zlib'); const fs = require('fs'); const server = http.createServer((req, res) => { // 如果HTTP报文头部是否含有Accept-Encoding首部,并且其值为gzip if (req.headers['accept-encoding'].indexOf('gzip') !== -1) { // 设定response HTTP报文头部的Content-Encoding首部值为gzip res.writeHead(200, { 'Content-Encoding': 'gzip', }); // 在每次请求到来时创建Gzip const gzip = zlib.createGzip(); return fs.createReadStream(__dirname + '/hello.html').pipe(gzip).pipe(res); } return fs.createReadStream(__dirname + '/hello.html').pipe(res); }); server.listen(80, () => { console.log('server listen in localhost:80') });
要在express中使用,则一般使用compression中间件:
compression
const compression = require('compression'); const express = require('express'); const app = express(); //尽量在其他中间件前使用compression app.use(compression());
一般情况下
Node.js
使用zlib
模块的使用gzip()
压缩,但有一个坏处是,大文件会使V8
缓冲区爆掉,原因是由于gzip()
使用缓存,而V8
的缓存区最大不超过0x3FFFFFFF
字节(约为1GB),一般不使用缓存的方式压缩与解压缩数据,而使用Stream
,原因可见Coding with Streams:zlib
模块同样支持gzipSync()
同步方法进行压缩:Node.js
使用zlib
模块的createGzip()
创建并返回一个带有给定options
的新的Gzip
对象,通过这种方法,并配合Stream
模块可以实现文件压缩,使用流的好处是可以实现大文件压缩,提升空间效率和时间效率:反过来,
zlib
模块的createGunzip()
方法可以实现解压缩:要实现高性能的
http
服务,可以使用gzip
对返回的静态文件进行压缩,判断HTTP
报文头部是否含有accept-encoding
首部,并且其值为gzip
:要在express中使用,则一般使用
compression
中间件: