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

Depois de eliminar downloads desnecessários de recursos, o melhor que você pode fazer para melhorar a velocidade de carregamento da 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 todos os recursos qualificados restantes que o navegador precisa transferir por download. 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 entradas do desenvolvedor.

Oferecer o melhor desempenho requer uma combinação de todas estas técnicas:

  • A compactação é o processo de codificar informações usando menos bits.
  • A eliminação de dados desnecessários sempre proporciona os melhores resultados.
  • Há várias técnicas e algoritmos de compactação diferentes.
  • Você precisará de diversas técnicas para conseguir a melhor compactação.

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

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

Para ilustrar os princípios fundamentais dessas técnicas, considere o processo de otimização de um formato de mensagem de texto simples que foi 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 nem os comportamentos da mensagem.
  2. As mensagens podem conter headers, que são pares de chave-valor (separados por ":" no exemplo anterior) exibidos no início da mensagem.
  3. As mensagens podem ter cargas 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. Há boas técnicas para codificar cabeçalhos de maneira eficiente. Por exemplo, se você sabe que todas as mensagens têm "format" e "date", é possível convertê-las em IDs inteiros curtos e apenas enviá-los. No entanto, como isso pode não ser verdade, é melhor não fazer isso por enquanto.
  3. O payload é somente de texto. Não sabemos qual é o conteúdo dele (aparentemente, ele está usando um "secret-cipher"), mas a análise do texto mostra que há muita redundância. Em vez de enviar letras repetidas, talvez você possa contar o número de letras repetidas e codificá-las com mais eficiência. Por exemplo, "AAA" se torna "3A", o que representa uma sequência de três As.

Combinar essas 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ê compactou a mensagem original em 72%. É 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 e, na Web, esses algoritmos 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, de modo que os usuários possam ver os efeitos desses recursos mais cedo do que veriam sem a 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 forma 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 desse 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. As otimizações são mais bem aplicadas como parte do processo de criação e implantação. Por exemplo, os bundlers são um tipo de software muito usado que pode reduzir 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 simplesmente excluir dados arbitrários. No entanto, em alguns contextos em que temos conhecimento específico do conteúdo do formato de dados e das propriedades dele, é possível reduzir significativamente o tamanho do payload sem afetar o significado ou os recursos reais.

<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 potencializar as interações e outros recursos avançados da página.

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

  • Os comentários de código são úteis para os desenvolvedores, mas o navegador não precisa deles. A remoção de comentários 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 sem afetar outros estilos, economizando mais bytes. Em um grande conjunto de regras de CSS, a remoção desse tipo de redundância pode aumentar, mas não pode ser algo que possa ser aplicado de forma agressiva, já que os seletores geralmente são duplicados em diferentes contextos, como em consultas de mídia.
  • Os espaços e as guias são conveniências para desenvolvedores em HTML, CSS e JavaScript. Um compressor adicional pode retirar todas as guias e espaços. Ao contrário de outras técnicas de eliminação de duplicação, 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, convém preservar os espaços nas execuções de texto em um documento HTML, porque eles garantem a legibilidade do conteúdo que os usuários realmente verão.
<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 muda de 516 para 204 caracteres, o que representa uma economia de aproximadamente 60%. Sim, não é muito legível, mas não precisa ser para ser utilizável. As práticas modernas de desenvolvimento também permitem manter as versões bem formatadas e legíveis do seu código-fonte separadas do código bem otimizado que você envia para a produção. Combinado com os mapas de origem, que fornecem uma representação legível do seu código de produção transformado, você pode solucionar mais facilmente bugs na produção e ter uma boa experiência de desenvolvedor, além de otimizar o desempenho para a experiência do usuário.

O exemplo anterior ilustra um ponto importante: um compactador de uso geral, como um projetado para compactar texto arbitrário, poderia compactar a página no exemplo anterior, mas nunca saberia remover os comentários, recolher regras CSS ou dezenas de outras otimizações específicas do conteúdo. É por isso que o pré-processamento, a minificação e outras otimizações com reconhecimento de 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 as próprias formas de metadados e vários payloads. Por exemplo, sempre que você tira uma foto com uma câmera, o arquivo dela normalmente incorpora várias outras informações: configurações da câmera, localização etc. 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 removê-lo. Na prática, esses metadados podem chegar a dezenas de kilobytes para cada imagem.

