Back home

Pontos-chave na escolha de SSR, CSR e renderização de streaming

Quantas vezes os mesmos dados serão recuperados, em que nível eles serão cobertos e quem irá interrompê-los após a ocorrência de um erro. Determine se a solução front-end será escrita de maneira confusa antes de "quanto mais rápida é a primeira tela?"

Muitas equipes discutem SSR, CSR e renderização de streaming, e a primeira coisa que perguntam é sobre desempenho.

Quanto tempo dura o primeiro tempo de tela, o LCP pode ser suprimido, o SEO pode ajudar, as interfaces podem ser paralelizadas e o streaming pode ser esqueletizado mais cedo. É claro que isso é importante, mas quando se trata de projetos, a primeira coisa que atrapalha a página é quantas vezes os mesmos dados foram buscados, em quais camadas eles estão armazenados em cache e quem irá fechá-los após uma falha.

Meu julgamento é: **A chave para a estratégia de renderização de front-end não é quem é mais avançado, SSR, CSR ou renderização de streaming, mas que os mesmos dados da página precisam passar por vários momentos de busca, vários tempos de hidratação e vários conjuntos de reversões de falha. Depois que uma página busca SEO, velocidade de interação e acessos ao cache ao mesmo tempo, as primeiras coisas que ficam fora de controle geralmente são a consistência dos dados, a cobertura de erros e os custos de solução de problemas. **

O que realmente atrapalha a página geralmente não é o método de renderização em si.

Já vi muitas páginas e, no início, era apenas uma página de detalhes de conteúdo muito comum:

  • Clique na página da lista para obter detalhes;
  • Esperamos que os motores de busca consigam rastrear a primeira tela, por isso precisamos de SSR;
  • Existem interações como cobranças, comentários e recomendações na página, então o cliente tem que continuar fazendo solicitações;
  • Para agilizar a primeira tela, a interface é dividida em dados principais e blocos secundários;
  • Para melhorar a taxa de acertos, o servidor adiciona cache de borda e o cliente adiciona uma camada de cache de solicitação.

Até este ponto, toda decisão pode ser justificada.

O problema é que depois que essas decisões são empilhadas, existem pelo menos quatro caminhos para “os dados chegarem ao local” na página:

  1. Os dados obtidos durante a primeira renderização do servidor;
  2. Os dados baixados quando o navegador é hidratado;
  3. Após a montagem do cliente, ele reenvia a solicitação para obtenção dos novos dados;
  4. Dados derivados que são atualizados localmente após interação do usuário.

Se não houver uma prioridade clara entre esses quatro caminhos, a página começará a ter alguns problemas estranhos e familiares:

  • O que você vê em HTML é o preço antigo, e ele irá piscar para o novo preço após a hidratação;
  • A primeira renderização da tela mostra “Favorito”, mas após o cliente assumir o controle, volta para “Não Favorito”;
  • O bloco recomendado está um passo atrasado e a página atualizada é parcialmente retornada ao valor antigo;
  • Quando o servidor reportava um erro, ele mostrava um conjunto de detalhes e, depois que o cliente tentava novamente, exibia outro conjunto de detalhes.

Esses problemas são causados ​​pelo fato de que o mesmo status de página é gerado e sobrescrito diversas vezes, mas ninguém define quem tem a palavra final.

SSR resolve a visibilidade da primeira tela, mas não resolve automaticamente a fonte da verdade dos dados.

Uma situação comum é pensar em SSR como “cuspir primeiro a página correta”, mas esta frase só é verdadeira sob uma premissa muito restrita: **Os dados obtidos pelo servidor são os dados finais que o usuário realmente deveria ver desta vez. **

Na realidade, esta premissa muitas vezes não é verdadeira.

Por exemplo, as informações do produto na tela inicial da página de detalhes são renderizadas pelo servidor, mas as seguintes informações geralmente não são:

  • Se o usuário clicou nos favoritos;
  • Qual conjunto de recomendações é atualmente atingido pelo balde experimental;
  • Inventário geograficamente relevante;
  • Preços ou direitos relacionados com login;
  • Atualizações assíncronas concluídas logo após a montagem da página.

Neste momento, o SSR só pode garantir que “primeiro cuspa uma versão para exibir os resultados”, mas não pode garantir que esta versão dos resultados será a verdade final de toda a página.

