Compressione in HTTP
La compressione è un modo importante per aumentare le prestazioni di un sito web. Per alcuni documenti, una riduzione delle dimensioni fino al 70% riduce le esigenze di capacità di larghezza di banda. Nel corso degli anni, anche gli algoritmi sono diventati più efficienti e nuovi sono supportati da client e server.
In pratica, gli sviluppatori web non hanno bisogno di implementare meccanismi di compressione, sia i browser che i server li hanno già implementati, ma devono essere sicuri che il server sia configurato adeguatamente. La compressione avviene a tre livelli diversi:
- prima alcuni formati di file vengono compressi con metodi ottimizzati specifici,
- poi la crittografia generale può avvenire a livello HTTP (la risorsa viene trasmessa compressa da un capo all’altro)
- e infine la compressione può essere definita a livello di connessione, tra due nodi di una connessione HTTP.
Compressione del formato di file
Ogni tipo di dati ha una certa ridondanza, ovvero spazio sprecato. Se il testo può in genere avere una ridondanza fino al 60%, questa percentuale può essere molto più alta per altri media come audio e video. A differenza del testo, questi altri tipi di media utilizzano molto spazio per archiviare i propri dati e la necessità di ottimizzare l’archiviazione e recuperare spazio è stata evidente molto presto. Gli ingegneri hanno progettato l’algoritmo di compressione ottimizzato utilizzato dai formati di file progettati per questo scopo specifico. Gli algoritmi di compressione utilizzati per i file possono essere raggruppati in due ampie categorie:
- Compressione senza perdita(lossless), in cui il ciclo di compressione-decompressione non altera i dati recuperati. Corrisponde (byte per byte) all’originale. Per le immagini, gif o png utilizzano la compressione senza perdita.
- Compressione con perdita(lossy), in cui il ciclo altera i dati originali in un modo (si spera) impercettibile per l’utente. I formati video sul Web sono con perdita; anche il formato immagine jpeg è con perdita.
Alcuni formati possono essere utilizzati sia per la compressione senza perdita che per quella con perdita, come webp, e solitamente l’algoritmo con perdita può essere configurato per comprimere di più o di meno, il che ovviamente porta a una qualità inferiore o superiore.
Per prestazioni migliori di un sito Web, è ideale comprimere il più possibile, mantenendo un livello di qualità accettabile. Per le immagini, un’immagine generata da uno strumento potrebbe non essere sufficientemente ottimizzata per il Web; si consiglia di utilizzare strumenti che comprimano il più possibile con la qualità richiesta. Esistono numerosi strumenti specializzati per questo.
Gli algoritmi di compressione lossy sono solitamente più efficienti di quelli lossless.
Nota: poiché la compressione funziona meglio su un tipo specifico di file, di solito non fornisce nulla per comprimerli una seconda volta. Infatti, questo è spesso controproducente poiché il costo del sovraccarico (gli algoritmi di solito hanno bisogno di un dizionario che si aggiunge alla dimensione iniziale) può essere superiore al guadagno extra in compressione che si traduce in un file più grande. Non utilizzare le due tecniche seguenti per i file in un formato compresso.
Compressione end-to-end
Per la compressione, la compressione end-to-end è dove risiedono i maggiori miglioramenti delle prestazioni dei siti Web. La compressione end-to-end si riferisce a una compressione del corpo di un messaggio che viene eseguita dal server e rimarrà invariata fino a quando non raggiunge il client. Qualunque siano i nodi intermedi, lasciano il corpo intatto.
Un server che invia un corpo HTTP compresso a un client tramite nodi di rete. Il corpo non viene decompresso in nessun salto attraverso la rete fino a quando non raggiunge il client.
Tutti i browser e i server moderni lo supportano e l’unica cosa da negoziare è l’algoritmo di compressione da utilizzare. Questi algoritmi sono ottimizzati per il testo. Negli anni ’90, la tecnologia di compressione stava avanzando a un ritmo rapido e numerosi algoritmi successivi sono stati aggiunti al set di possibili scelte. Oggigiorno, solo due sono rilevanti: gzip, il più comune, e br il nuovo sfidante.
Per selezionare l’algoritmo da utilizzare, i browser e i server utilizzano la negoziazione proattiva dei contenuti. Il browser invia un’intestazione Accept-Encoding con l’algoritmo che supporta e il suo ordine di precedenza, il server ne sceglie uno, lo usa per comprimere il corpo della risposta e usa l’intestazione Content-Encoding per dire al browser l’algoritmo che ha scelto. Poiché la negoziazione del contenuto è stata usata per scegliere una rappresentazione in base alla sua codifica, il server deve inviare un’intestazione Vary contenente almeno Accept-Encoding insieme a questa intestazione nella risposta; in questo modo, le cache saranno in grado di mettere in cache le diverse rappresentazioni della risorsa.
Poiché la compressione apporta significativi miglioramenti delle prestazioni, si consiglia di attivarla per tutti i file, ad eccezione di quelli già compressi come immagini, file audio e video.
Apache supporta la compressione e utilizza mod_deflate; per Nginx c’è ngx_http_gzip_module; per IIS, l’elemento <httpCompression>.
Compressione hop-by-hop
La compressione hop-by-hop, sebbene simile alla compressione end-to-end, differisce per un elemento fondamentale: la compressione non avviene sulla risorsa nel server, creando una rappresentazione specifica che viene poi trasmessa, ma sul corpo del messaggio tra due nodi qualsiasi sul percorso tra il client e il server. Le connessioni tra nodi intermedi successivi possono applicare una compressione diversa.
Per fare questo, HTTP usa un meccanismo simile alla negoziazione del contenuto per la compressione end-to-end: il nodo che trasmette la richiesta pubblicizza la sua volontà usando l’intestazione TE e l’altro nodo sceglie il metodo adeguato, lo applica e indica la sua scelta con l’intestazione Transfer-Encoding.
In pratica, la compressione hop-by-hop è trasparente per il server e il client, e viene usata raramente. TE e Transfer-Encoding vengono usati principalmente per inviare una risposta a blocchi, consentendo di iniziare a trasmettere una risorsa senza conoscerne la lunghezza.
Nota che usare Transfer-Encoding e la compressione a livello di hop è così raro che la maggior parte dei server, come Apache, Nginx o IIS, non ha un modo semplice per configurarlo. Tale configurazione solitamente avviene a livello di proxy.