Otimizar o tempo para o primeiro byte

Saiba como otimizar a métrica "Tempo até o primeiro byte".

O Tempo para o primeiro byte (TTFB) é uma métrica de desempenho da Web fundamental que precede todas as outras métricas significativas de experiência do usuário, como First Contentful Paint (FCP) e Largest Contentful Paint (LCP). Isso significa que valores altos de TTFB adicionam tempo às métricas que o seguem.

Recomendamos que o servidor responda às solicitações de navegação com rapidez suficiente para que a percentila 75 dos usuários tenha uma FCP dentro do limite "bom". Como guia aproximado, a maioria dos sites precisa ter um TTFB de 0,8 segundos ou menos.

Bons valores de TTFB são de 0,8 segundo ou menos, valores ruins são maiores que 1,8 segundo, e qualquer valor entre esses dois extremos precisa ser melhorado.

Como medir o TTFB

Antes de otimizar o TTFB, é necessário observar como ele afeta os usuários do seu site. Você deve usar os dados de campo como a principal fonte de observação do TTFB, já que ele é afetado por redirecionamentos, enquanto as ferramentas baseadas em laboratório são frequentemente medidas usando o URL final, perdendo esse atraso extra.

O PageSpeed Insights é uma maneira de receber informações de campo e de laboratório sobre sites públicos disponíveis no Relatório de experiência do usuário do Chrome.

O TTFB para usuários reais é mostrado na seção Descubra a experiência dos seus usuários reais:

Dados de usuários reais do PageSpeed Insights, incluindo dados de campo para a métrica TTFB.

Um subconjunto de TTFB é mostrado na auditoria do tempo de resposta do servidor:

Auditoria do tempo de resposta do servidor

Para saber mais sobre como medir o TTFB no campo e no laboratório, consulte a página da métrica TTFB.

Depurar TTFB alto no campo com Server-Timing

O cabeçalho de resposta Server-Timing pode ser usado no back-end do aplicativo para medir processos de back-end distintos que podem contribuir para a alta latência. A estrutura do valor do cabeçalho é flexível, aceitando, no mínimo, um identificador definido por você. Os valores opcionais incluem um valor de duração (usando dur) e uma descrição opcional legível por humanos (usando desc).

O Serving-Timing pode ser usado para medir muitos processos de back-end de aplicativos, mas há alguns que merecem atenção especial:

  • Consultas de banco de dados
  • Tempo de renderização do lado do servidor, se aplicável
  • Procuras de disco
  • Êxitos/falhas do cache do servidor de borda (se estiver usando uma CDN)

Todas as partes de uma entrada Server-Timing são separadas por dois-pontos, e várias entradas podem ser separadas por vírgulas:

// Two metrics with descriptions and values
Server-Timing: db;desc="Database";dur=121.3, ssr;desc="Server-side Rendering";dur=212.2

O cabeçalho pode ser definido usando o idioma de escolha do back-end do seu aplicativo. No PHP, por exemplo, é possível definir o cabeçalho da seguinte maneira:

<?php
// Get a high-resolution timestamp before
// the database query is performed:
$dbReadStartTime = hrtime(true);

// Perform a database query and get results...
// ...

// Get a high-resolution timestamp after
// the database query is performed:
$dbReadEndTime = hrtime(true);

// Get the total time, converting nanoseconds to
// milliseconds (or whatever granularity you need):
$dbReadTotalTime = ($dbReadEndTime - $dbReadStartTime) / 1e+6;

// Set the Server-Timing header:
header('Server-Timing: db;desc="Database";dur=' . $dbReadTotalTime);
?>

Quando esse cabeçalho é definido, ele mostra informações que podem ser usadas no laboratório e no campo.

No campo, qualquer página com um cabeçalho de resposta Server-Timing definido vai preencher a propriedade serverTiming na API Navigation Timing:

// Get the serverTiming entry for the first navigation request:
performance.getEntries('navigation')[0].serverTiming.forEach(entry => {
  // Log the server timing data:
  console.log(entry.name, entry.description, entry.duration);
});

No laboratório, os dados do cabeçalho de resposta Server-Timing serão visualizados no painel de tempos da guia Rede no Chrome DevTools:

Uma visualização dos valores do cabeçalho Server-Timing na guia &quot;Network&quot; do Chrome DevTools. Nesta imagem, os valores do cabeçalho Server-Timing estão medindo se um servidor de borda do CDN encontrou ou não um acerto ou erro de cache, além do tempo para recuperar o recurso do servidor de borda e da origem.

Cabeçalhos de resposta Server-Timing visualizados na guia de rede do Chrome DevTools. Aqui, Server-Timing é usado para medir se uma solicitação de um recurso atingiu o cache do CDN e quanto tempo leva para a solicitação atingir o servidor de borda do CDN e depois a origem.

Depois de determinar que você tem um TTFB problemático ao analisar os dados disponíveis, é possível corrigir o problema.

Maneiras de otimizar o TTFB

O aspecto mais desafiador da otimização do TTFB é que, embora a pilha de front-end da Web sempre seja HTML, CSS e JavaScript, as pilhas de back-end podem variar significativamente. Há vários stacks de back-end e produtos de banco de dados que têm técnicas de otimização próprias. Portanto, este guia vai se concentrar no que se aplica à maioria das arquiteturas, em vez de se concentrar apenas em orientações específicas da pilha.

Orientações específicas da plataforma

A plataforma usada no seu site pode afetar muito o TTFB. Por exemplo, a performance do WordPress é afetada pelo número e pela qualidade dos plug-ins ou pelos temas usados. Outras plataformas são afetadas de forma semelhante quando são personalizadas. Consulte a documentação da sua plataforma para conferir conselhos específicos do fornecedor que complementam as dicas de performance mais gerais desta postagem. A auditoria do Lighthouse para reduzir os tempos de resposta do servidor também inclui algumas orientações limitadas específicas da pilha.

Hospedagem, hospedagem, hospedagem

Antes de considerar outras abordagens de otimização, a hospedagem deve ser a primeira coisa que você considera. Não há muitas orientações específicas que possam ser oferecidas aqui, mas uma regra geral é garantir que o host do seu site seja capaz de processar o tráfego enviado a ele.

A hospedagem compartilhada geralmente é mais lenta. Se você estiver executando um pequeno site pessoal que serve principalmente arquivos estáticos, provavelmente não há problema. Algumas das técnicas de otimização a seguir vão ajudar a reduzir o TTFB o máximo possível.

No entanto, se você estiver executando um aplicativo maior com muitos usuários que envolve personalização, consulta de banco de dados e outras operações intensivas no servidor, sua escolha de hospedagem se torna essencial para reduzir o TTFB no campo.

Ao escolher um provedor de hospedagem, considere o seguinte:

  • Quanta memória é alocada pela instância do aplicativo? Se o aplicativo tiver memória insuficiente, ele vai ter dificuldades para carregar as páginas o mais rápido possível.
  • Seu provedor de hospedagem mantém o stack de back-end atualizado? À medida que novas versões de linguagens de back-end de aplicativos, implementações HTTP e softwares de banco de dados são lançadas, a performance nesse software é aprimorada com o tempo. É fundamental fazer parceria com um provedor de hospedagem que priorize esse tipo de manutenção crucial.
  • Se você tiver requisitos de aplicativo muito específicos e quiser o menor nível de acesso aos arquivos de configuração do servidor, pergunte se faz sentido personalizar a instância do seu próprio aplicativo.

Há muitos provedores de hospedagem que cuidam dessas coisas para você, mas se você começar a observar valores de TTFB longos, mesmo em provedores de hospedagem dedicados, pode ser um sinal de que talvez seja necessário reavaliar os recursos do seu provedor de hospedagem atual para que você possa oferecer a melhor experiência possível ao usuário.