Uma vez que a equipe também exige que “o servidor produza primeiro o HTML, e o cliente assuma e depois adicione a personalização”, o sistema se dividirá naturalmente em dois conjuntos de julgamentos:

  • O servidor determina primeiro como a página deve ficar;
  • O cliente determina a aparência que a página deverá ter.

Se as condições de acesso, o tempo de armazenamento em cache e as estratégias de tolerância a falhas de ambos os lados não forem completamente consistentes, a página será definitivamente inconsistente.

Então, o que o SSR realmente deveria perguntar é:

  • Por quanto tempo os dados gerados pelo servidor podem ser mantidos atualizados desta vez;
  • Quais campos podem ser percorridos após a hidratação;
  • Quais campos devem ser baseados nos últimos resultados do cliente;
  • As falhas do lado do servidor e as falhas do lado do cliente têm o mesmo conjunto de semântica?

Sem esclarecer primeiro estas questões, o SSR apenas enviará uma determinada versão da resposta ao utilizador num momento anterior, em vez de resolver a consistência a um nível superior.

O verdadeiro problema com CSR é que é fácil escrever a semântica de atualização de maneira vaga

A RSE é frequentemente criticada por ser lenta acima da dobra, e com razão. Mas meu problema mais comum é que os projetos de CSR tendem a escrever “re-extrair os dados novamente” como uma ação padrão irrestrita.

A página é inicializada e puxada uma vez; Corte a aba e puxe uma vez; Puxe o foco da janela novamente; Depois que a operação do usuário for bem-sucedida, puxe-a novamente com facilidade; A biblioteca de solicitações tenta novamente automaticamente.

O código parece natural, mas o efeito final pode ser:

  • O status da página é sobrescrito diversas vezes em um curto período de tempo;
  • A solicitação antiga retornada posteriormente substituirá a nova solicitação retornada primeiro;
  • A atualização otimista acabou de entrar em vigor e foi adiada por uma nova busca completa;
  • Um determinado componente local é atualizado separadamente e o status no nível da página é remontado em outra versão do resultado.

Esse tipo de problema é particularmente comum em RSE, porque o cliente naturalmente considera “extrair os dados mais recentes novamente agora” como uma ação de baixo custo. Mas contanto que uma página tenha uma lista, um resumo e feedback interativo, refetch é um ato de reavaliar o status da página inteira.

Se não houver regras claras, a RSE acabará por se tornar: não importa quem obtém os dados primeiro, quem tem a palavra final, quem obtém os dados com sucesso no final.

Claro, a página está instável neste momento. Tem menos a ver com o CSR em si e mais com a abertura muito ampla do caminho de gravação.

O custo mais facilmente subestimado da renderização de streaming é o custo da interpretação do estado causado pela “chegada do lote”

A renderização de streaming nos últimos dois anos pode ser facilmente considerada um benefício líquido:

  • O esqueleto chega mais cedo;
  • O conteúdo principal sai primeiro;
  • Não importa se o bloco secundário é posterior;
  • A experiência do usuário será mais tranquila.

Tudo isso é verdade. Mas tem um preço que raramente é considerado seriamente nas revisões do plano: a página ** não tem mais apenas dois estados: “chegou” ou “não chegou”, mas tem vários blocos chegando em lotes, erros em lotes e reversões em lotes. **

Uma vez que a página é dividida em fragmentos assíncronos, como conteúdo principal, comentários, recomendações, espaços publicitários e camadas flutuantes personalizadas, não é apenas o desempenho que precisa ser tratado, mas as seguintes questões de engenharia:

  • Se a versão dos dados mestres da qual depende um determinado bloco de chegada tardia e a versão da primeira tela são iguais;
  • Quando o bloco principal é bem-sucedido e o bloco secundário falha, se a página inteira ainda pode ser considerada bem-sucedida;
  • Se o conteúdo já produzido no fluxo pode ser anulado por fragmentos subsequentes;
  • O usuário já iniciou a operação após a chegada do primeiro fragmento da página. Os fragmentos subsequentes substituirão os resultados da interação.

Este custo não é abstrato. Eu vi uma página que fornece SSRs das informações principais e adiciona recomendações relacionadas e direitos de usuário em formato de streaming. Acontece que o bug mais difícil de solucionar online é “a cópia de direitos vista por alguns usuários será trocada duas vezes em dois segundos”.

