Otimizar o tempo para o primeiro byte

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

O tempo até o primeiro byte (TTFB, na sigla em inglês) é uma métrica fundamental de desempenho da Web que antecede todas as outras métricas significativas da experiência do usuário, como First Contentful Paint (FCP) e Largest Contentful Paint (LCP). Isso significa que altos valores 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 o 75o percentil dos usuários tenha uma FCP dentro do limite "bom". Em termos gerais, a maioria dos sites deve ter um TTFB de 0,8 segundos ou menos.

Bons valores TTFB são 0,8 segundos ou menos, valores ruins são maiores do que 1,8 segundo e tudo o que está entre eles precisa ser melhorado

Como medir o TTFB

Antes de otimizar o TTFB, você precisa observar como isso afeta os usuários do seu site. Confie nos dados de campo como a principal fonte de observação do TTFB, enquanto ele é afetado por redirecionamentos, enquanto as ferramentas baseadas em laboratórios geralmente são medidas usando o URL final, portanto, não têm esse atraso extra.

O PageSpeed Insights é uma maneira de receber informações de campo e de laboratórios para sites públicos que estão disponíveis no Chrome User Experience Report.

O TTFB para usuários reais é exibido na seção superior Descubra o que seus usuários reais estão experimentando:

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

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

Auditoria do tempo de resposta do servidor

Para descobrir mais formas de medir o TTFB, tanto em campo quanto no laboratório, consulte a página de métricas do TTFB.

Depurar o 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 e aceita, no mínimo, um identificador definido por você. Os valores opcionais incluem um valor de duração (usando dur), bem como uma descrição opcional legível por humanos (usando desc).

O Serving-Timing pode ser usado para medir muitos processos de back-end de aplicativo, mas preste atenção especial a alguns deles:

  • Consultas de banco de dados
  • Tempo de renderização do lado do servidor, se aplicável
  • Buscas de disco
  • Ocorrências/ausências no 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 uma vírgula:

// 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 a linguagem de preferência do back-end do aplicativo. No PHP, por exemplo, você pode definir o cabeçalho assim:

<?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 - $dbReadStarTime) / 1e+6;

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

Quando definido, esse cabeçalho vai mostrar 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 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 tempo da guia Rede no Chrome DevTools:

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

Server-Timing cabeçalhos de resposta visualizados na guia de rede do Chrome DevTools. Aqui, Server-Timing é usado para medir se uma solicitação de um recurso atingiu o cache da CDN e quanto tempo leva para a solicitação chegar ao servidor de borda da CDN e, em seguida, à origem.

Depois de determinar que você tem um TTFB problemático através da análise dos dados disponíveis, então você pode prosseguir para a correção do problema.

Formas 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. Existem inúmeras pilhas de back-end e produtos de banco de dados, cada um com técnicas de otimização próprias. Portanto, este guia se concentrará no que se aplica à maioria das arquiteturas, em vez de se concentrar apenas na orientação específica da pilha.

Orientações específicas da plataforma

A plataforma que você usa para seu site pode ter um grande impacto no TTFB. Por exemplo, o desempenho do WordPress é afetado pelo número e pela qualidade dos plug-ins ou pelos temas usados. Outras plataformas são afetadas da mesma forma quando são personalizadas. Consulte a documentação da sua plataforma para ver orientações específicas sobre fornecedores e complementar as orientações de desempenho mais gerais desta postagem. A auditoria do Lighthouse para reduzir os tempos de resposta do servidor também inclui algumas orientações específicas para pilhas.

Hospedagem, hospedagem e hospedagem

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

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

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

Ao escolher um provedor de hospedagem, considere o seguinte:

  • Quanta memória está alocada na instância do seu aplicativo? Se o seu aplicativo tiver memória insuficiente, ele se sobrecarregará e terá dificuldades para exibir as páginas o mais rápido possível.
  • O provedor de hospedagem mantém a pilha de back-end atualizada? À medida que novas versões de linguagens de back-end de aplicativos, implementações HTTP e software de banco de dados são lançadas, o desempenho desse software será aprimorado ao longo do tempo. É fundamental fazer parceria com um provedor de hospedagem que prioriza esse tipo de manutenção crucial.
  • Se você tem requisitos de aplicativo muito específicos e quer o nível mais baixo de acesso aos arquivos de configuração do servidor, pergunte se faz sentido personalizar o back-end da instância do seu aplicativo.