Usar uma rede de fornecimento de conteúdo (CDN)

O tópico Uso de CDN é muito usado, mas por um bom motivo: você pode ter um back-end de aplicativo muito bem otimizado, mas os usuários localizados longe do servidor de origem ainda podem ter um TTFB alto no campo.

As CDNs resolvem o problema de proximidade do usuário do servidor de origem usando uma rede distribuída de servidores que armazenam em cache os recursos em servidores fisicamente mais próximos dos usuários. Esses servidores são chamados de servidores de borda.

Os provedores de CDN também podem oferecer benefícios além dos servidores de borda:

  • Os provedores de CDN geralmente oferecem tempos de resolução de DNS extremamente rápidos.
  • Uma CDN provavelmente vai enviar seu conteúdo de servidores de borda usando protocolos modernos, como HTTP/2 ou HTTP/3.
  • O HTTP/3, em particular, resolve o problema de bloqueio de cabeça de linha presente no TCP (em que o HTTP/2 depende) usando o protocolo UDP.
  • Uma CDN provavelmente também vai fornecer versões modernas de TLS, o que reduz a latência envolvida no tempo de negociação de TLS. O TLS 1.3, em particular, foi projetado para manter a negociação de TLS o mais curta possível.
  • Alguns provedores de CDN oferecem um recurso chamado "edge worker", que usa uma API semelhante à API Service Worker para interceptar solicitações, gerenciar respostas em cache de borda ou reescrever respostas.
  • Os provedores de CDN são muito bons na otimização para compactação. A compactação é difícil de fazer por conta própria e pode levar a tempos de resposta mais lentos em determinados casos com marcação gerada dinamicamente, que precisa ser compactada em tempo real.
  • Os provedores de CDN também armazenam automaticamente as respostas compactadas em cache para recursos estáticos, levando à melhor combinação de taxa de compactação e tempo de resposta.

Embora a adoção de um CDN exija um esforço variável, de trivial a significativo, ela deve ser uma prioridade para otimizar o TTFB se o site ainda não estiver usando um.

Usado conteúdo armazenado em cache sempre que possível

Os CDNs permitem que o conteúdo seja armazenado em cache em servidores de borda que estão localizados fisicamente mais próximos dos visitantes, desde que o conteúdo seja configurado com os cabeçalhos HTTP Cache-Control apropriados. Embora isso não seja adequado para conteúdo personalizado, exigir uma viagem de volta à origem pode anular grande parte do valor de um CDN.

Para sites que atualizam o conteúdo com frequência, até mesmo um tempo curto de armazenamento em cache pode resultar em ganhos de desempenho perceptíveis para sites movimentados, já que apenas o primeiro visitante durante esse período experimenta a latência total de volta ao servidor de origem, enquanto todos os outros visitantes podem reutilizar o recurso armazenado em cache do servidor de borda. Alguns CDNs permitem a invalidação do cache em versões de sites, oferecendo o melhor dos dois mundos: tempos de cache longos, mas atualizações instantâneas quando necessário.

Mesmo que o armazenamento em cache esteja configurado corretamente, isso pode ser ignorado com o uso de parâmetros de string de consulta exclusivos para medição do Google Analytics. Eles podem parecer diferentes para o CDN, mesmo sendo iguais, e, portanto, a versão em cache não será usada.

O conteúdo mais antigo ou menos visitado também pode não ser armazenado em cache, o que pode resultar em valores de TTFB mais altos em algumas páginas do que em outras. Aumentar os tempos de armazenamento em cache pode reduzir o impacto disso, mas lembre-se de que, com o aumento dos tempos de armazenamento em cache, há uma maior possibilidade de exibir conteúdo potencialmente desatualizado.

