Otimizar a codificação e o tamanho da transferência de recursos baseados em texto

Além de eliminar downloads de recursos desnecessários, a melhor coisa que você pode fazer para melhorar a velocidade de carregamento de página é minimizar o tamanho geral do download otimizando e compactando os recursos restantes.

Introdução à compactação de dados

Depois de configurar seu site para evitar o download de recursos não utilizados, a próxima etapa é compactar os recursos restantes qualificados que o navegador precisa baixar. Dependendo do tipo de recurso (texto, imagens, fontes etc.), há muitas técnicas diferentes para escolher: ferramentas genéricas que podem ser ativadas no servidor da Web, otimizações de pré-processamento para tipos de conteúdo específicos e otimizações específicas de recursos que exigem entrada do desenvolvedor.

Para oferecer a melhor performance, é preciso combinar todas as técnicas a seguir:

  • A compactação é o processo de codificação de informações usando menos bits.
  • Eliminar dados desnecessários sempre gera os melhores resultados.
  • Existem muitas técnicas e algoritmos de compactação diferentes.
  • Você vai precisar de várias técnicas para conseguir a melhor compactação.

O processo de redução do tamanho dos dados é chamado de compactação de dados. Muitas pessoas contribuíram com algoritmos, técnicas e otimizações para melhorar as taxas de compressão, a velocidade de compressão e a memória necessária para vários algoritmos de compressão.

Uma discussão completa sobre compactação de dados está muito além do escopo deste guia. No entanto, é importante entender, em um nível alto, como a compactação funciona e as técnicas que você pode usar para reduzir o tamanho de vários recursos necessários para suas páginas.

Para ilustrar os princípios básicos dessas técnicas, considere o processo de otimizar um formato simples de mensagem de texto inventado apenas para este exemplo:

# Below is a secret message, which consists of a set of headers in
# key-value format followed by a newline and the encrypted message.
format: secret-cipher
date: 08/25/16
AAAZZBBBBEEEMMM EEETTTAAA
  1. As mensagens podem conter anotações arbitrárias, às vezes chamadas de comentários, que são indicadas pelo prefixo "#". As anotações não afetam o significado da mensagem nem os comportamentos dela.
  2. As mensagens podem conter cabeçalhos, que são pares de chave-valor (separados por ":" no exemplo anterior) que aparecem no início da mensagem.
  3. As mensagens carregam payloads de texto.

O que pode ser feito para reduzir o tamanho da mensagem anterior, que começa com 200 caracteres?

  1. O comentário é interessante, mas não afeta o significado da mensagem. Elimine-o ao transmitir a mensagem.
  2. Existem boas técnicas para codificar cabeçalhos de maneira eficiente. Por exemplo, se você sabe que todas as mensagens têm "formato" e "data", pode converter esses dados em IDs de números inteiros curtos e enviar apenas eles. No entanto, isso pode não ser verdade, então é melhor deixar como está por enquanto.
  3. O payload é apenas texto. Embora não saibamos o que o conteúdo realmente é (aparentemente, ele está usando um "secret-cipher"), basta olhar para o texto para perceber que há muita redundância nele. Talvez, em vez de enviar letras repetidas, você possa contar o número de letras repetidas e codificá-las de forma mais eficiente. Por exemplo, "AAA" se torna "3A", que representa uma sequência de três As.

A combinação dessas técnicas produz o seguinte resultado:

format: secret-cipher
date: 08/25/16
3A2Z4B3E3M 3E3T3A

A nova mensagem tem 56 caracteres, o que significa que você comprimiu a mensagem original em 72%. Essa é uma redução significativa.

Este é um exemplo simples de como os algoritmos de compactação podem ser eficazes na redução do tamanho da transferência de recursos baseados em texto. Na prática, os algoritmos de compactação são muito mais sofisticados do que o exemplo anterior ilustra. Na Web, eles podem ser usados para reduzir significativamente os tempos de download de recursos. Ao aplicar a compactação a recursos baseados em texto, uma página da Web pode gastar menos tempo carregando recursos, para que os usuários vejam os efeitos desses recursos mais cedo do que sem compactação.

Minificação: pré-processamento e otimizações específicas do contexto

A primeira técnica discutida aqui é a minificação. Embora a minificação não seja estritamente um algoritmo de compactação, ela é uma maneira de remover caracteres desnecessários e redundantes usados no código-fonte para tornar os recursos mais legíveis para humanos. No entanto, essa legibilidade não é necessária para manter a funcionalidade do código-fonte em sites de produção e pode atrasar o carregamento de recursos na Web.

A minificação é um tipo de otimização específica do conteúdo que pode reduzir significativamente o tamanho dos recursos entregues. Essas otimizações são mais bem aplicadas como parte do processo de build e implantação. Por exemplo, os bundlers são um tipo de software usado com frequência que pode minimizar automaticamente os recursos pouco antes da implantação de um novo código de produção em um site.

A melhor maneira de compactar dados redundantes ou desnecessários é eliminá-los. No entanto, não é possível excluir dados arbitrários. No entanto, em alguns contextos em que temos conhecimento específico do conteúdo sobre o formato de dados e suas propriedades, é possível reduzir significativamente o tamanho da carga útil sem afetar o significado ou as capacidades reais dela.

<html>
  <head>
    <style>
      /* awesome-container is only used on the landing page */
      .awesome-container {
        font-size: 120%;
      }

      .awesome-container {
        width: 50%;
      }
    </style>
  </head>
  <body>
    <!-- awesome container content: START -->
    <div>
      This is my awesome container, and it is <em>so</em> awesome.
    </div>
    <!-- awesome container content: END -->
    <script>
      awesomeAnalytics(); // Beacon conversion metrics
    </script>
  </body>
</html>

Considere o snippet HTML anterior e os três tipos de conteúdo diferentes que ele contém:

  1. Marcação HTML.
  2. CSS para personalizar a apresentação de uma página.
  3. JavaScript para ativar interações e outros recursos avançados da página.