Finalmente verificado, é:

  • O primeiro segmento do servidor utiliza o antigo equity snapshot no cache público;
  • Os segmentos de streaming subsequentes usam uma nova interface com modo de usuário;
  • Após a hidratação do cliente, os campos de exibição são recalculados com base no status do login local.

Todos os três conjuntos de fontes fazem sentido, mas quando reunidos, a página não parece um sistema.

O que deve ser desenhado primeiro é a linha de dados principal da página.

No final da discussão sobre estratégias de renderização, fiquei cada vez mais preocupado se a página tinha uma linha principal de dados clara.

A chamada linha principal de dados serve para determinar antecipadamente o seguinte:

1. Quais dados são a linha de base da primeira tela?

Quando a primeira tela HTML for exibida, quais campos já podem ser considerados valores verdadeiros exibíveis e quais são apenas resultados de espaço reservado devem ser claramente indicados.

Por exemplo:

  • O texto do artigo pode ser baseado em resultados de SSR;
  • O status like do usuário só pode ser determinado pela solicitação de status de login do cliente;
  • O bloco recomendado é declarado desde o início como “conclusão assíncrona, não participa do valor verdadeiro da primeira tela”.

Enquanto esta camada não for definida, cada ronda subsequente de pedidos competirá com a ronda anterior pelos direitos de interpretação.

2. Quais campos podem ser substituídos e quais campos só podem ser preenchidos de forma incremental?

Muitas páginas são escritas desordenadas porque todos os dados que chegam posteriormente são padronizados como “os mais recentes e mais confiáveis”. Na verdade.

Alguns campos são adequados para cobertura, como estoque, preço e número de pessoas online; Alguns campos só podem ser preenchidos, como paginação de comentários e lista de recomendações; Alguns campos devem ser substituídos com julgamento de versão, como o status da coleção que o usuário acabou de operar.

Se não houver regras de substituição em nível de campo, quanto mais solicitações subsequentes houver, maior será a probabilidade de o valor antigo substituir o novo valor.

3. A falha do lado do servidor e a falha do lado do cliente têm a mesma semântica?

Isto é facilmente esquecido.

Em alguns sistemas, quando a solicitação do servidor falha, ele será rebaixado diretamente para o módulo padrão; quando o cliente falha, um botão independente de nova tentativa de erro é exibido. O resultado que o usuário vê é:

  • Ao atualizar a página, esse conteúdo desaparece silenciosamente;
  • Depois que a página é montada, esse conteúdo aparece repentinamente em estado de erro.

Isso ocorre porque o sistema não possui uma explicação unificada para “falha”.

No mesmo bloco, se a semântica de falha do servidor e do cliente for diferente, será difícil responder na solução de problemas: isso é um downgrade normal ou uma exibição anormal?

Um mal-entendido comum: considerar “extrair os dados mais recentes mais uma vez” como uma garantia

Quando muitas equipes encontram problemas de consistência, sua primeira reação é “então o cliente extrairá os dados mais recentes novamente”.

Esse truque costuma ser eficaz no curto prazo porque atualiza alguns dos dados antigos do SSR. Mas, a longo prazo, pode facilmente aumentar o problema de “a primeira tela às vezes é um pouco antiga” para “a página inteira está competindo pelos direitos de interpretação final”.

O link com falha mais típico é este:

  1. O servidor primeiro pega os dados da versão A e renderiza a primeira tela;
  2. Após a montagem do navegador, o cliente extrai automaticamente a versão B;
  3. O usuário clicou imediatamente na coleção e a atualização otimista local mudou para C;
  4. A versão B solicita um retorno tardio e empurra C de volta;
  5. Retorne à interface da coleção e a página voltará para D.

Tecnicamente, cada passo está “certo”.

Mas para os usuários, a página mudou as respostas quatro vezes em três segundos. Neste ponto, é difícil dizer se o cerne do problema é SSR ou CSR, porque o verdadeiro problema é: **A página não especifica qual prioridade deve ser dada à escrita interativa ou à atualização completa. **

Contraexemplo: Nem todas as páginas são dignas de SSR ou streaming

Há também um mal-entendido muito real, que é considerar a estratégia de renderização como uma lista de capacidades da plataforma.