O impacto do conteúdo armazenado em cache não afeta apenas quem usa CDNs. A infraestrutura do servidor pode precisar gerar conteúdo de pesquisas de banco de dados caras quando o conteúdo armazenado em cache não pode ser reutilizado. Os dados acessados com mais frequência ou as páginas pré-armazenadas em cache geralmente têm um desempenho melhor.

Evite redirecionamentos múltiplos de página

Um dos fatores comuns que contribuem para um TTFB alto são os redirecionamentos. Os redirecionamentos ocorrem quando uma solicitação de navegação para um documento recebe uma resposta que informa ao navegador que o recurso existe em outro local. Um redirecionamento pode adicionar latência indesejada a uma solicitação de navegação, mas pode piorar se esse redirecionamento apontar para outro recurso que resulta em outro redirecionamento e assim por diante. Isso pode afetar principalmente os sites que recebem um grande volume de visitantes de anúncios ou newsletters, já que eles geralmente redirecionam por serviços de análise para fins de medição. Eliminar redirecionamentos sob seu controle direto pode ajudar a alcançar um bom TTFB.

Há dois tipos de redirecionamentos:

  • Redirecionamentos de mesma origem, em que o redirecionamento ocorre totalmente no seu site.
  • Redirecionamentos entre origens, em que o redirecionamento ocorre inicialmente em outra origem, como de um serviço de encurtamento de URL de mídia social, antes de chegar ao seu site.

Você quer se concentrar em eliminar redirecionamentos de mesma origem, porque tem controle direto sobre eles. Isso envolve verificar os links no seu site para ver se algum deles resulta em um código de resposta 302 ou 301. Isso geralmente acontece por não incluir o esquema https:// (de modo que os navegadores usam http:// por padrão, o que gera redirecionamentos) ou porque as barras finais não são incluídas ou excluídas corretamente no URL.

Os redirecionamentos entre origens são mais complicados, já que geralmente estão fora do seu controle, mas tente evitar vários redirecionamentos sempre que possível. Por exemplo, use vários encurtadores de links ao compartilhar links. Verifique se o URL fornecido aos anunciantes ou newsletters é o URL final correto para não adicionar outro redirecionamento aos usados por esses serviços.

Outro motivo importante para o tempo de redirecionamento é o redirecionamento de HTTP para HTTPS. Uma maneira de contornar isso é usar o cabeçalho Strict-Transport-Security (HSTS, na sigla em inglês), que vai forçar o HTTPS na primeira visita a uma origem e, em seguida, vai instruir o navegador a acessar a origem imediatamente pelo esquema HTTPS em visitas futuras.

Depois de implementar uma boa política de HSTS, você pode acelerar as coisas na primeira visita a uma origem adicionando seu site à lista de pré-carregamento de HSTS.

Transmitir a marcação para o navegador

Os navegadores são otimizados para processar a marcação de forma eficiente quando ela é transmitida, ou seja, a marcação é processada em partes à medida que chega do servidor. Isso é crucial quando se trata de payloads de marcação grandes, porque significa que o navegador pode analisar os pedaços de marcação de forma incremental, em vez de esperar que a resposta inteira chegue antes que o início da análise.

Embora os navegadores sejam ótimos para lidar com a marcação de streaming, é fundamental fazer o possível para manter o fluxo, para que os bits iniciais de marcação sejam enviados o mais rápido possível. Se o back-end estiver atrasando as coisas, isso é um problema. Como há muitas stacks de back-end, não é possível cobrir todas as stacks e os problemas que podem surgir em cada uma delas neste guia.

O React, por exemplo, e outros frameworks que podem renderizar marcação sob demanda no servidor usaram uma abordagem síncrona para a renderização do lado do servidor. No entanto, as versões mais recentes do React implementaram métodos de servidor para streaming de marcação conforme ela é renderizada. Isso significa que você não precisa esperar que um método da API do servidor React renderize toda a resposta antes de enviá-la.

