Compressão em HTTP

A Compressão é uma forma importante de aumentar o desempenho de um Web site. Para alguns documentos, a redução de tamanho de até 70% diminui a necessidade de capacidade de largura de banda. Com o passar dos anos, os algoritmos também ficaram mais eficientes e novos têm recebido suporte por clientes e servidores.

Na prática, os desenvolvedores web não precisam implementar mecanismos de compressão de dados, pois ambos os navegadores e servidores já possuem tais mecanismos implementados. Porém, é preciso ter certeza de que o servidor esteja configurado adequadamente. A compressão acontece em três níveis distintos:

  • primeiramente, alguns formatos de arquivo são comprimidos com métodos otimizados específicos,
  • então a criptografia ocorre no nível HTTP (o recurso é transmitido comprimido de ponta a ponta),
  • e finalmente a compressão pode ser definida no nível da conexão, entre dois nós de uma conexão HTTP.

Compressão de formato de arquivo

Cada tipo de dado tem alguma redundância, ou seja, espaço desperdiçado. Se um texto pode geralmente apresentar até 60% de redundância, essa taxa pode ser muito maior para outras mídias, como áudio e vídeo. Ao contrário do texto, esses outros tipos de mídia ocupam muito espaço de armazenamento, sendo que a necessidade de recuperar esse espaço desperdiçado apareceu muito cedo. Engenheiros projetaram o algoritmo de compressão otimizada usada por formatos de arquivo para esse fim específico. Os algoritmos de compressão usados para arquivos podem ser agrupados em duas grandes categorias:

  • Compressão sem perdas (do inglês Loss-less compression), em que o ciclo de compressão-descompressão não altera os dados recuperados. Corresponde byte a byte com o original. Para imagens, gif e png usam a compressão sem perdas.
  • Compressão com perdas (do inglês Lossy compression), onde o ciclo altera os dados originais, de forma imperceptível para o usuário. Formatos de vídeo na Web utilizam compressão com perdas, assim como o formato jpeg para imagens.

Alguns formatos podem ser usados para a compressão com ou sem perdas, como o webp. Geralmente, o algoritmo de compressão com perdas pode ser configurado para comprimir mais ou menos, resultando em uma qualidade menor ou maior.

Para o melhor desempenho de um site, é ideal comprimir o máximo possível, mantendo um nível aceitável de qualidade. Para imagens, uma imagem gerada por uma ferramenta pode não ser otimizada o suficiente para a Web. Recomenda-se portanto o uso de ferramentas que comprimirão o máximo possível com uma certa qualidade exigida. Existem inúmeras ferramentas especializadas para isso.

Algoritmos de compressão com perdas geralmente são mais eficientes que os sem perdas.

Nota: Como a compressão funciona melhor em tipos específicos de arquivos, ela geralmente não fornece nada mais ao comprimir o mesmo arquivo uma segunda vez. Na verdade, isso geralmente é contraproducente, pois o custo da sobrecarga (algoritmos geralmente precisam de um dicionário que some ao tamanho inicial) pode ser maior do que o ganho extra na compressão, resultando em um arquivo maior. Não use as duas técnicas a seguir para arquivos em um formato comprimido.

Compressão de ponta a ponta

Para compressão, a compressão de ponta a ponta é onde residem as maiores melhorias de desempenho dos sites. Compressão de ponta a ponta refere-se a uma compressão do corpo de uma mensagem que é realizada pelo servidor e permanecerá inalterada até atingir o cliente. Quaisquer que sejam os nós intermediários, eles deixam o corpo intacto.

Todos os navegadores e servidores modernos suportam a compressão, bastante somente negociar o algoritmo a ser usado. Esses algoritmos são otimizados para texto. Nos anos 90, a tecnologia de compressão avançava a um ritmo acelerado e numerosos algoritmos sucessivos foram adicionados ao conjunto de escolhas possíveis. Hoje em dia, apenas dois são relevantes: o gzip, o mais comum, e br o novo desafiante.

Para selecionar o algoritmo a ser usado, os navegadores e servidores usam a negociação proativa de conteúdo. O navegador envia um cabeçalho Accept-Encoding com o algoritmo que ele suporta e sua ordem de precedência. O servidor escolhe um, usa-o para comprimir o corpo da resposta e usa o Content-Encoding para informar ao navegador o algoritmo escolhido. Como a negociação de conteúdo foi usada para escolher uma representação baseada em sua codificação, o servidor deve enviar um cabeçalho Vary contendo pelo menos Accept-Encoding ao lado do cabeçalho na resposta. Dessa forma, os caches poderão armazenar em cache as diferentes representações do recurso.

Como a copressão de dados traz melhorias significativas no desempenho, recomenda-se ativá-la para todos os arquivos, com exceção daqueles já comprimidos, como imagens, arquivos de áudio e vídeos.

Apache suporta compressão e usa mod_deflate; para nginx existe ngx_http_gzip_module; para IIS, o elemento <httpCompression>.

Compressão de nó a nó (Hop-by-hop)

A compressão de nó a nó (do inglês Hop-by-hop compression), embora semelhante à compresão de ponta a ponta, difere em um elemento fundamental: a compressão não acontece no recurso no servidor, criando uma representação específica que é então transmitida, mas sim no corpo da mensagem entre dois nós no caminho entre o cliente e o servidor. Conexões entre nós intermediários sucessivos podem aplicar uma compressão diferente.

Para fazer isso, o HTTP usa um mecanismo semelhante à negociação de conteúdo para a compressão ponta a ponta: o nó que transmite a solicitação anuncia sua vontade usando o cabeçalho TE, sendo que o outro nó escolhe o método adequado, aplica-o e indica a sua escolha com o cabeçalho Transfer-Encoding.

Na prática, a compressão de nó a nó é transparente para o servidor e o cliente, sendo raramente usada. TE e Transfer-Encoding são usados principalmente para enviar uma resposta por partes, permitindo iniciar a transmissão de um recurso sem conhecer seu tamanho.

Observe que usar Transfer-Encoding e compressão a nível de salto entre nós é tão raro que a maioria dos servidores, como Apache, nginx ou IIS, não apresentam uma maneira fácil de configurá-lo. Tal configuração geralmente acontece no nível do proxy.