本文,帮助了解响应压缩的一些知识及用法(大部分翻译于官网,英文水平有限,不准确之处,欢迎指正)。

什么是响应压缩?响应压缩简单的说就是为了减少网络带宽,而把返回的响应压缩,使之体积缩小,从而加快响应的一种技术(个人理解)

网络带宽是有限的资源。减少响应(response)的大小通常可以增加应用的响应性(即减少响应的大小可以加快响应的速度),这是很引人注目的(often
dramatically).压缩(压缩compress)应用的响应可以减少装载的大小。

当使用响应压缩中间件时(Response Compression Middleware)

在IIS,Apache,Nginx中使用基于服务端的响应压缩技术。中间件的执行可能和服务端模块不匹配。HTTP.sys 和Kestrel server
目前没有提供内置的压缩支持。

什么时候使用Response Compression Middleware:

* 不能使用下面的服务端压缩技术时:
* IIS Dynamic Compression module (IIS 动态压缩模块)
* Apache mod_deflate module (deflate:紧缩 )
* Nginx Compression and Decompression
* 部署运行在:
* HTTP.sys server
* Kestrel server
响应压缩(Response compression)

通常,任何不能自动压缩的响应都可以从响应压缩中获益。典型的不能自动压缩的响应包括:CSS, JavaScript, HTML, XML, 和JSON.
你不应该压缩自动压缩的文件,例如 PNG文件。如果你尝试更进一步压缩一个自动压缩的响应,那么任何小的额外的缩小和传送时间都将会显得黯然失色,等到它处理压缩,
不要压缩小于150-1000bytes文件(取决于文件的内容和压缩的效率)。 压缩小文件开销可以产生大于未压缩文件的压缩文件。

当客户端可以处理压缩内容时,客户端必须通过发送请求头上的Accept-Encoding 通知服务器它的能力。当服务器发送压缩内容时,它必须在
Content-Encoding头中包含压缩的响应是怎么编码的内容。内容编码的指定是通过下表中展示的中间件支持的。



中间件允许你为自定义的Accept-Encoding
的头上的值增加额外的压缩提供者,中间件对于质量值的反应是很熟练的,质量值是被客户端发送的用来衡量优先处理压缩协议的。

压缩算法是受支配于压缩速度和压缩效率的一种平衡交易。效率关系到压缩之后的大小,最优压缩压缩出来的就是最小的。

涉及到请求,发送,缓存,接收压缩内容的头部在下表中有描述

 

利用sample app
<https://github.com/aspnet/AspNetCore.Docs/tree/master/aspnetcore/performance/response-compression/samples>
 探索响应压缩的功能。这个例子表明:

*  应用的利用Gzip和自定义压缩提供者的压缩
* 怎样增加MIME类型到默认的压缩的MIME类型的列表
Package

为了在项目中包含这个中间件,增加一个到 Microsoft.AspNetCore.App metapackage
<https://docs.microsoft.com/en-us/aspnet/core/fundamentals/metapackage-app?view=aspnetcore-2.2>
, 的引用,它包含 Microsoft.AspNetCore.ResponseCompression
<https://www.nuget.org/packages/Microsoft.AspNetCore.ResponseCompression/> 包 

Configuration

下面的代码展示了怎样允许Response Compression Middleware , 对于默认的MIME类型和压缩提供者(Brotli 和 Gzip):
public class Startup { public void ConfigureServices(IServiceCollection
services) { services.AddResponseCompression(); }public void
Configure(IApplicationBuilder app, IHostingEnvironment env) {
app.UseResponseCompression(); } }
注意:

*
App.UseResponseCompression 必须在app.UseMvc之前被调用

*
用一个工具(例如Fiddler, Filrebug, Postman)来设置Accept-Encoding 请求头,并且研究响应头,大小和body

提交一个不携带Acccept-Encoding 头的请求到示例应用,并且观察到响应是未压缩的。Content-Encoding 和 Vary
头没有在响应中呈现。

 

