Compressione GZip in ASP.NET Core

di Moreno Gentili, in ASP.NET Core,

Quando sviluppiamo applicazioni web è importante che i tempi di caricamento siano ridotti al minimo, in modo che i nostri utenti abbiano una migliore percezione della qualità del nostro servizio.
Il protocollo HTTP prevede che i dati che inviamo al client possano essere compressi, in modo da ridurre la durata di ciascun trasferimento dati.

Se la nostra applicazione è ospitata nel webserver IIS, possiamo abilitare (o disabilitare) la compressione agendo sul nodo system.webServer/urlCompression del web.config.

<system.webServer>
  <urlCompression doStaticCompression="true" doDynamicCompression="false" />
</system.webServer>

Tuttavia, un'applicazione ASP.NET Core può essere ospitata anche da altri webserver. Nelle situazioni in cui non possiamo (o non vogliamo) affidarci ad IIS, ha senso che la compressione sia svolta dall'applicazione stessa per avere un comportamento uniforme e indipendente dalla piattaforma di hosting.

Aggiungere il middleware di compressione


Il pacchetto NuGet Microsoft.AspNetCore.ResponseCompression contiene un middleware di compressione che possiamo aggiungere alle nostre applicazioni ASP.NET Core 1.0 e 1.1.

Da Visual Studio 2017, apriamo la Console Package Manager e digitiamo il seguente comando:

Install-Package Microsoft.AspNetCore.ResponseCompression

Mentre, se stiamo usando Visual Studio Code, dalla scheda Terminal (o direttamente dal prompt dei comandi) digitiamo:

dotnet add package Microsoft.AspNetCore.ResponseCompression
dotnet restore

Ora che il pacchetto NuGet è installato, apriamo il file Startup.cs e configuriamo il middleware.

Nel metodo ConfigureServices, aggiungiamo una chiamata a AddResponseCompression:

public void ConfigureServices(IServiceCollection services)
{
  services.AddResponseCompression();
  // Qui configurazione di altri servizi
}

Poi modifichiamo così il metodo Configure, avendo cura di inserire la chiamata a UseResponseCompression subito prima degli eventuali metodi UseMvc e UseStaticFiles.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  app.UseResponseCompression();
  app.UseStaticFiles();
  app.UseMvc(routes =>
  {
    routes.MapRoute(
      name: "default",
      template: "{controller=Home}/{action=Index}/{id?}");
  });
}

Da questo momento, se avviamo l'applicazione e consultiamo gli strumenti di sviluppo del browser (tasto F12) noteremo che alcuni dei contenuti sono arrivati compressi con l'algoritmo gzip.


L'uso della compressione gzip è completamente trasparente dal punto di vista dell'applicazione client e non comporta alcuna ulteriore complessità nella comunicazione con il server.

Configurare il tipo di contenuti soggetti a compressione


I contenuti che ottengono i migliori benefici dalla compressione sono quelli testuali e, in generale, tutti quelli che contengono sequenze ripetute di byte. Ottimi candidati per la compressione sono le pagine HTML, gli stili CSS, i javascript e i dati JSON o XML, di dimensione superiore ad 1KB.
Negli altri casi, una ulteriore compressione potrebbe essere controproducente e dar luogo a trasferimenti di dimensione addirittura superiore all'originale.

Per default, i contenuti compressi dal middleware saranno:

  • Testi e pagine web aventi mimetype text/plain e text/html;
  • Stili e javascript con mimetype text/css, application/javascript;
  • Risultati JSON o XML con mimetype application/json, text/json, text/xml, application/xml.

Se desideriamo comprimere altri tipi di contenuto, come le immagini vettoriali SVG (sono file XML), modifichiamo così la chiamata a AddResponseCompression che abbiamo aggiunto in precedenza.

services.AddResponseCompression(options =>
{
  options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] { "image/svg+xml" });
});

Se invece vogliamo ridefinire l'intero elenco, scriviamo:

services.AddResponseCompression(options =>
{
  options.MimeTypes = new string[] { "text/html", "text/css", "image/svg+xml" };
});

Verifichiamo che la nostra impostazione ha avuto effetto grazie agli strumenti di sviluppo del browser.

Impostare il livello di compressione


Il middleware ci permette di decidere fra 3 livelli di compressione, così come indicato dall'enumerazione CompressionLevel:

  • NoCompression è il più rapido dei 3 ma non offre alcuna compressione effettiva. I dati compressi avranno una dimensione di poco superiore all'originale per via di un piccolo overhead dovuto al formato gzip;
  • Fastest (è il default) offre una buona compressione senza richiedere troppa capacità elaborativa;
  • Optimal richiede maggiore capacità elaborativa per comprimere i dati il più possibile.

Per impostare uno dei livelli di compressione, aggiungiamo questo blocco di codice al metodo ConfigureServices del file Startup.cs.

//Non necessario per usare Fastest, che è il default
services.Configure<GzipCompressionProviderOptions>(options =>
{
  options.Level = CompressionLevel.Optimal;
});

Secondo un rapido benchmark che coinvolge una risposta JSON di circa 600KB, l'opzione Fastest è il miglior compromesso tra compressione e capacità elaborativa richiesta.

Richiedere la compressione dal client


Il middleware eseguirà la compressione solo se nella richiesta HTTP è stata inclusa l'intestazione Accept-Encoding: gzip, oppure Accept-Encoding: *.

Se il nostro client è una pagina web, tale intestazione verrà automaticamente aggiunta dal browser web ogni volta che effettuiamo una richiesta ajax o carichiamo una nuova pagina web.

Lo stesso vale per un client .NET come un'applicazione Xamarin o WPF: se usiamo la classe HttpClient per inviare richieste web, l'intestazione Accept-Encoding verrà automaticamente aggiunta alle richieste. Possiamo anche configurare HttpClient in maniera esplicita per richiedere la compressione gzip in questo modo:

var handler = new HttpClientHandler()
{
  AutomaticDecompression = DecompressionMethods.Gzip
};

using (var client = new HttpClient(handler))
{
  //Qui inviamo una richiesta web
}

E' bene notare che il middleware di compressione supporta solo l'algoritmo gzip.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi