Nodejs를 사용하여 콘텐츠 압축을 달성하는 방법은 무엇입니까? 다음 글에서는 Node 측에서 컨텐츠 압축(gzip/br/deflate)을 구현하는 방법에 대해 실습을 통해 이야기해보겠습니다.
application로그를 확인할 때 로그 페이지에 들어간 후 로드하는 데 항상 몇 초가 걸린다는 사실을 발견했습니다(인터페이스는 페이지가 매겨져 있지 않았습니다). 그래서 네트워크 패널을 열어
를 확인했습니다.
이제서야 인터페이스에서 반환된 데이터가 압축되지 않은 것을 발견했습니다. 인터페이스가 Nginx 역방향 프록시를 사용하고 Nginx가 자동으로 이 레이어를 수행하는 데 도움이 될 것이라고 생각했습니다. 이론적으로 가능함)
여기 백엔드는 Node Service
이 기사에서는 HTTP 데이터 압축
에 대한 지식과 노드 측
HTTP数据压缩
相关知识以及在Node侧的实践
前置知识
下面的客户端均指浏览器
accept-encoding
客户端在向服务端发起请求时,会在请求头(request header)中添加accept-encoding
字段,其值标明客户端支持的压缩内容编码
格式
content-encoding
服务端在对返回内容执行压缩后,通过在响应头(response header)中添加content-encoding
,来告诉浏览器内容实际压缩使用的编码算法
deflate/gzip/br
deflate
是同时使用了LZ77
算法与哈夫曼编码(Huffman Coding)
的一个无损数据压缩算法。
gzip
是基于 DEFLATE
的算法
br
指代Brotli
,该数据格式旨在进一步提高压缩比,对文本的压缩相对deflate
能增加20%
的压缩密度,而其压缩与解压缩速度则大致不变
zlib模块
Node.js包含一个zlib 模块
,提供了使用 Gzip
、Deflate/Inflate
、以及 Brotli
实现的压缩功能
这里以gzip
为例分场景列举多种使用方式,Deflate/Inflate
与Brotli
使用方式一样,只是API不一样
基于stream
的操作
基于buffer
的操作
引入几个所需的模块
const zlib = require('zlib') const fs = require('fs') const stream = require('stream') const testFile = 'tests/origin.log' const targetFile = `${testFile}.gz` const decodeFile = `${testFile}.un.gz`
文件的解/压缩
解/压缩结果查看,这里使用du
指令直接统计解压缩前后结果
# 执行 du -ah tests # 结果如下 108K tests/origin.log.gz 2.2M tests/origin.log 2.2M tests/origin.log.un.gz 4.6M tests
基于流(stream)
的操作
使用createGzip
与createUnzip
- 注:所有
zlib
API,除了那些显式同步的 API,都使用 Node.js 内部线程池,可以看做是异步的 - 因此下面的示例中的压缩和解压代码应分开执行,否则会报错
方式1: 直接利用实例上的pipe
方法传递流
// 压缩 const readStream = fs.createReadStream(testFile) const writeStream = fs.createWriteStream(targetFile) readStream.pipe(zlib.createGzip()).pipe(writeStream) // 解压 const readStream = fs.createReadStream(targetFile) const writeStream = fs.createWriteStream(decodeFile) readStream.pipe(zlib.createUnzip()).pipe(writeStream)
方式2: 利用stream
上的pipeline
,可在回掉中单独做其它的处理
// 压缩 const readStream = fs.createReadStream(testFile) const writeStream = fs.createWriteStream(targetFile) stream.pipeline(readStream, zlib.createGzip(), writeStream, err => { if (err) { console.error(err); } }) // 解压 const readStream = fs.createReadStream(targetFile) const writeStream = fs.createWriteStream(decodeFile) stream.pipeline(readStream, zlib.createUnzip(), writeStream, err => { if (err) { console.error(err); } })
方式3: Promise化pipeline
方法
const { promisify } = require('util') const pipeline = promisify(stream.pipeline) // 压缩 const readStream = fs.createReadStream(testFile) const writeStream = fs.createWriteStream(targetFile) pipeline(readStream, zlib.createGzip(), writeStream) .catch(err => { console.error(err); }) // 解压 const readStream = fs.createReadStream(targetFile) const writeStream = fs.createWriteStream(decodeFile) pipeline(readStream, zlib.createUnzip(), writeStream) .catch(err => { console.error(err); })
基于Buffer
的操作
利用 gzip
与 unzip
API,这两个方法包含同步
与异步
类型
- 压缩
gzip
gzipSync
- 解压
unzip
unzipSync
方式1: 将readStream
转Buffer
,然后进行进一步操作
- gzip:异步
// 压缩 const buff = [] readStream.on('data', (chunk) => { buff.push(chunk) }) readStream.on('end', () => { zlib.gzip(Buffer.concat(buff), targetFile, (err, resBuff) => { if(err){ console.error(err); process.exit() } fs.writeFileSync(targetFile,resBuff) }) })
- gzipSync:同步
// 压缩 const buff = [] readStream.on('data', (chunk) => { buff.push(chunk) }) readStream.on('end', () => { fs.writeFileSync(targetFile,zlib.gzipSync(Buffer.concat(buff))) })
方式2: 直接通过readFileSync
사전 지식다음 클라이언트는 모두 브라우저를 참조합니다
accept-encoding
다음 클라이언트는 모두 브라우저를 참조합니다
accept-encoding
필드를 추가합니다. 이 필드의 값은 클라이언트의 지원되는 압축 콘텐츠 인코딩
형식을 나타냅니다. 🎜콘텐츠 인코딩
🎜콘텐츠를 추가하여 브라우저 콘텐츠에 <code>실제 압축에 사용되는 인코딩 알고리즘을 응답 헤더에 추가합니다. /code>🎜<h3 id="deflate-gzip-br">deflate/gzip/br</h3>🎜<code>deflate
는 LZ77
알고리즘과 Huffman Coding
은 무손실 데이터 압축 알고리즘입니다. 🎜🎜gzip
은 DEFLATE
를 기반으로 한 알고리즘입니다. 🎜🎜br
은 Brotli
를 의미합니다. 압축 비율을 더욱 향상시키기 위해 텍스트 압축은 deflate
에 비해 압축 밀도를 20%
높일 수 있으며 압축 및 압축 해제 속도는 거의 동일하게 유지됩니다🎜zlib 모듈 🎜🎜Node.js에는 Gzip
, Deflate/Inflate
사용을 제공하는 zlib 모듈
이 포함되어 있습니다. , Brotli에서 구현한 압축 기능
🎜🎜여기에서는 시나리오에 따른 다양한 사용 방법을 나열하기 위해 gzip
을 예로 들어 Deflate/Inflate
및 Brotli
사용법은 같지만 API가 다릅니다🎜🎜스트림
기반 작업🎜🎜
🎜🎜버퍼 기반 작업 코드>
🎜🎜
🎜🎜몇 가지 필수 모듈 소개 🎜// 压缩
const readBuffer = fs.readFileSync(testFile)
const decodeBuffer = zlib.gzipSync(readBuffer)
fs.writeFileSync(targetFile,decodeBuffer)
// 解压
const readBuffer = fs.readFileSync(targetFile)
const decodeBuffer = zlib.gzipSync(decodeFile)
fs.writeFileSync(targetFile,decodeBuffer)
파일 압축 해제/압축🎜🎜압축 해제/압축 결과 보기, 여기에서 du
명령을 사용하여 직접 계산 압축 풀기 전과 후의 결과🎜// 测试数据
const testData = fs.readFileSync(testFile, { encoding: 'utf-8' })
stream
기반 작업🎜createGzip
및 createUnzip 사용
🎜
- 참고: 명시적으로 동기식을 제외한 모든
zlib
API는 Node.js 내부 스레드 풀을 사용하며 비동기식으로 간주될 수 있습니다.
- 그래서 다음 예제의 압축 및 압축 풀기 코드는 별도로 실행되어야 합니다. 그렇지 않으면 오류가 보고됩니다.
🎜방법 1: 파이프
를 직접 사용합니다. > 스트림을 전달하기 위한 인스턴스의 메소드🎜 const buffer = Buffer.from(testData)
🎜방법 2: 스트림
의 파이프라인
을 사용하면 스트림 중에 별도로 다른 처리를 수행할 수 있습니다. Rollback🎜const transformStream = new stream.PassThrough()
transformStream.write(buffer)
// or
const transformStream = new stream.Duplex()
transformStream.push(Buffer.from(testData))
transformStream.push(null)
🎜방법 3 : 파이프라인
메소드 약속🎜transformStream
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream(targetFile))
버퍼
기반 작업🎜 gzip
및 unzip
API를 활용하세요. 이 두 가지 방법에는 동기
및 비동기
유형이 포함됩니다🎜 - 압축
gzip
gzipSync
- 압축 해제
unzip
unzipSync
🎜방법 1 : readStream
을 버퍼
로 지정한 다음 추가 작업을 수행합니다🎜- gzip: 비동기
const buffer = Buffer.from(testData)
- gzipSync: 동기화됨
const result = zlib.gzipSync(buffer)
🎜방법 2: readFileSync
🎜🎜In을 통해 직접 텍스트 콘텐츠의 🎜fs.writeFileSync(targetFile, result)
🎜압축 풀기/압축 읽기 파일 압축 외에도 때로는 전송된 콘텐츠의 압축을 직접 풀기 위해🎜
du
명령을 사용하여 직접 계산 압축 풀기 전과 후의 결과🎜// 测试数据 const testData = fs.readFileSync(testFile, { encoding: 'utf-8' })
stream
기반 작업🎜createGzip
및 createUnzip 사용
🎜- 참고: 명시적으로 동기식을 제외한 모든
zlib
API는 Node.js 내부 스레드 풀을 사용하며 비동기식으로 간주될 수 있습니다. - 그래서 다음 예제의 압축 및 압축 풀기 코드는 별도로 실행되어야 합니다. 그렇지 않으면 오류가 보고됩니다.
파이프
를 직접 사용합니다. > 스트림을 전달하기 위한 인스턴스의 메소드🎜 const buffer = Buffer.from(testData)🎜방법 2:
스트림
의 파이프라인
을 사용하면 스트림 중에 별도로 다른 처리를 수행할 수 있습니다. Rollback🎜const transformStream = new stream.PassThrough() transformStream.write(buffer) // or const transformStream = new stream.Duplex() transformStream.push(Buffer.from(testData)) transformStream.push(null)🎜방법 3 :
파이프라인
메소드 약속🎜transformStream .pipe(zlib.createGzip()) .pipe(fs.createWriteStream(targetFile))
버퍼
기반 작업🎜 gzip
및 unzip
API를 활용하세요. 이 두 가지 방법에는 동기
및 비동기
유형이 포함됩니다🎜 - 압축
gzip
gzipSync
- 압축 해제
unzip
unzipSync
🎜방법 1 : readStream
을 버퍼
로 지정한 다음 추가 작업을 수행합니다🎜- gzip: 비동기
const buffer = Buffer.from(testData)
- gzipSync: 동기화됨
const result = zlib.gzipSync(buffer)
🎜방법 2: readFileSync
🎜🎜In을 통해 직접 텍스트 콘텐츠의 🎜fs.writeFileSync(targetFile, result)
🎜압축 풀기/압축 읽기 파일 압축 외에도 때로는 전송된 콘텐츠의 압축을 직접 풀기 위해🎜
gzip
gzipSync
unzip
unzipSync
这里以压缩文本内容为例
// 测试数据 const testData = fs.readFileSync(testFile, { encoding: 'utf-8' })
基于流(stream)
操作
这块就考虑 string
=> buffer
=> stream
的转换就行
string
=> buffer
const buffer = Buffer.from(testData)
buffer
=> stream
const transformStream = new stream.PassThrough() transformStream.write(buffer) // or const transformStream = new stream.Duplex() transformStream.push(Buffer.from(testData)) transformStream.push(null)
这里以写入到文件示例,当然也可以写到其它的流里,如HTTP的Response
(后面会单独介绍)
transformStream .pipe(zlib.createGzip()) .pipe(fs.createWriteStream(targetFile))
基于Buffer
操作
同样利用Buffer.from
将字符串转buffer
const buffer = Buffer.from(testData)
然后直接使用同步API进行转换,这里result就是压缩后的内容
const result = zlib.gzipSync(buffer)
可以写入文件,在HTTP Server
中也可直接对压缩后的内容进行返回
fs.writeFileSync(targetFile, result)
Node Server中的实践
这里直接使用Node中 http
模块创建一个简单的 Server 进行演示
在其他的 Node Web
框架中,处理思路类似,当然一般也有现成的插件,一键接入
const http = require('http') const { PassThrough, pipeline } = require('stream') const zlib = require('zlib') // 测试数据 const testTxt = '测试数据123'.repeat(1000) const app = http.createServer((req, res) => { const { url } = req // 读取支持的压缩算法 const acceptEncoding = req.headers['accept-encoding'].match(/(br|deflate|gzip)/g) // 默认响应的数据类型 res.setHeader('Content-Type', 'application/json; charset=utf-8') // 几个示例的路由 const routes = [ ['/gzip', () => { if (acceptEncoding.includes('gzip')) { res.setHeader('content-encoding', 'gzip') // 使用同步API直接压缩文本内容 res.end(zlib.gzipSync(Buffer.from(testTxt))) return } res.end(testTxt) }], ['/deflate', () => { if (acceptEncoding.includes('deflate')) { res.setHeader('content-encoding', 'deflate') // 基于流的单次操作 const originStream = new PassThrough() originStream.write(Buffer.from(testTxt)) originStream.pipe(zlib.createDeflate()).pipe(res) originStream.end() return } res.end(testTxt) }], ['/br', () => { if (acceptEncoding.includes('br')) { res.setHeader('content-encoding', 'br') res.setHeader('Content-Type', 'text/html; charset=utf-8') // 基于流的多次写操作 const originStream = new PassThrough() pipeline(originStream, zlib.createBrotliCompress(), res, (err) => { if (err) { console.error(err); } }) originStream.write(Buffer.from('<h1 id="BrotliCompress">BrotliCompress</h1>')) originStream.write(Buffer.from('<h2 id="测试数据">测试数据</h2>')) originStream.write(Buffer.from(testTxt)) originStream.end() return } res.end(testTxt) }] ] const route = routes.find(v => url.startsWith(v[0])) if (route) { route[1]() return } // 兜底 res.setHeader('Content-Type', 'text/html; charset=utf-8') res.end(`<h1 id="nbsp-url">404: ${url}</h1> <h2 id="已注册路由">已注册路由</h2> <ul> ${routes.map(r => `<li><a href="${r[0]}">${r[0]}</a></li>`).join('')} </ul> `) res.end() }) app.listen(3000)
更多node相关知识,请访问:nodejs 教程!
위 내용은 실습을 통해 Node를 사용하여 콘텐츠 압축을 달성하는 방법에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