Muitos provedores de hospedagem cuidam disso para você, mas se você começar a observar valores longos de TTFB mesmo em provedores de hospedagem dedicados, pode ser um sinal de que você pode precisar reavaliar as capacidades do seu provedor de hospedagem atual para que possa oferecer a melhor experiência possível ao usuário.

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

O tópico Uso da CDN é muito usado, mas por um bom motivo: você poderia 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 em campo.

As CDNs resolvem o problema da proximidade do usuário em relação ao servidor de origem usando uma rede distribuída de servidores que armazenam recursos em cache nos servidores que estão 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.
  • Um CDN provavelmente vai veicular seu conteúdo de servidores de borda usando protocolos modernos, como HTTP/2 ou HTTP/3.
  • Em especial, o HTTP/3 resolve o problema de bloqueio no cabeçalho da linha presente no TCP (de que o HTTP/2 depende) usando o protocolo UDP.
  • Um CDN provavelmente também fornecerá versões modernas de TLS, o que diminui a latência envolvida no tempo de negociação do TLS. O TLS 1.3 (link em inglês) foi desenvolvido para manter a negociação do TLS o mais curta possível.
  • Alguns provedores de CDN oferecem um recurso chamado de "worker de borda", que usa uma API semelhante à da API Service Worker para interceptar solicitações, gerenciar de maneira programática respostas em caches de borda ou reescrever respostas completamente.
  • Os provedores de CDN são muito bons em otimizar a compactação. A compactação é difícil de acertar por conta própria e, em alguns casos, pode levar a tempos de resposta mais lentos, com marcação gerada dinamicamente, que precisa ser compactada em tempo real.
  • Os provedores de CDN também armazenam em cache automaticamente as respostas compactadas para recursos estáticos, resultando na melhor combinação de taxa de compactação e tempo de resposta.

A adoção de uma CDN envolve um esforço variado de trivial a significativo, mas deve ser uma alta prioridade na otimização do TTFB se seu site ainda não estiver usando um.

Usou conteúdo armazenado em cache quando possível

As CDNs permitem que o conteúdo seja armazenado em cache em servidores de borda localizados fisicamente mais perto dos visitantes, desde que o conteúdo seja configurado com os cabeçalhos HTTP Cache-Control adequados. Embora isso não seja apropriado para conteúdo personalizado, exigir uma viagem de volta até a origem pode anular grande parte do valor de uma CDN.

Para sites que atualizam o conteúdo com frequência, mesmo um curto tempo de armazenamento em cache pode resultar em ganhos de desempenho perceptíveis para sites ocupados, já que apenas o primeiro visitante durante esse tempo 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. Algumas CDNs permitem a invalidação de cache em versões de sites, o que permite o melhor dos dois mundos: longos tempos de cache, mas atualizações instantâneas quando necessário.

Mesmo quando o armazenamento em cache está configurado corretamente, isso pode ser ignorado com o uso de parâmetros de string de consulta exclusivos para medição de análises. Apesar de serem iguais, eles podem parecer conteúdos diferentes para a CDN. Por isso, 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 saiba que com o aumento dos tempos de armazenamento em cache, há uma possibilidade maior de veicular conteúdo possivelmente desatualizado.

O impacto do conteúdo armazenado em cache não afeta somente aqueles que usam CDNs. A infraestrutura do servidor pode precisar gerar conteúdo com base em pesquisas dispendiosas no banco de dados quando o conteúdo armazenado em cache não puder ser reutilizado. Dados acessados com mais frequência ou páginas pré-armazenadas em cache geralmente têm uma performance melhor.

Evite redirecionamentos múltiplos de página

Um fator comum de 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 certamente 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 impactar particularmente sites que recebem grandes volumes de visitantes de anúncios ou newsletters, já que eles geralmente redirecionam por meio de serviços de análise para fins de medição. Eliminar os redirecionamentos sob seu controle direto pode ajudar a alcançar um bom TTFB.

Existem dois tipos de redirecionamento:

  • Redirecionamentos de mesma origem, quando o redirecionamento ocorre inteiramente no seu site.
  • Redirecionamentos de origem cruzada, em que o redirecionamento ocorre inicialmente em outra origem, como um serviço de encurtamento de URL de mídias sociais, por exemplo, antes de chegar ao site.

Concentre-se em eliminar redirecionamentos de mesma origem, pois você terá controle direto sobre isso. Isso envolveria verificar os links no seu site para ver se algum deles resulta em um código de resposta 302 ou 301. Muitas vezes, isso pode ser resultado da não inclusão do esquema https:// (o padrão dos navegadores é http://, que, em seguida, redireciona) ou porque as barras finais não estão incluídas ou excluídas corretamente no URL.