提交一个带Accept-Encoding: br头的请求到示例应用。(Brotli compress)并且观察响应是压缩的。Content-Encoding
和Vary 在响应中呈现了。



Providers(提供者)

Brotli Compression Provider

使用BrotliCompressionProvider来压缩响应,使用Brotli compressed data format ( brotli
compress 数据格式),

如果没有compression providers(压缩提供者)被明确的加到 CompressionProviderCollection中:

* Brotli Compression Provider 默认被加到compression providers的数组中,和Gzip
compression provider.
* 当客户端支持Brotli compressed data format (Brotli 压缩数据格式)时,默认使用Brotli compression
压缩. 如果客户端不支持Brotli , 但是客户端支持Gzip 压缩时,会默认使用Gzip public void
ConfigureServices(IServiceCollection services) {
services.AddResponseCompression(); }
Brotoli Compression Provider必须被添加,当任意compression provider 明确的被添加时。
public void ConfigureServices(IServiceCollection services) {
services.AddResponseCompression(options=> { options.Providers.Add
<BrotliCompressionProvider>(); options.Providers.Add<GzipCompressionProvider>
(); options.Providers.Add<CustomCompressionProvider>(); options.MimeTypes =
ResponseCompressionDefaults.MimeTypes.Concat(new[] { "image/svg+xml" }); }); }
使用BrotliCompressionProviderOptions设置压缩级别。Brotli Compression Provider
默认使用的是最快的压缩级别( CompressionLevel.Fastest ),
这种级别可能不会产生最有效率的压缩。如果最有效率的压缩被需要时,可以为最佳的压缩配置中间件


public void ConfigureServices(IServiceCollection services) {
services.AddResponseCompression(); services.Configure
<BrotliCompressionProviderOptions>(options => { options.Level =
CompressionLevel.Fastest; }); }
Gzip Compression Provider

使用GzipCompressionProvider来压缩响应,用Gzip file format.(用Gzip 文件格式)

如果没有compression provider被明确的加入到CompressionProviderCollection中:

* Gzip Compression Provider默认被添加到 压缩提供者数组中,并且还有Brotli Compression Provider.
* 当客户端支持Brotli compressed data format (Brotli 压缩数据格式)时,默认使用Brotli compression
压缩. 如果客户端不支持Brotli , 但是客户端支持Gzip 压缩时,会默认使用Gzip  public void
ConfigureServices(IServiceCollection services) {
services.AddResponseCompression(); }
Gzip Compression Provider 必须被添加,当任意压缩提供者被明确的添加时:
public void ConfigureServices(IServiceCollection services) {
services.AddResponseCompression(options=> { options.Providers.Add
<BrotliCompressionProvider>(); options.Providers.Add<GzipCompressionProvider>
(); options.Providers.Add<CustomCompressionProvider>(); options.MimeTypes =
ResponseCompressionDefaults.MimeTypes.Concat(new[] { "image/svg+xml" }); }); }
使用GzipCompressionProviderOptions设置压缩级别。Gzip Compression Provider默认使用的是最快的压缩级别(
CompressionLevel.Fastest ),这种级别可能不会产生最有效率的压缩。如果最有效率的压缩被需要时,可以为最佳的压缩配置中间件


public void ConfigureServices(IServiceCollection services) {
services.AddResponseCompression(); services.Configure
<GzipCompressionProviderOptions>(options => { options.Level =
CompressionLevel.Fastest; }); }
Custom providers

通过实现ICompressionProvider接口创建自定义的压缩。EncodingName代表ICompressionProvider生成的内容编码
(the content encoding).中间件使用这个信息来选择provider,在请求的Accept-Encoding 头上的列表的基础上。

