1. 程式人生 > >在ASP.NET Core中使用brotli壓縮

在ASP.NET Core中使用brotli壓縮

Brotli是一種全新的資料格式,可以提供比Zopfli高20-26%的壓縮比。據谷歌研究,Brotli壓縮速度同zlib的Deflate實現大致相同,而在Canterbury語料庫上的壓縮密度比LZMA和bzip2略大。 連結:Google開源Brotli壓縮演算法 微軟使用了一種基於谷歌提供的C程式碼的實現,向.NET Core 2.1添加了Brotli壓縮支援。由於Brotli得到了許多Web瀏覽器和Web伺服器的廣泛支援,所以.NET Core提供對這項技術的支援是非常有用的。

什麼是 Brotli 壓縮演算法

Brotli最初發佈於2015年,用於網路字型的離線壓縮。Google軟體工程師在2015年9月釋出了包含通用

無損資料壓縮的Brotli增強版本,特別側重於HTTP壓縮。其中的編碼器被部分改寫以提高壓縮比,編碼器和解碼器都提高了速度,流式API已被改進,增加更多壓縮質量級別。新版本還展現了跨平臺的效能改進,以及減少解碼所需的記憶體。

與常見的通用壓縮演算法不同,Brotli使用一個預定義的120千位元組字典。該字典包含超過13000個常用單詞、短語和其他子字串,這些來自一個文字和HTML文件的大型語料庫。預定義的演算法可以提升較小檔案的壓縮密度。

使用brotli替換deflate來對文字檔案壓縮通常可以增加20%的壓縮密度,而壓縮與解壓縮速度則大致不變。使用Brotli進行流壓縮的內容編碼型別已被提議使用“br”。

另附 Brotli 演算法和其他演算法的效能比較:

大部分瀏覽器都已經支援Brotli壓縮

Brotli瀏覽器支援

在 netcoreapp2.1 包裡面包含了 System.IO.Compression.Brotli

image

響應壓縮中介軟體檢視請求的頭部並檢查壓縮提供者是否可以處理其中一種可接受的編碼。預設情況下,只支援gzip演算法。通過實施自定義壓縮提供程式來支援自定義編碼。自定義提供程式必須實現該ICompressionProvider介面。該介面包含一個具有編碼名稱的屬性以及一個建立壓縮流的方法。System.IO.Compression.Brotli.dll 提供了一個BrotliStream

類,所以實現非常簡單:

public class BrotliCompressionProvider : ICompressionProvider
     {
         public string EncodingName => "br";
         public bool SupportsFlush => true;

        public Stream CreateStream(Stream outputStream)
         {
                return new BrotliStream(outputStream,CompressionLevel.Fastest);
         }
     }

客戶端提交的請求Accept-Encoding: br 標頭。 該中介軟體使用自定義壓縮的實現,並返回響應,其中Content-Encoding: br 標頭。 客戶端必須能夠解壓縮順序用於工作的自定義壓縮實現的自定義編碼brotli 。

image

VaryContent-Encoding標頭會顯示在響應。當壓縮響應基於Accept-Encoding標頭,有可能的多個壓縮的版本響應和未壓縮的版本。 若要指示客戶端和代理伺服器快取,多個版本存在,並且應儲存Vary標頭新增與Accept-Encoding值。 

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
     services.AddResponseCompression(options =>
     {         
         options.Providers.Add<BrotliCompressionProvider>();
         options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] { "image/svg+xml" });
     });

}

public void Configure(IApplicationBuilder app)
{
    app.UseResponseCompression();
    app.UseStaticFiles();
    app.UseMvcWithDefaultRoute();
}