Se a estrutura apoiar a SSR, tende a ser uma SSR em todo o local; Apoie a renderização de streaming e comece a remover blocos; Se você está preocupado com SEO, use o lado do servidor para todas as páginas de detalhes por padrão; Se você está preocupado com a lentidão, adicione outra camada de cache do cliente.

Finalmente, os custos de interpretação do sistema dispararam.

Algumas páginas simplesmente não valem estratégias de renderização complexas:

  • Páginas de back-end com forte status de login, forte personalização e baixo valor do mecanismo de pesquisa;
  • Uma página de transação cujos dados em tempo real são muito superiores ao valor de uma primeira tela estática;
  • Uma página de operação com pouco conteúdo na primeira tela mas muitas interações.

Se o SSR for instalado nessas páginas e, em seguida, a extração suplementar e o streaming parcial do lado do cliente forem adicionados, os benefícios geralmente não são tão bons quanto escrever os dados sob o CSR honestamente.

Pelo contrário, páginas de detalhes baseadas em conteúdo, páginas de destino públicas e páginas de informações com uma estrutura estável são mais adequadas para aproveitar ao máximo o SSR ou as receitas de streaming. A premissa ainda é se os limites dos dados da página podem ser claramente separados**.

Para escolher um método, observe três coisas primeiro

Se você realmente deseja fazer um julgamento entre SSR, CSR e renderização de streaming, recomendo ler essas três coisas primeiro, em vez de ler primeiro a página promocional da estrutura.

Primeiro, verifique se o conteúdo da primeira tela tem um valor verdadeiro estável.

Se a maior parte do conteúdo da primeira tela puder ser obtida no lado do servidor e a diferença no modo do usuário for pequena, o SSR será mais estável.

Se a primeira tela depender muito do estado de login, do dispositivo e do estado em tempo real, e o servidor obtiver apenas um valor aproximado que expira rapidamente, a receita de SSR será descontada porque o cliente em breve terá que recalculá-la novamente.

Segundo, verifique se a página permite explicação em lote

Se a página puder ser acessada naturalmente em blocos, como texto primeiro, comentários por último e recomendações por último, a renderização de streaming será mais valiosa.

Se vários blocos na página compartilharem uma grande quantidade de estado, e a chegada tardia de um anulará os dois anteriores, a renderização de streaming não só trará otimização de desempenho, mas também custos de coordenação de estado.

Terceiro, veja se a escrita interativa entrará em conflito com o caminho de atualização.

Enquanto houver ações como coleções, carrinhos de compras, formulários e troca de permissão na página que mudarão o status imediatamente, é necessário focar se o caminho de escrita interativo e o caminho de atualização da página se cobrirão.

Este assunto não é fixo, não importa qual estratégia de renderização você escolha, apenas cometerá erros de outra forma.

Limites aplicáveis

Este artigo discute principalmente:- Buscar simultaneamente SEO, velocidade acima da dobra e páginas web personalizadas;

  • A mesma página possui primeira renderização do lado do servidor, renderização suplementar do lado do cliente e blocos assíncronos locais;
  • Problemas de hidratação, cache e montagem de streaming que são encontrados naturalmente ao usar estruturas front-end modernas.

Se a página for muito simples, seja pura exibição de conteúdo ou pura operação em segundo plano, a complexidade da estratégia de renderização não será tão alta. O problema com maior probabilidade de surgir é a página que “parece apenas uma página de detalhes, mas na verdade transporta distribuição de conteúdo, conversão de negócios e interação do usuário ao mesmo tempo”.

Resumo

SSR, CSR e renderização de streaming não estão errados. O que está errado é considerá-los como puros interruptores de desempenho.

Uma vez que uma página tem requisitos de primeira tela, requisitos de cache e requisitos de interação ao mesmo tempo, o que realmente fica fora de controle primeiro é qual versão dos dados é contada, quem será responsável pela falha e quem terá prioridade na escrita interativa e nos caminhos de atualização.

Portanto, o que a estratégia de renderização de front-end deve realmente determinar primeiro é quantas vezes esta página de dados será gerada, quantas vezes ela será sobrescrita, quantas vezes ela não retornará e qual camada irá finalmente fechá-la.

Este assunto não está claro. Quanto mais avançado o esquema de renderização, mais parece que a página é escrita por muitos conjuntos de mecanismos razoáveis ​​ao mesmo tempo.