Os redirecionamentos de origem cruzada são mais complicados, porque geralmente estão fora do seu controle, mas tente evitar vários redirecionamentos sempre que possível, por exemplo, usando 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.

Outra fonte importante do tempo de redirecionamento pode vir de redirecionamentos HTTP para HTTPS. Uma maneira de contornar isso é usar o cabeçalho Strict-Transport-Security (HSTS), que aplicará o HTTPS na primeira visita a uma origem e, em seguida, instruirá o navegador a acessar imediatamente a origem pelo esquema HTTPS em visitas futuras.

Depois de implementar uma boa política de HSTS, é possível acelerar o processo na primeira visita a uma origem adicionando seu site à lista de pré-carregamento de HSTS.

Marcação de stream para o navegador

Os navegadores são otimizados para processar marcações de forma eficiente quando ela é transmitida, o que significa que a marcação é tratada em partes assim que chega do servidor. Isso é crucial no caso de grandes payloads de marcação, já que significa que o navegador pode analisar os blocos de marcação incrementalmente, em vez de esperar que toda a resposta chegue antes que a análise possa começar.

Embora os navegadores sejam ótimos em lidar com marcação de streaming, é crucial fazer tudo o que puder para manter esse fluxo fluindo, para que os bits iniciais de marcação estejam a caminho o mais rápido possível. Se o back-end estiver segurando as coisas, isso é um problema. Como há muitas pilhas de back-end, não faz parte do escopo deste guia abordar todas as pilhas e os problemas que podem surgir em cada uma delas.

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

Outra forma de garantir que a marcação seja transmitida para o navegador rapidamente é contar com a renderização estática, que gera arquivos HTML durante o tempo de compilação. Com o arquivo completo disponível imediatamente, os servidores da Web podem começar a enviá-lo 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 de todos os sites, como aquelas que exigem uma resposta dinâmica como parte da experiência do usuário, ela pode ser útil para aquelas que não exigem que a marcação seja personalizada para um usuário específico.

Usar um service worker

A API Service Worker pode ter um grande impacto no TTFB tanto para documentos quanto para os recursos que eles carregam. O motivo é que um service worker atua como um proxy entre o navegador e o servidor, mas se há um impacto no TTFB do seu site depende de como você configurou o service worker e se essa configuração está alinhada com os requisitos do seu aplicativo.

  • Use uma estratégia de validação enquanto revalida para recursos. Se um recurso estiver no cache do service worker, seja um documento ou um recurso exigido pelo documento, a estratégia obsoleto-enquanto revalidará esse recurso do cache primeiro, depois fará o download desse recurso em segundo plano e o exibirá do cache para interações futuras.
    • Se você tem recursos de documentos que não mudam com muita frequência, usar uma estratégia obsoleto-enquanto revalida pode tornar o TTFB da página quase instantâneo. No entanto, isso não funciona muito bem se o site enviar marcações geradas dinamicamente, como marcações que mudam com base na autenticação do usuário. Nesses casos, é sempre recomendável acessar a rede primeiro, para que o documento fique o mais atualizado possível.
    • Se seu documento carregar recursos não críticos que mudam com alguma frequência, mas buscar o 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 para esses recursos pode ser bastante reduzido usando uma estratégia de revalidação obsoleta.
  • 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 a partir 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 essenciais de renderização

Não importa o quão bem o back-end do aplicativo seja otimizado, ainda pode haver uma quantidade significativa de trabalho que o servidor precisa fazer para preparar uma resposta, incluindo um trabalho caro (mas necessário) de banco de dados que atrasa a resposta de navegação de chegar o mais rápido possível. O efeito potencial disso é que alguns recursos críticos de renderização subsequentes podem sofrer atraso, 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 existem recursos críticos de renderização que a página deve iniciar por download enquanto a marcação é preparada. Para navegadores compatíveis, o efeito pode ser a renderização de documentos (CSS) mais rápida 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 encapsular tudo o que você pode fazer para reduzir o TTFB do seu site. No entanto, estas são algumas opções que você pode explorar para agilizar as coisas no lado do servidor.

Assim como na otimização de todas as métricas, a abordagem é muito semelhante: meça o TTFB no campo, use ferramentas de laboratório para detalhar as causas e aplique as otimizações sempre que possível. Nem todas as técnicas aqui podem ser viáveis para sua situação, mas algumas são. Como sempre, fique de olho nos dados de campo e faça os ajustes necessários para garantir a experiência do usuário mais rápida possível.

Imagem principal de Taylor Vick, extraída do Unsplash.