Em resumo, como primeira etapa na otimização da eficiência dos recursos, crie um inventário dos diferentes tipos de conteúdo e considere que tipos de otimizações específicas de conteúdo podem ser aplicados para reduzir o tamanho deles. Em seguida, depois de descobrir o que são, automatize essas otimizações adicionando-as às etapas de build e lançamento para garantir que as otimizações sejam aplicadas de maneira consistente a cada nova versão na 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, procurando agressivamente padrões repetíveis em payloads baseados em texto antes de enviá-los ao usuário e descompactá-los quando eles chegarem ao navegador do usuário. O resultado é uma redução ainda maior e significativa desses recursos e tempos de download mais rápidos.

  • O gzip e o Brotli são algoritmos de compactação usados com frequência e que funcionam melhor em recursos de texto: CSS, JavaScript e HTML.
  • Todos os navegadores modernos são compatíveis com a compactação gzip e Brotli e anunciarão o suporte para ambos no cabeçalho de solicitação HTTP Accept-Encoding.
  • Seu servidor deve estar configurado para ativar a compactação. O software servidor da Web geralmente permite que os módulos compactem recursos baseados em texto por padrão.
  • O gzip e o Brotli podem ser ajustados para melhorar as taxas de compactação, ajustando o nível de compactação. As configurações de compactação variam de 1 a 9 para o gzip, sendo 9 o melhor. Para 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 que são compactados dinamicamente, ou seja, no momento da solicitação, as configurações no meio do intervalo tendem a oferecer a melhor compensação entre a taxa de compactação e a velocidade. No entanto, a compactação estática é possível, ou seja, quando a resposta é compactada antecipadamente e, portanto, pode usar as configurações de compactação mais agressivas disponíveis para cada algoritmo de compactação.
  • As redes de fornecimento de conteúdo (CDNs, na sigla em inglês) geralmente oferecem a compactação automática de recursos qualificados. Os CDNs também podem gerenciar a compactação dinâmica e estática para você, oferecendo um aspecto da compactação a menos para se preocupar.

gzip e Brotli são compressores comuns que podem ser aplicados a qualquer fluxo de bytes. Internamente, eles se lembram de alguns conteúdos previamente examinados de um arquivo e, posteriormente, tentam encontrar e substituir fragmentos de dados duplicados de forma eficiente.

Na prática, o gzip e o Brotli têm melhor desempenho em conteúdo de texto, muitas vezes atingindo taxas de compactação de 70% a 90% em 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 ou com perda, gera pouco ou nenhuma melhoria.

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

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 as economias que a compactação com Brotli e gzip pode 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, dê preferência ao Brotli em vez do gzip.

Ativar a compactação é uma das otimizações mais simples e eficazes para implementar. Se seu site não estiver aproveitando isso, você está perdendo uma grande oportunidade de melhorar o desempenho para os usuários. Felizmente, muitos servidores da Web fornecem configurações padrão que permitem essa otimização importante, e as CDNs, em particular, são muito eficazes para implementá-las de uma maneira que equilibre a velocidade e a proporção de compactação.

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

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

Assim como na imagem anterior, você 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 um dos recursos 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 no desempenho não podem ser medidas, a menos que haja métricas que reflitam essas melhorias. A iniciativa Core Web Vitals existe para criar e aumentar o reconhecimento de métricas que refletem a experiência real do usuário. Isso é diferente em relação a métricas, como o tempo de carregamento de página simples, por exemplo, 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, dependendo dos recursos otimizados e das métricas envolvidas. No entanto, veja alguns casos em que a aplicação dessas otimizações pode melhorar as Core Web Vitals do seu site:

  • Os recursos HTML minificados e compactados podem melhorar o carregamento desse HTML e a detecção dos sub-recursos e, portanto, o carregamento deles. Isso pode ser útil para a Maior exibição de conteúdo (LCP) de uma página. Dicas de recursos, como rel="preload", podem ser usadas para afetar a capacidade de descoberta dos recursos, mas o uso excessivo delas pode causar problemas com a contenção da largura de banda. Ao garantir que a resposta HTML de uma solicitação de navegação seja compactada, os recursos dentro dela podem ser descobertos o mais rápido possível pelo verificador de pré-carregamento.
  • Algumas candidaturas a LCP também podem ser carregadas mais cedo usando a compactação. Por exemplo, imagens SVG que são candidatas a LCP podem ter o tempo de carregamento de recursos reduzido com a compactação baseada em texto. Isso é diferente das otimizações que você faria para outros tipos de imagem, que são compactadas intrinsecamente por outros métodos de compactação, por exemplo, como as imagens JPEG usam a compactação com perda.
  • Além disso, os nós de texto também podem ser candidatos à LCP. A maneira como as técnicas descritas neste guia dependem do uso de uma fonte da Web para textos nas páginas da Web. Se você estiver usando uma fonte da Web, as práticas recomendadas de otimização de fontes da Web vão ser aplicadas. No entanto, se você não estiver usando fontes da Web, mas sim fontes do sistema exibidas sem tempos de carregamento de recursos, a redução e a compactação do CSS reduz o tempo de carregamento. Isso significa que a renderização de possíveis nós de texto LCP pode ocorrer antes.

Conclusão

A forma de otimizar a codificação e a transferência de recursos baseados em texto é um conceito de desempenho básico, mas que tem um grande impacto. Faça tudo o que puder para garantir que os recursos qualificados para minificação e compactação sejam beneficiados com essas otimizações.

Mais importante ainda, certifique-se de que esses processos estejam sendo automatizados. Para minificação, use um bundler para aplicar a minificação a recursos qualificados. Verifique se a configuração do seu servidor da Web oferece suporte à compactação, mas, além disso, use a compactação mais eficaz disponível. Para tornar isso o mais trivial possível, use CDNs para automatizar a compactação, uma vez que elas não só podem compactar recursos para você, mas também podem fazer isso muito rapidamente.

Ao consolidar esses conceitos de performance de referência na arquitetura do seu site, você pode garantir que os esforços de otimização da performance estejam em uma boa base e que as otimizações subsequentes possam se basear em uma base sólida de boas práticas de referência.