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

Depois da eliminação de downloads de recursos desnecessários, o melhor que podemos fazer para melhorar a velocidade de carregamento da página é minimizar o tamanho geral do download otimizando e comprimindo os recursos restantes.

Introdução à compactação de dados

Depois de configurar seu site para evitar o download de recursos não usados, a próxima etapa é comprimir os recursos qualificados restantes que o navegador precisa fazer o 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 de recursos específicos que exigem interação do desenvolvedor.

O fornecimento do melhor desempenho exige uma combinação de todas as seguintes técnicas:

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

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

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

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, 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 podem conter 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. 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", você pode convertê-los em IDs inteiros curtos e apenas enviar esses IDs. No entanto, isso pode não ser verdade, então é melhor não fazer nada por enquanto.
  3. O payload é apenas texto. Embora não saibamos qual é realmente o conteúdo dele (aparentemente, está usando um "secret-cipher"), apenas olhar para o 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ê 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 para reduzir o 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, 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 possam conferir os efeitos deles mais rapidamente do que 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 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 de conteúdo que pode reduzir significativamente o tamanho dos recursos entregues. As otimizações são melhor 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 minificar recursos automaticamente 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 de suas propriedades, é possível reduzir consideravelmente o tamanho do payload sem afetar o significado real ou os recursos.

<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 de 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 incrementar as 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, regras diferentes para especificar comentários e assim por diante. A questão que permanece é "como o tamanho dessa página pode ser reduzido?"

  • Os comentários de código são os melhores amigos dos desenvolvedores, mas o navegador não precisa deles. A eliminação de comentários CSS (/* ... */), HTML (<!-- ... -->) e JavaScript (// ...) reduz o tamanho total de transferência da página e dos subrecursos.
  • Um compressor de CSS "inteligente" pode perceber que estamos usando uma maneira ineficiente de definir regras para .awesome-container e juntar as duas declarações em uma sem afetar os outros estilos, economizando mais bytes. Em um grande conjunto de regras do CSS, a remoção desse tipo de redundância pode aumentar, mas não é algo que pode 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 convenientes para desenvolvedores no HTML, no CSS e no JavaScript. Um compressor adicional pode eliminar 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, é melhor preservar os espaços entre execuções de texto em um documento HTML, porque elas garantem a legibilidade do conteúdo que os usuários vão realmente 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>

Após a aplicação das etapas anteriores, a página vai 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 que você mantenha as versões formatadas e legíveis do código-fonte separadas do código bem otimizado enviado para a produção. Combinado com mapas de origem, que fornecem uma representação legível do código de produção transformado, facilita a solução de problemas de bugs na produção, o desenvolvedor pode ter uma boa experiência enquanto otimiza o desempenho para melhorar a experiência do usuário.

O exemplo anterior ilustra um ponto importante: um compressor de uso geral (por exemplo, um criado para compactar texto arbitrário) poderia compactar a página de forma eficiente, mas jamais saberia remover os comentários, recolher regras de CSS ou dezenas de outras otimizações específicas do conteúdo. É por isso que o pré-processamento, a minimização e outras otimizações sensíveis ao contexto são importantes.

Da mesma forma, as técnicas descritas acima podem ser estendidas para além de simples recursos baseados em texto. Imagens, vídeos e outros tipos de conteúdo contêm as próprias formas de metadados e diversos payloads. Por exemplo, sempre que você tira uma foto com uma câmera, o arquivo normalmente incorpora várias informações extras, como configurações da câmera, localização e assim por diante. Dependendo do aplicativo, esses dados podem ser essenciais (por exemplo, um site de compartilhamento de fotos) ou totalmente inúteis. Você precisa considerar se vale a pena remover. 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 quais tipos de otimizações específicas podem ser aplicados para reduzir o tamanho deles. Depois de descobrir o que 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 cada nova versão 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 assim que chegam ao navegador do usuário. O resultado é uma redução maior e significativa desses recursos e, subsequentemente, os 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 modernos são compatíveis com a compactação gzip e Brotli e anunciarão esse suporte no cabeçalho de solicitação HTTP Accept-Encoding.
  • Seu servidor precisa estar configurado para ativar a compressão. O software do servidor da Web muitas vezes permite que os módulos compactem recursos baseados em texto por padrão.
  • Tanto o gzip quanto o Brotli podem ser ajustados para melhorar as taxas de compressão ajustando o nível de compactação. Para o gzip, as configurações de compactação variam de 1 a 9, sendo 9 a melhor opção. 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 que são compactados dinamicamente, ou seja, no momento da solicitação, as configurações no meio do intervalo tendem a oferecer o melhor equilíbrio entre taxa de compactação e velocidade. No entanto, a compactação estática é possível, que é quando a resposta é compactada com antecedência e 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) geralmente oferecem compactação automática de recursos qualificados. Os CDNs também podem gerenciar a compactação dinâmica e estática, reduzindo o número de aspectos de compactação com que você precisa se preocupar.

