O que é a hydration? O passo que torna interativo o HTML renderizado no servidor

  • vuetelemetry
  • Guias
  • 7 min de leitura

O HTML renderizado no servidor fica inerte até a hydration lhe ligar o Vue. O que a hydration faz, porque é preciso createSSRApp, as três causas documentadas de um mismatch de hydration e porque um mismatch é um imposto silencioso sobre o desempenho e não uma falha.

A renderização no servidor entrega HTML já completo antes de correr qualquer JavaScript, e é por isso que ajuda a primeira pintura e os rastreadores. Mas esse HTML é inerte. A própria documentação do Vue diz-o sem rodeios: se clicar no botão, o número não muda, porque a página fica estática até o framework assumir o comando no navegador. A hydration é precisamente essa passagem de testemunho.

O Vue descreve o mecanismo com precisão. Durante a hydration cria a mesma aplicação Vue que correu no servidor, associa cada componente aos nós do DOM que deve controlar e liga os ouvintes de eventos do DOM. Quando corre bem, nada é reconstruído de raiz: a marcação já lá está e a hydration apropria-se dela.

É preciso pedi-la explicitamente, não acontece sozinha. Montar no cliente uma aplicação renderizada no servidor exige createSSRApp e não createApp, porque é isso que diz ao Vue que o HTML foi pré-renderizado e que deve hidratá-lo em vez de montar novos nós DOM. Escolher a função errada é uma forma comum de renderizar tudo duas vezes sem dar por isso.

Quando as duas versoes divergem

Painel do inspetor de um navegador a mostrar uma árvore DOM de elementos div e header aninhados. Um mismatch de hydration é um desacordo entre esta árvore e aquilo que a aplicação do lado do cliente espera.
Painel do inspetor de um navegador a mostrar uma árvore DOM de elementos div e header aninhados. Um mismatch de hydration é um desacordo entre esta árvore e aquilo que a aplicação do lado do cliente espera.

Tudo isto pressupõe que a saída do servidor e a expectativa do cliente coincidem. Quando não coincidem, surge um mismatch de hydration, que o Vue define como a estrutura DOM do HTML pré-renderizado não corresponder à saída esperada pela aplicação do lado do cliente.

A documentação aponta três causas, e nenhuma delas é exótica.

As tres causas documentadas

A primeira é o aninhamento HTML inválido. Se um template coloca um div dentro de um p, o próprio analisador do navegador corrige a estrutura enquanto lê o HTML do servidor, e o DOM já corrigido deixa de corresponder ao que o cliente espera. O framework não fez nada de errado: foi o navegador que reescreveu a página antes de o Vue sequer a ver.

  • A hydration recria no navegador a aplicação executada no servidor, associa os componentes aos nós DOM existentes e liga os ouvintes de eventos.
  • Exige createSSRApp em vez de createApp, o que diz ao Vue para hidratar em vez de montar nós novos.
  • Um mismatch de hydration é quando o DOM pré-renderizado não corresponde ao que a aplicação do lado do cliente espera.
  • O Vue aponta três causas: aninhamento HTML inválido corrigido pelo analisador do navegador, valores gerados aleatoriamente e fusos horários diferentes entre servidor e cliente.
  • O Vue recupera automaticamente e a aplicação continua a funcionar, mas os nós descartados e remontados custam desempenho de renderização.

A segunda são os valores gerados aleatoriamente. A mesma aplicação corre duas vezes, uma no servidor e outra no navegador, e nada garante que um valor aleatório seja idêntico entre essas duas execuções. Tudo o que for sorteado no momento da renderização acabará por divergir.

A terceira são os fusos horários. Quando o servidor e o cliente estão em fusos diferentes, uma data formatada durante a execução no servidor e essa mesma data formatada no navegador não vão coincidir. É a causa que sobrevive mais tempo em produção, porque só aparece para os utilizadores que estão no sítio errado.

Porque e um custo silencioso

O que acontece a seguir explica porque este bug é tão fácil de ignorar. O Vue tenta recuperar automaticamente e ajusta o DOM pré-renderizado ao estado do cliente, pelo que a aplicação em geral continua a funcionar. O preço é uma perda de desempenho de renderização, porque os nós incorretos são descartados e no lugar deles são montados novos.

Um mismatch é, portanto, raramente uma falha total. É um imposto silencioso: o servidor produziu HTML e depois parte desse trabalho foi deitada fora e refeita no navegador. Pagou a renderização no servidor duas vezes e ficou com o benefício uma só. É exatamente o tipo de regressão que um teste funcional nunca apanha, porque a página continua a parecer correta.

Um mismatch é, portanto, raramente uma falha total. É um imposto silencioso: o servidor produziu HTML e depois parte desse trabalho foi deitada fora e refeita no navegador. Pagou a renderização no servidor duas vezes e ficou com o benefício uma só. É exatamente o tipo de regressão que um teste funcional nunca apanha, porque a página continua a parecer correta.

- vuetelemetry

A resposta mais simples para paginas estaticas

Se os dados necessários para renderizar uma página são os mesmos para todos os utilizadores, o Vue aponta para uma resposta mais simples do que renderizar a cada pedido: a geração de sites estáticos, também chamada pré-renderização, em que a página é renderizada uma única vez durante a build. A hydration continua a aplicar-se ao resultado, mas o custo de servidor por pedido desaparece. Antes de otimizar uma pipeline de SSR, vale a pena perguntar se a página precisava mesmo de ser dinâmica.

Stack relacionado