注: 文章摘自 juan26 - 思否
压缩方式
前端压缩的方式很多, 依赖 java 的有 ant 工具, 前端自己打包压缩的有 grunt,gulp,webpack, 这些压缩也很重要, 基本上能压缩 50% 以上, 下面我们对压缩文件来个对比, 如图所示
这是未压缩的
这是压缩后的
开启 gzip 后能在压缩的基础上再进行压缩 50% 以上
压缩原理
是不是每个浏览器都支持 gzip 呢? 如何知道客户端是否支持 gzip 呢?
请求头中有个 Accept-Encoding 来标识对压缩的支持. 客户端 http 请求头声明浏览器支持的压缩方式, 服务端配置启用压缩, 压缩的文件类型, 压缩方式. 当客户端请求到服务端的时候, 服务器解析请求头, 如果客户端支持 gzip 压缩, 响应时对请求的资源进行压缩并返回给客户端, 浏览器按照自己的方式解析, 在 http 响应头, 我们可以看到
Content-Encoding: gzip
, 这是指服务端使用了 gzip 的压缩方式
那么怎么看有没有用 gzip 压缩的文件呢?
打开 f12, 查看 network, 按照下面的方式过滤, content-encoding 是 gzip 的话就说明返回的是 gzip
启用方式
前面说过了, 启用 gzip 需要客户端和服务端的支持, 如果客户端支持 gzip 的解析, 那么只要服务端能够返回 gzip 的文件就可以启用 gzip 了, 现在来说一下几种不同的环境下的服务端如何配置
node
node 端很简单, 只要加上 compress 模块即可, 代码如下
- var compression = require('compression')
- var App = express();
- // 尽量在其他中间件前使用 compression
- App.use(compression());
这是基本用法, 如果还要对请求进行过滤的话, 还要加上
- App.use(compression({filter: shouldCompress}))
- function shouldCompress (req, res) {
- if (req.headers['x-no-compression']) {
- // 这里就过滤掉了请求头包含'x-no-compression'
- return false
- }
- return compression.filter(req, res)
- }
如果用的是 koa, 用法和上面的差不多
- const compress = require('koa-compress');
- const App = module.exports = new Koa();
- App.use(compress());
因为 node 读取的是生成目录中的文件, 所以要先用 webpack 等其他工具进行压缩成 gzip,webpack 的配置如下
plugins 是 webpack 的插件
- const CompressionWebpackPlugin = require('compression-webpack-plugin');
- plugins.push(
- new CompressionWebpackPlugin({
- asset: '[path].gz[query]', // 目标文件名
- algorithm: 'gzip', // 使用 gzip 压缩
- test: new RegExp(
- '\\.(js|CSS)$' // 压缩 JS 与 CSS
- ),
- threshold: 10240, // 资源文件大于 10240B = 10kB 时会被压缩
- minRatio: 0.8 // 最小压缩比达到 0.8 时才会被压缩
- })
- );
- tomcat
找到 tomcat 的 server.xml 文件, 找到其中 Connector 节点然后进行配置修改, 具体配置如下
<Connectorport="80"protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" maxPostSize="0" useBodyEncodingForURI="true"compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,application/javascript,text/css,text/plain,image/jpeg,application/json"/>
参数说明:
compression="on" 打开压缩功能
compressionMinSize="2048"
启用压缩的输出内容大小, 当被压缩对象的大小 >= 该值时才会被压缩, 这里面默认为 2KB
noCompressionUserAgents="gozilla, traviata"
对于以下的浏览器, 不启用压缩
compressableMimeType="text/html, text/xml, text/javascript, text/css, text/plain"
压缩类型
注意: tomcat7 以后, JS 文件的 mimetype 类型变为了 application/JavaScript, 而在 tomcat7 以下则为 text/JavaScript; 具体的 tomcat7 定义的类型可以在 conf/Web.xml 文件中找到
可以在 Web.xml 下搜索, 如我搜索 JavaScript 会找到如下代码
- <mime-mapping>
- <extension>JS</extension>
- <mime-type>application/JavaScript</mime-type>
- </mime-mapping>
切记上面的类型不能配置错了, 如果配置错了压缩是不会起作用的
nginx
gzip 使用环境: http, server, location, if(x), 一般把它定义在 nginx.conf 的 http{.....} 之间
gzip on
on 为启用, off 为关闭
gzip_min_length 1k
设置允许压缩的页面最小字节数, 页面字节数从 header 头中的 Content-Length 中进行获取. 默认值是 0, 不管页面多大都压缩. 建议设置成大于 1k 的字节数, 小于 1k 可能会越压越大.
gzip_buffers 4 16k
获取多少内存用于缓存压缩结果,'4 16k'表示以 16k*4 为单位获得
gzip_comp_level 5
gzip 压缩比 (1~9), 越小压缩效果越差, 但是越大处理越慢, 所以一般取中间值;
gzip_types text/plain application/x-JavaScript text/CSS application/xml text/JavaScript application/x-httpd-PHP
对特定的 MIME 类型生效, 其中'text/html'被系统强制启用
gzip_http_version 1.1
识别 http 协议的版本, 早起浏览器可能不支持 gzip 自解压, 用户会看到乱码
gzip_vary on
启用应答头 "Vary: Accept-Encoding"
gzip_proxied off
nginx 做为反向代理时启用, off(关闭所有代理结果的数据的压缩),expired(启用压缩, 如果 header 头中包括 "Expires" 头信息),no-cache(启用压缩, header 头中包含 "Cache-Control:no-cache"),no-store(启用压缩, header 头中包含 "Cache-Control:no-store"),private(启用压缩, header 头中包含 "Cache-Control:private"),no_last_modefied(启用压缩, header 头中不包含 "Last-Modified"),no_etag(启用压缩, 如果 header 头中不包含 "Etag" 头信息),auth(启用压缩, 如果 header 头中包含 "Authorization" 头信息)
gzip_disable msie6
(IE5.5 和 IE6 SP1 使用 msie6 参数来禁止 gzip 压缩 ) 指定哪些不需要 gzip 压缩的浏览器 (将和 User-Agents 进行匹配), 依赖于 PCRE 库
以上代码可以插入到 http {...} 整个服务器的配置里, 也可以插入到虚拟主机的 server {...} 或者下面的 location 模块内
来源: http://www.jianshu.com/p/a0a399a04be2