각각의 엔진의 구현 원리 및 최적화 전략이 다르기 때문에 JavaScript 엔진은 JavaScript 코드를 구문 분석하고 실행할 때 다른 영향을 미칩니다. 1. 어휘 분석 : 소스 코드를 어휘 단위로 변환합니다. 2. 문법 분석 : 추상 구문 트리를 생성합니다. 3. 최적화 및 컴파일 : JIT 컴파일러를 통해 기계 코드를 생성합니다. 4. 실행 : 기계 코드를 실행하십시오. V8 엔진은 즉각적인 컴파일 및 숨겨진 클래스를 통해 최적화하여 Spidermonkey는 유형 추론 시스템을 사용하여 동일한 코드에서 성능이 다른 성능을 제공합니다.

실제 세계에서 JavaScript의 응용 프로그램에는 서버 측 프로그래밍, 모바일 애플리케이션 개발 및 사물 인터넷 제어가 포함됩니다. 1. 서버 측 프로그래밍은 Node.js를 통해 실현되며 동시 요청 처리에 적합합니다. 2. 모바일 애플리케이션 개발은 재교육을 통해 수행되며 크로스 플랫폼 배포를 지원합니다. 3. Johnny-Five 라이브러리를 통한 IoT 장치 제어에 사용되며 하드웨어 상호 작용에 적합합니다.