gzip e Brotli são compressores comuns que podem ser aplicados a qualquer fluxo de bytes. Por trás, eles lembram de alguns dos conteúdos examinados anteriormente de um arquivo e, em seguida, 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 baseado em texto, muitas vezes alcançando taxas de compressão de até 70% a 90% para arquivos maiores. No entanto, a execução desses ativos 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 perda ou com perda, gera poucas melhorias.

Todos os navegadores modernos anunciam compatibilidade com 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 servir o recurso comprimido quando o cliente 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 as economias que a compressã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 ao gzip.

Ativar a compactação é uma das otimizações mais simples e eficazes a ser implementada. Se o seu site não estiver aproveitando isso, você está perdendo uma grande oportunidade de melhorar a performance para seus usuários. Felizmente, muitos servidores da Web oferecem configurações padrão que permitem essa otimização importante, e as CDNs, em particular, são muito eficazes na implementação de uma maneira que equilibra a velocidade e a proporção da compactação.

Uma maneira rápida de conferir a compressão em ação é abrir o Chrome DevTools, abrir o painel Network, carregar a página que você escolher e observar a parte de baixo do painel de rede.

Leitura do DevTools do tamanho real versus 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, conforme visualizado no painel de rede do Chrome DevTools.

Como na imagem anterior, você vai encontrar 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 da 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 a menos que haja métricas que reflitam essas melhorias. A iniciativa Core Web Vitals foi criada para criar e aumentar a conscientização sobre as métricas que refletem a experiência real do usuário. Isso contrasta com as métricas, como o tempo de carregamento da 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 das Core Web Vitals podem variar de acordo com os recursos otimizados e as métricas envolvidas. No entanto, confira alguns casos em que a aplicação dessas otimizações pode melhorar as Core Web Vitals do seu site:

  • Recursos HTML minificados e compactados podem melhorar o carregamento desse HTML, a capacidade de descoberta dos subrecursos e, portanto, o carregamento deles. Isso pode ser benéfico para a maior exibição de conteúdo (LCP) de uma página. Embora dicas de recursos como rel="preload" possam ser usadas para afetar a detectabilidade de recursos, o uso excessivo deles pode causar problemas com contenção de largura de banda. Ao garantir que a resposta HTML de uma solicitação de navegação seja compactada, os recursos nelas podem ser descobertos o mais rápido possível pelo verificador de pré-carregamento.
  • Alguns candidatos de LCP também podem ser carregados mais rapidamente usando a compactação. Por exemplo, imagens SVG candidatas a LCP podem ter a duração do carregamento de recursos reduzida por meio da compactação baseada em texto. Isso é diferente das otimizações que você faria para outros tipos de imagem, que são compactadas intrinsecamente por meio de outros métodos de compactação, como a maneira como imagens JPEG usam compactação com perda.
  • Além disso, os nós de texto também podem ser candidatos à LCP. A forma como as técnicas descritas neste guia dependem se você está usando uma fonte da Web para texto nas 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 usar fontes da Web, mas sim fontes do sistema que aparecem sem incorrer em nenhuma duração de carregamento de recursos, minimizar e compactar seu CSS reduz essa duração, o que significa que a renderização de possíveis nós de texto do LCP pode ocorrer mais cedo.

Conclusão

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

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, mas, mais do que isso, use a compactação mais eficaz disponível. Para tornar isso o mais simples possível, use CDNs para automatizar a compactação, já que elas não apenas podem compactar recursos, mas também podem fazer isso muito rapidamente.

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