本文,幫助瞭解響應壓縮的一些知識及用法(大部分翻譯於官網,英文水平有限,不準確之處,歡迎指正)。
什麼是響應壓縮?響應壓縮簡單的說就是為了減少網路頻寬,而把傳回的響應壓縮,使之體積縮小,從而加快響應的一種技術(個人理解)
網路頻寬是有限的資源。減少響應(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 探索響應壓縮的功能。這個例子表明:
- 應用的利用Gzip和自定義壓縮提供者的壓縮
- 怎樣增加MIME型別到預設的壓縮的MIME型別的串列
Package
為了在專案中包含這個中介軟體,增加一個到 Microsoft.AspNetCore.App metapackage, 的取用,它包含 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(); options.Providers.Add(); options.Providers.Add(); options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat( new[] { "image/svg+xml" }); }); }
使用BrotliCompressionProviderOptions設定壓縮級別。Brotli Compression Provider預設使用的是最快的壓縮級別( CompressionLevel.Fastest ), 這種級別可能不會產生最有效率的壓縮。如果最有效率的壓縮被需要時,可以為最佳的壓縮配置中介軟體
public void ConfigureServices(IServiceCollection services) { services.AddResponseCompression(); services.Configure(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(); options.Providers.Add(); options.Providers.Add(); options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat( new[] { "image/svg+xml" }); }); }
使用GzipCompressionProviderOptions設定壓縮級別。Gzip Compression Provider預設使用的是最快的壓縮級別( CompressionLevel.Fastest ), 這種級別可能不會產生最有效率的壓縮。如果最有效率的壓縮被需要時,可以為最佳的壓縮配置中介軟體
public void ConfigureServices(IServiceCollection services) { services.AddResponseCompression(); services.Configure(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(); options.Providers.Add(); options.Providers.Add(); 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(); options.Providers.Add(); options.Providers.Add(); options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat( new[] { "image/svg+xml" }); }); }
Compression with secure protocol (帶安全協議的壓縮)
在安全連線上的壓縮響應可以使用 EnableForHttps 項(option)來控制, 它預設是被禁用的, 在動態生成的頁面上面使用壓縮可能會導致安全問題, 例如 CRIME and BREACH 攻擊。
Adding the Vary essay-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.
Working with IIS dynamic compression
當你有一個啟用的IIS動態壓縮模組配置在伺服器級別(at the server level), 你可能會想要在一個應用上禁止它,那麼你可以在web.config檔案中禁用它。更多的資訊:Disabling IIS modules.
本文翻譯於:https://docs.microsoft.com/en-us/aspnet/core/performance/response-compression?view=aspnetcore-2.2
朋友會在“發現-看一看”看到你“在看”的內容