热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用node.js压缩流优化http请求

前端性能优化一直是一个值得讨论的话题,而节省每次HTTP请求的流量,则是优化的一个重要的点,比如javascript文件、图片、样式表等进

前端性能优化一直是一个值得讨论的话题,而节省每次HTTP请求的流量,则是优化的一个重要的点,比如Javascript文件、图片、样式表等进行压缩传输,不仅使访问速度更快,也可以有效的节省站点的流量。

HTTP的请求中带有一个头Content-Encoding来处理压缩。

常见的压缩模式:

  • GZIP
  • Deflate

GZIP

GZIP最早由Jean-loup Gailly和Mark Adler创建,用于UNⅨ系统的文件压缩。我们在Linux中经常会用到后缀为.gz的文件,它们就是GZIP格式的。现今已经成为Internet 上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

Deflate

DEFLATE是同时使用了LZ77算法与哈夫曼编码(Huffman Coding)的一个无损数据压缩算法。 它最初是由Phil Katz为他的PKZIP归档工具第二版所定义的,后来定义在RFC 1951规范中。

在node.js中使用压缩流

node.js中已经为我们提供了压缩的功能,它的核心功能在zlib包里。

zlib模块提供通过 Gzip 和 Deflate/Inflate 实现的压缩功能。

使用方法

const zlib = require('zlib');
const fs = require('fs');
const path = require('path');let file = path.join(__dirname, './1.txt');
zip(file);function zip(file) {let gzip = zlib.createGzip(); //gzip是一个转换流fs.createReadStream(file).pipe(gzip).pipe(fs.createWriteStream(file + '.gz'));
}

可以看到用法非常简单,使用createGzip可以创建一个gzip压缩流,它是一个Transform转换流。首先使用待压缩的目标文件创建一个可读流,将它pipe到gzip压缩流中,再pipe到一个可写流中,即可完成压缩。运行这段代码可以看到在模块目录下已经多了一个1.txt.gz的压缩包。

unzip(path.join(__dirname, './1.txt.gz'));
function unzip(file) {let gunzip = zlib.createGunzip(file);fs.createReadStream(file).pipe(gunzip).pipe(fs.createWriteStream(path.basename(file, '.gz')));
}

解压缩同样如此,使用解压缩流即可。

使用压缩优化http请求

了解了压缩流的使用,怎么样才能配合http来优化用户的请求呢?

http有一个字段,它描述了浏览器支持哪种压缩格式:

Accept-Encoding: gzip, deflate, br

响应头

Content-Encoding: gzip

处理流程:

  1. 首先查看http请求头Accept-Encoding都支持哪些压缩格式
  2. 根据不同的压缩格式将资源压缩并输出到浏览器
  3. 对不同的压缩格式发送响应头Content-Encoding

实例代码:

const http = require('http');
const url = require('url');
const path = require('path');
const fs = require('fs');
const zlib = require('zlib');let server = http.createServer((req, res) => {let {pathname} = url.parse(req.url, true);if (pathname === '/') {res.end('请访问一个服务器上的文件 如http://localhost:3000/1.txt');}let file = path.join(__dirname, pathname);fs.stat(file, (err, stat) => {if (err) {res.end('访问的文件不存在');} else {let acceptEncoding = req.headers['accept-encoding']; //取得浏览器的accept-encoding头,询问支持哪种压缩if (acceptEncoding.match(/\bgzip\b/)) { //浏览器支持gzip格式res.setHeader('Content-Encoding', 'gzip'); //告知浏览器发送的数据是gzip压缩格式let gzip = zlib.createGzip();fs.createReadStream(file).pipe(gzip).pipe(res); //压缩后输出} else if (acceptEncoding.match(/\bdeflate\b/)) { //浏览器支持deflate格式let deflate = zlib.createDeflate();res.setHeader('Content-Encoding','deflate');fs.createReadStream(file).pipe(deflate).pipe(res); 压缩后输出} else {fs.createReadStream(file).pipe(res);}}});
});server.listen(3000, () => {console.log('服务器已启动在3000端口...')
});

重要代码说明:

let acceptEncoding = req.headers['accept-encoding'];

取得浏览器的请求头,查看支持哪些压缩格式,因为某些老旧浏览器是不支持压缩的,因此要针对不同的压缩格式分别处理。

if (acceptEncoding.match(/\bgzip\b/)) {

使用正则来进行判断,看看是否支持gzip压缩

res.setHeader('Content-Encoding', 'gzip'); //告知浏览器发送的数据是gzip压缩格式

使用setHeader来设置响应头,告知浏览器此数据是经gzip压缩的,这样浏览器才会正确处理,否则浏览器并不识别gzip数据。

deflate格式的逻辑完全一样,这样就可以做到http压缩以节省流量的目的。



推荐阅读
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • PHP中的单例模式与静态变量的区别及使用方法
    本文介绍了PHP中的单例模式与静态变量的区别及使用方法。在PHP中,静态变量的存活周期仅仅是每次PHP的会话周期,与Java、C++不同。静态变量在PHP中的作用域仅限于当前文件内,在函数或类中可以传递变量。本文还通过示例代码解释了静态变量在函数和类中的使用方法,并说明了静态变量的生命周期与结构体的生命周期相关联。同时,本文还介绍了静态变量在类中的使用方法,并通过示例代码展示了如何在类中使用静态变量。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
author-avatar
暗恋具体哦
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有