일상적인 기술 도구를 사용하여 기능적 다중 테넌트 SaaS 응용 프로그램 (Edtech 앱)을 구축했으며 동일한 작업을 수행 할 수 있습니다. 먼저, 다중 테넌트 SaaS 응용 프로그램은 무엇입니까? 멀티 테넌트 SAAS 응용 프로그램은 노래에서 여러 고객에게 서비스를 제공 할 수 있습니다.

이 기사에서는 Contrim에 의해 확보 된 백엔드와의 프론트 엔드 통합을 보여 주며 Next.js를 사용하여 기능적인 Edtech SaaS 응용 프로그램을 구축합니다. Frontend는 UI 가시성을 제어하기 위해 사용자 권한을 가져오고 API가 역할 기반을 준수하도록합니다.

JavaScript는 현대 웹 개발의 핵심 언어이며 다양성과 유연성에 널리 사용됩니다. 1) 프론트 엔드 개발 : DOM 운영 및 최신 프레임 워크 (예 : React, Vue.js, Angular)를 통해 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축합니다. 2) 서버 측 개발 : Node.js는 비 차단 I/O 모델을 사용하여 높은 동시성 및 실시간 응용 프로그램을 처리합니다. 3) 모바일 및 데스크탑 애플리케이션 개발 : 크로스 플랫폼 개발은 개발 효율을 향상시키기 위해 반응 및 전자를 통해 실현됩니다.

JavaScript의 최신 트렌드에는 Typescript의 Rise, 현대 프레임 워크 및 라이브러리의 인기 및 WebAssembly의 적용이 포함됩니다. 향후 전망은보다 강력한 유형 시스템, 서버 측 JavaScript 개발, 인공 지능 및 기계 학습의 확장, IoT 및 Edge 컴퓨팅의 잠재력을 포함합니다.

JavaScript는 현대 웹 개발의 초석이며 주요 기능에는 이벤트 중심 프로그래밍, 동적 컨텐츠 생성 및 비동기 프로그래밍이 포함됩니다. 1) 이벤트 중심 프로그래밍을 사용하면 사용자 작업에 따라 웹 페이지가 동적으로 변경 될 수 있습니다. 2) 동적 컨텐츠 생성을 사용하면 조건에 따라 페이지 컨텐츠를 조정할 수 있습니다. 3) 비동기 프로그래밍은 사용자 인터페이스가 차단되지 않도록합니다. JavaScript는 웹 상호 작용, 단일 페이지 응용 프로그램 및 서버 측 개발에 널리 사용되며 사용자 경험 및 크로스 플랫폼 개발의 유연성을 크게 향상시킵니다.

Python은 데이터 과학 및 기계 학습에 더 적합한 반면 JavaScript는 프론트 엔드 및 풀 스택 개발에 더 적합합니다. 1. Python은 간결한 구문 및 풍부한 라이브러리 생태계로 유명하며 데이터 분석 및 웹 개발에 적합합니다. 2. JavaScript는 프론트 엔드 개발의 핵심입니다. Node.js는 서버 측 프로그래밍을 지원하며 풀 스택 개발에 적합합니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기

Eclipse용 SAP NetWeaver 서버 어댑터
Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

PhpStorm 맥 버전
최신(2018.2.1) 전문 PHP 통합 개발 도구

드림위버 CS6
시각적 웹 개발 도구

mPDF
mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.