Cada um desses tipos de conteúdo tem regras diferentes para o que constitui conteúdo válido, para especificar comentários e assim por diante. A questão que permanece, no entanto, é: "como o tamanho dessa página pode ser reduzido?"

  • Os comentários de código são os melhores amigos de um desenvolvedor, mas o navegador não precisa deles. A remoção de comentários em CSS (/* ... */), HTML (<!-- ... -->) e JavaScript (// ...) reduz o tamanho total da transferência da página e dos sub-recursos dela.
  • Um compressor de CSS "inteligente" pode perceber que estamos usando uma maneira ineficiente de definir regras para .awesome-container e recolher as duas declarações em uma só sem afetar outros estilos, economizando mais bytes. Em um grande conjunto de regras de CSS, remover esse tipo de redundância pode ser útil, mas talvez não seja algo que possa ser aplicado de forma agressiva, já que os seletores geralmente são duplicados em contextos diferentes, como em consultas de mídia.
  • Espaços e tabulações são conveniências para desenvolvedores em HTML, CSS e JavaScript. Um compressor adicional pode remover todas as tabulações e espaços. Ao contrário de outras técnicas de remoção de duplicidade, esse tipo de otimização pode ser aplicado de forma bastante agressiva, desde que esses espaços ou guias não sejam necessários para a apresentação da página. Por exemplo, é importante preservar os espaços em execuções de texto em um documento HTML, já que eles garantem a legibilidade do conteúdo que os usuários vão ver.
<html><head><style>.awesome-container{font-size:120%;width:50%}</style></head><body><div>This is my awesome container, and it is <em>so</em> awesome.</div><script>awesomeAnalytics()</script></body></html>

Depois de aplicar as etapas anteriores, a página passa de 516 para 204 caracteres, o que representa uma economia de aproximadamente 60%. É verdade que não é muito legível, mas não precisa ser para ser útil. As práticas de desenvolvimento modernas também permitem manter as versões bem formatadas e legíveis do código-fonte separadas do código bem otimizado que você envia para produção. Combinado com mapas de origem, que fornecem uma representação legível do seu código de produção transformado, você pode resolver problemas de bugs na produção com mais facilidade e ter uma boa experiência de desenvolvedor ao mesmo tempo em que otimiza o desempenho para a experiência do usuário.

O exemplo anterior ilustra um ponto importante: um compressor de uso geral, digamos, projetado para compactar texto arbitrário, pode fazer um bom trabalho de compactação da página no exemplo anterior, mas nunca saberia remover os comentários, recolher as regras de CSS ou dezenas de outras otimizações específicas de conteúdo. Por isso, o pré-processamento, a minificação e outras otimizações com base no contexto são importantes.

Da mesma forma, as técnicas descritas acima podem ser estendidas além dos recursos baseados em texto. Imagens, vídeos e outros tipos de conteúdo têm suas próprias formas de metadados e vários payloads. Por exemplo, sempre que você tira uma foto com uma câmera, o arquivo geralmente incorpora muitas informações extras: configurações da câmera, local e assim por diante. Dependendo do aplicativo, esses dados podem ser essenciais (por exemplo, um site de compartilhamento de fotos) ou completamente inúteis. Considere se vale a pena remover. Na prática, esses metadados podem adicionar até dezenas de kilobytes a cada imagem.

Em resumo, como primeira etapa para otimizar a eficiência dos seus recursos, crie um inventário dos diferentes tipos de conteúdo e considere quais otimizações específicas de conteúdo podem ser aplicadas para reduzir o tamanho deles. Depois de descobrir quais são, automatize essas otimizações adicionando-as às etapas de build e lançamento para garantir que elas sejam aplicadas de forma consistente em todas as novas versões para produção.

Compactação de texto com algoritmos de compactação

A próxima etapa para reduzir o tamanho dos recursos baseados em texto é aplicar um algoritmo de compactação a eles. Isso vai um passo além, pesquisando agressivamente padrões repetíveis em payloads baseados em texto antes de enviá-los ao usuário e descompactando-os quando chegam ao navegador do usuário. O resultado é uma redução ainda maior e significativa desses recursos e tempos de download mais rápidos.

  • gzip e Brotli são algoritmos de compactação usados com frequência que têm melhor desempenho em recursos baseados em texto: CSS, JavaScript e HTML.
  • Todos os navegadores mais recentes são compatíveis com a compactação gzip e Brotli e anunciam suporte para ambos no cabeçalho da solicitação HTTP Accept-Encoding.
  • Seu servidor precisa estar configurado para ativar a compactação. O software do servidor da Web geralmente ativa módulos para compactar recursos baseados em texto por padrão.
  • Tanto o gzip quanto o Brotli podem ser ajustados para melhorar as taxas de compactação ao ajustar o nível de compactação. Para gzip, as configurações de compactação variam de 1 a 9, sendo 9 a melhor. Para o Brotli, esse intervalo é de 0 a 11, sendo 11 o melhor. No entanto, configurações de compactação mais altas exigem mais tempo. Para recursos compactados dinamicamente, ou seja, no momento da solicitação, as configurações no meio do intervalo tendem a oferecer o melhor custo-benefício entre taxa de compactação e velocidade. No entanto, é possível fazer a compactação estática, em que a resposta é compactada com antecedência e, portanto, pode usar as configurações de compactação mais agressivas disponíveis para cada algoritmo.
  • As redes de fornecimento de conteúdo (CDNs) geralmente oferecem compactação automática de recursos qualificados. As CDNs também podem gerenciar a compactação dinâmica e estática para você, o que significa uma preocupação a menos.

gzip e Brotli são compactadores comuns que podem ser aplicados a qualquer fluxo de bytes. Por baixo dos panos, eles se lembram de alguns dos conteúdos examinados anteriormente de um arquivo e tentam encontrar e substituir fragmentos de dados duplicados de maneira eficiente.

Na prática, o gzip e o Brotli têm melhor desempenho em conteúdo baseado em texto, muitas vezes alcançando taxas de compressão de até 70 a 90% para arquivos maiores. No entanto, executar esses recursos de algoritmos que já estão compactados usando algoritmos alternativos, como a maioria dos formatos de imagem que usam técnicas de compactação sem perdas ou com perdas, não gera melhorias significativas.

Todos os navegadores mais recentes anunciam suporte para gzip e Brotli no cabeçalho da solicitação HTTP Accept-Encoding. No entanto, é responsabilidade do provedor de hospedagem garantir que o servidor da Web esteja configurado corretamente para veicular o recurso compactado quando o cliente o solicitar.

Arquivo Algoritmo Tamanho descompactado Tamanho compactado Taxa de compressão
angular-1.8.3.js Brotli 1.346 KiB 256 KiB 81%
angular-1.8.3.js gzip 1.346 KiB 329 KiB 76%
angular-1.8.3.min.js Brotli 173 KiB 53 KiB 69%
angular-1.8.3.min.js gzip 173 KiB 60 KiB 65%
jquery-3.7.1.js Brotli 302 KiB 69 KiB 77%
jquery-3.7.1.js gzip 302 KiB 83 KiB 73%
jquery-3.7.1.min.js Brotli 85 KiB 27 KiB 68%
jquery-3.7.1.min.js gzip 85 KiB 30 KiB 65%
lodash-4.17.21.js Brotli 531 KiB 73 KiB 86%
lodash-4.17.21.js gzip 531 KiB 94 KiB 82%
lodash-4.17.21.min.js Brotli 71 KiB 23 KiB 68%
lodash-4.17.21.min.js gzip 71 KiB 25 KiB 65%

A tabela anterior mostra a economia que a compactação Brotli e gzip podem oferecer para algumas bibliotecas JavaScript conhecidas. A economia varia de 65% a 86%, dependendo do arquivo e do algoritmo. Para referência, o nível máximo de compactação foi aplicado a cada arquivo para Brotli e gzip. Sempre que possível, prefira o Brotli em vez do gzip.

Ativar a compactação é uma das otimizações mais simples e eficazes de implementar. Se o seu site não estiver aproveitando esse recurso, você está perdendo uma grande oportunidade de melhorar a performance para os usuários. Felizmente, muitos servidores da Web oferecem configurações padrão que ativam essa otimização importante, e as CDNs, em particular, são muito eficazes na implementação dela de uma forma que equilibra a velocidade e a taxa de compactação.

Uma maneira rápida de ver a compressão em ação é abrir o Chrome DevTools, o painel Rede, carregar uma página de sua escolha e observar a parte inferior do painel de rede.

Leitura do DevTools do tamanho real versus o tamanho de transferência.
Uma representação do tamanho da transferência (ou seja, compactado) de todos os recursos da página em comparação com o tamanho real deles, conforme visualizado no painel de rede do Chrome DevTools.

Assim como na imagem anterior, você vai ver um detalhamento de:

  • O número de solicitações, que é o número de recursos carregados para a página.
  • O tamanho da transferência de todas as solicitações. Isso reflete a eficácia da compactação aplicada a qualquer recurso de uma página.
  • O tamanho do recurso de todas as solicitações. Isso reflete o tamanho dos recursos da página depois da descompactação.

Efeitos nas Core Web Vitals

As melhorias de performance não podem ser medidas sem métricas que reflitam essas melhorias. A iniciativa Core Web Vitals existe para criar e aumentar a conscientização sobre métricas que refletem a experiência real do usuário. Isso contrasta com métricas, como o tempo simples de carregamento da página, que não se traduzem claramente na qualidade da experiência do usuário.

Quando você aplica as otimizações descritas neste guia aos recursos do seu site, os efeitos nas Core Web Vitals podem variar de acordo com os recursos otimizados e as métricas envolvidas. No entanto, confira alguns casos em que aplicar essas otimizações pode melhorar as Core Web Vitals do seu site:

  • Recursos HTML minimizados e compactados podem melhorar o carregamento do HTML, a capacidade de descoberta dos sub-recursos e, portanto, o carregamento deles. Isso pode ser benéfico para a Largest Contentful Paint (LCP) de uma página. Embora as dicas de recursos, como rel="preload", possam ser usadas para afetar a capacidade de descoberta de recursos, usar muitas delas pode causar problemas com a disputa de largura de banda. Ao garantir que a resposta HTML para uma solicitação de navegação seja compactada, os recursos nela podem ser descobertos o mais rápido possível pelo scanner de pré-carregamento.
  • Alguns candidatos a LCP também podem ser carregados mais cedo usando a compactação. Por exemplo, as imagens SVG, que são candidatas a LCP, podem ter a duração do carregamento de recursos reduzida com a compactação baseada em texto. Isso é diferente das otimizações que você faria em outros tipos de imagem, que são compactadas intrinsecamente por outros métodos de compactação, como o uso de compactação com perda em imagens JPEG.
  • Além disso, nós de texto também podem ser candidatos a LCP. Como as técnicas descritas neste guia dependem do uso de uma fonte da Web para texto nas suas páginas da Web. Se você estiver usando uma fonte da Web, as práticas recomendadas de otimização de fontes da Web serão aplicadas. No entanto, se você não estiver usando fontes da Web, mas sim fontes do sistema que são exibidas sem incorrer em nenhuma duração de carregamento de recursos, a minificação e a compactação do CSS vão reduzir essa duração, o que significa que a renderização de possíveis nós de texto LCP pode ocorrer antes.

Conclusão

A forma como você otimiza a codificação e a transferência de recursos baseados em texto é um conceito básico de performance, mas que tem um grande impacto. Faça o possível para garantir que os recursos qualificados para minificação e compressão estejam aproveitando essas otimizações.

E, mais importante, verifique se esses processos estão sendo automatizados. Para minificação, use um bundler para aplicar a minificação aos recursos qualificados. Verifique se a configuração do servidor da Web oferece suporte à compactação e use a mais eficiente disponível. Para tornar isso o mais trivial possível, use CDNs para automatizar a compactação, já que elas não apenas compactam recursos, mas também fazem isso muito rapidamente.

Ao consolidar esses conceitos básicos de performance na arquitetura do seu site, você garante que seus esforços de otimização de performance estejam em uma boa posição e que as otimizações subsequentes possam se basear em uma base sólida de boas práticas básicas.