在示例项目上,客户端提交请求,带有Accept-Encoding: mycustomcompression头。中间件使用自定义的压缩实现并且返回带有
Content-Encoding:mycustomcompression头的响应。客户端必须可以按顺序的解压自定义的编码( the custom
encoding),对于一个自定义的压缩实现的工作。
public void ConfigureServices(IServiceCollection services) {
services.AddResponseCompression(options=> { options.Providers.Add
<BrotliCompressionProvider>(); options.Providers.Add<GzipCompressionProvider>();
options.Providers.Add<CustomCompressionProvider>(); options.MimeTypes =
ResponseCompressionDefaults.MimeTypes.Concat(new[] { "image/svg+xml" }); }); }
public class CustomCompressionProvider : ICompressionProvider { public string
EncodingName =>"mycustomcompression"; public bool SupportsFlush => true; public
Stream CreateStream(Stream outputStream) {// Create a custom compression stream
wrapper here return outputStream; } }
提交一个带Accept-Encodign:mycustomcompression头的请求到示例应用,并且观察响应头。响应中呈现出了Vary 和
Content-Encoding头。The response body 没有被压缩在项目中。在示例项目的CustomCompressionProvider
类中没有一个压缩实现。示例展示了你在哪里实现这样一个压缩算法。



MIME types

这个中间件指定一个默认的用于压缩的MIME types:

* application/javascript
* application/json
* application/xml
* text/css
* text/html
* text/json
* text/plain
* text/xml
在Response Compression Middleware options上替换或者增加MIME types. 注意,带有通配符的MIME types,
例如text/* 是不支持的。 示例应用中增加了一个MIME type 为 image/svg+xml 并且压缩并且作用于ASP.NET Core的
banner image ( banner,svg ).
public void ConfigureServices(IServiceCollection services) {
services.AddResponseCompression(options=> { options.Providers.Add
<BrotliCompressionProvider>(); options.Providers.Add<GzipCompressionProvider>
(); options.Providers.Add<CustomCompressionProvider>(); options.MimeTypes =
ResponseCompressionDefaults.MimeTypes.Concat(new[] { "image/svg+xml" }); }); }
Compression with secure protocol (带安全协议的压缩)

在安全连接上的压缩响应可以使用 EnableForHttps 项(option)来控制, 它默认是被禁用的, 在动态生成的页面上面使用压缩可能会导致安全问题,
例如  CRIME <https://wikipedia.org/wiki/CRIME_(security_exploit)> and BREACH
<https://wikipedia.org/wiki/BREACH_(security_exploit)>  攻击。

Adding the Vary header

当压缩响应在Accept-Encoding 头上时, 那是可能会有多个压缩版本(compressed versions)
的响应和一个不压缩的版本。为了指导客户端和代理(client and proxy)缓存多个存在的版本,并且存储,Vary 头是被加到
Accept-Encoding值。 在ASP.NET Core 2.0或者更新的版本,当响应被压缩时,中间件自动添加Vary 头。

Middleware issue when behind an Nginx reverse proxy (Nginx反向代理时中间件的问题)

当一个请求被Nginx代理时,Accept-Encoding 头被移除了, Accept-Encoding头的移除阻止了中间件压缩响应。更多的信息:
NGINX: Compression and Decompression
<https://www.nginx.com/resources/admin-guide/compression-and-decompression/>. 

Working with IIS dynamic compression

当你有一个激活的IIS动态压缩模块配置在服务器级别(at the server level), 你可能会想要在一个应用上禁止它,那么你可以在
web.config文件中禁用它。更多的信息:Disabling IIS modules
<https://www.cnblogs.com/Vincent-yuan/p/11026436.html#disabling-iis-modules>.  

 本文翻译于:
https://docs.microsoft.com/en-us/aspnet/core/performance/response-compression?view=aspnetcore-2.2

<https://docs.microsoft.com/en-us/aspnet/core/performance/response-compression?view=aspnetcore-2.2>

 

 

 

 

 

友情链接
ioDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信