Outra maneira de garantir que a marcação seja transmitida ao navegador rapidamente é usar a renderização estática, que gera arquivos HTML durante o build. Com o arquivo completo disponível imediatamente, os servidores da Web podem começar a enviar o arquivo imediatamente, e a natureza inerente do HTTP resultará em marcação de streaming. Embora essa abordagem não seja adequada para todas as páginas em todos os sites, como aquelas que exigem uma resposta dinâmica como parte da experiência do usuário, ela pode ser benéfica para páginas que não exigem que a marcação seja personalizada para um usuário específico.

Usar um worker de serviço

A API Service Worker pode ter um grande impacto no TTFB dos documentos e dos recursos carregados. Isso acontece porque um worker de serviço atua como um proxy entre o navegador e o servidor. No entanto, o impacto no TTFB do seu site depende de como você configura o worker de serviço e se essa configuração está alinhada aos requisitos do aplicativo.

  • Use uma estratégia de revalidação para recursos. Se um recurso estiver no cache do service worker, seja um documento ou um recurso necessário para o documento, a estratégia de revalidação enquanto está desatualizado vai atender esse recurso primeiro, depois vai fazer o download desse recurso em segundo plano e exibi-lo no cache para interações futuras.
    • Se você tiver recursos de documentos que não mudam com muita frequência, usar uma estratégia de revalidação pode tornar o TTFB de uma página quase instantâneo. No entanto, isso não funciona tão bem se o site enviar marcação gerada dinamicamente, como marcação que muda de acordo com a autenticação do usuário. Nesses casos, sempre acesse a rede primeiro para que o documento seja o mais recente possível.
    • Se o documento carregar recursos não críticos que mudam com alguma frequência, mas a busca do recurso desatualizado não afetar muito a experiência do usuário, como imagens selecionadas ou outros recursos que não são críticos, o TTFB desses recursos pode ser bastante reduzido usando uma estratégia desatualizada-enquanto-revalidar.
  • Use o modelo de shell do app para aplicativos renderizados pelo cliente. Esse modelo é mais adequado para SPAs em que o "shell" da página pode ser entregue instantaneamente do cache do service worker, e o conteúdo dinâmico da página é preenchido e renderizado mais tarde no ciclo de vida da página.

Usar 103 Early Hints para recursos de renderização críticos

Não importa o quanto o back-end do aplicativo está otimizado, ainda pode haver uma quantidade significativa de trabalho que o servidor precisa fazer para preparar uma resposta, incluindo trabalhos caros (mas necessários) no banco de dados que atrasam a resposta de navegação. O efeito potencial disso é que alguns recursos críticos de renderização subsequentes podem ser atrasados, como CSS ou, em alguns casos, JavaScript que renderiza a marcação no cliente.

O cabeçalho 103 Early Hints é um código de resposta inicial que o servidor pode enviar ao navegador enquanto o back-end está ocupado preparando a marcação. Esse cabeçalho pode ser usado para indicar ao navegador que há recursos de renderização críticos que a página precisa começar a fazer o download enquanto a marcação está sendo preparada. Para navegadores compatíveis, o efeito pode ser uma renderização de documentos mais rápida (CSS) e a disponibilidade mais rápida da funcionalidade principal da página (JavaScript).

Conclusão

Como há muitas combinações de pilhas de aplicativos de back-end, não há um artigo que possa englobar tudo o que você pode fazer para reduzir o TTFB do seu site. No entanto, estas são algumas opções que você pode testar para tentar acelerar um pouco as coisas no servidor.

Assim como na otimização de todas as métricas, a abordagem é bastante semelhante: meça o TTFB no campo, use ferramentas de laboratório para analisar as causas e aplique otimizações sempre que possível. Nem todas as técnicas aqui são viáveis para sua situação, mas algumas são. Como sempre, você precisa monitorar de perto os dados de campo e fazer ajustes conforme necessário para garantir a melhor experiência possível para o usuário.

Imagem principal de Taylor Vick, do Unsplash.