Andressa Costa

Server componentes e a minha dificuldade com acrônimos.

Se tu também se sentiu confusa, meio balançada, vagando pela cidade pensando em por que server components? por que tá todo mundo falando de server side rendering tal qual os antigos? vem comigo e vamos ficar confusas juntas.



8 minutes

Desde que a instituição React anunciou os server components, a confusão entre server components e server side rendering invadiram o meu SER. E digo confusão, pois fiquei ??? e no silêncio da noite, volta e meia me vinha a questão, mas já não existe suporte a SSR com React via Next (e outros) faz tempo?

Não é com orgulho, mas com honestidade, que afirmo que o meu modus operandi em situação de "novidade" na bolha frontend é respirar fundo e me inteirar do estritamente necessário, até que seja absolutamente, quiçá humanamente, impossível desviar da questão. O meu caminho para tentar entender server components e o problema que eles se propõem a resolver começou dando um passinho atrás e revisitando a fonte da minha confusão, o SSR (e outras estratégias de renderização, já que estou aqui).

Estratégias de renderização

Tanto CSR quanto SSR são estratégias de renderização. Quando falo de SSR quero dizer que a renderização inicial vai acontecer no servidor, e o servidor vai enviar para o navegador um arquivo HTML pronto.

Já, quando falo de CSR, o servidor envia um HTML vazio que vai ser responsável por disparar o download do bundle de JS, que por sua vez vai ser parseado e então o HTML vai estar pronto.

Existem prós e contras em ambas as estratégias. No SSR, é necessário esperar o servidor enviar um arquivo completo, muita coisa vai acontecer no servidor nessa primeira ida então o usuário pode ficar algum tempo encarando uma tela vazia, porém, uma vez que o HTML chegar ao navegador, a aplicação estará pronta para usar. A primeira renderização já vai apresentar o conteúdo que o usuário requisitou, o que é bom para o SEO e para as métricas de LCP e TTI que medem o tempo até que o usuário consiga fazer uso da aplicação.

Quando a renderização acontece no cliente o navegador vai ao servidor e busca o HTML que vai então disparar o download do bundle de JS necessário tanto para tornar a página interativa quanto para buscar os dados para popular a aplicação. O tempo para que a aplicação possa ser considerada "pronta" pode ser mais longa, porém, temos mais controle do que mostrar para o usuário enquanto as operações de download e parser acontecem.

CSR foi a estratégia de renderização predominante nos últimos anos e o padrão de mostrar um "esqueleto" inicial acompanhado de uma animação indicando que o carregamento ainda está acontecendo é super popular, por baixo dos panos o que rola é mais ou menos isso:

  1. o navegador receber o HTML inicial vazio
  2. começa a baixar o bundle de JS
  3. renderiza o "esqueleto" da aplicação (ou qualquer estratégia de carregamento) e então temos a métrica de FCP
  4. o JS começa a buscar os dados necessários para popular a aplicação
  5. o navegador renderiza o conteúdo que substitui o "esqueleto" da aplicação, a famigerada hidratação, e então temos as métricas de TTI e LCP

CSR e a hidratação

O processo de baixar e parsear o bundle de JS e tornar a aplicação dinâmica é chamado de hidratação. No SSR o JS já está disponível e parseado, então o trampo do navegador é mais de fazer o JS adotar os elementos HTML que serão interativos. No React a fase de hidratação acontece em duas etapas, primeiramente é feita uma renderização rápida que estabelece a forma da árvore de componentes e inicializa as instâncias dos componentes e cria os nodos no DOM, em seguida, a árvore é percorrida e a interatividade é adicionada (botões começam a ouvir eventos, refs são anexadas a elementos, entre outros).

Diferentes modalidades de SSR

A renderização no servidor pode ser, a princípio, sob demanda ou estática. Sob demanda, a mecânica é mais ou menos essa:

  1. o usuário visita uma página
  2. o servidor recebe a requisição
  3. o servidor gera o HTML inicial e envia para o navegador
  4. o navegador renderiza o HTML

Já no caso de renderizar um site estático, o processo de gerar o HTML acontece antes da requisição chegar ao servidor, durante o processo de build:

  1. o usuário visita uma página
  2. o servidor responde com o HTML, que já estava pronto
  3. o navegador renderiza o HTML

Aqui a operação é um pouco mais rápida, porque eliminamos a fase de gerar o HTML no servidor.

Analisando isoladamente, pode parecer que essa é a resposta para todos os problemas e traz o seu amor de volta em 7 dias, mas existem alguns pontos a levar em consideração:

  • Personalização: O HTML gerado na fase de compilação é o mesmo servido para todos os usuários, sendo assim, não tem como personalizar nada (a não ser que eu faça isso via JS, que vai ter de ser baixado e parseado depois da primeira renderização), em um blog isso provavelmente não é um problema, tanto que muitas ferramentos para gerar site estático visam justamente os blogs, mas em uma aplicação onde usuários podem logar talvez não faça tanto sentido apostar num site estático.
  • Páginas desatualizadas: Como as páginas são geradas apenas quando o site é compilado, pode ser que certos conteúdos fiquem desatualizados, por exemplo, pensando em uma funcionalidade de artigos mais lidos no site de uma revista, como vou ter certeza que o número de visualização está correto se só vou atualizá-lo quando o site for compilado de novo?
  • Tempo de build: Se eu estiver construindo uma aplicação para uma loja que possui milhares de itens e eu preciso gerar uma página para cada item, o tempo de build vai ser muito longo, pra situações assim faz muito mais sentido usar a renderização sob demanda

Além da renderização sob demanda e da estática, existe ainda a incremental, introduzida pelo next, a renderização incremental é um mix entre a estática e a sob demanda. Na primeira vez que uma página for solicitada, o servidor vai gerar o HTML e enviar para o usuário, o diferencial é que o servidor vai segurar esse HTML gerado e a próxima vez que ele for solicitado o Next vai servir o HTML pronto, como acontece na renderização estática. Para evitar que o servidor sirva um HTML desatualizado, o Next adiciona uma fase de "revalidação" que acontece na primeira ida ao servidor e pode ditar se o HTML precisa ser gerado novamente ou não.

Voltando aos server components

Fechando essa grande digressão, SSR é uma parada que existe há muito tempo, mesmo no ecossistema do React, e é uma estratégia que disponibiliza a aplicação para o usuário na primeira renderização, antes do JS ser carregado e parseado.

Server components é outra formiga.

Server componentes é sobre pré-renderizar componentes no servidor, de forma com que esse componente não seja incluído no bundle de JS. Server components não tem acesso às APIs do navegador, mas tem acesso ao servidor e é aí o pulo do gato, posso fazer fetch de dados diretamente no componente! server components podem importar client components (que são apenas componentes "normais", renderizados como de costume, no cliente), então existe agora um controle granular e intencional do que precisa de JS no cliente. Se na aplicação em questão apenas um botão é interativo, o resto todo pode vir pré-renderizado do servidor e o único JS que precisa ser baixado, parseado e renderizado, é o do botão.

Alguns frameworks já tinham gambiarras para oferecer algo similar há algum tempo, mas, de modo geral, era necessário pelo menos uma ida ao servidor para buscar o bundle de JS, parsear, e então fazer uma nova ida ao servidor para buscar os dados, a requisição acontecia no cliente.

Um server component roda exclusivamente no servidor e por isso podemos fazer operações assíncronas e introduzir side effects sem a preocupação com re-render, o re-render nunca vai acontecer porque o componente gerado no servidor não vai mudar no cliente.

Server components e Server Side Rendering

Então, a pré-renderização que os Server components fazem consiste em descrever o componente em um formato que o React vai se encarregar de transformar em HTML, essa transformação pode acontecer no servidor ou no cliente. Ou seja, server components funcionam muito bem com SSR, mas eles podem existir em um contexto sem SSR.

Eu acho uma baita sacada que todo componente, por padrão, é considerado um server component. Se eu quiser um component client preciso adicionar a diretiva use client no topo do arquivo, isso faz com que eu reflita muito mais sobre a maneira como estou arquitetando meus componentes e o que realmente quero mandar pro meu bundle de JS.

Um porém muito grande é que Server Components, por enquanto, são apenas suportados pelo Next. É uma questão de tempo para que outros frameworks se adaptem, mas não deixa de ser estranho ver uma tecnologia tão utilizada, como o React, estar tão atrelada a um único framework, torna a linha de separação entre o que é React e o que é Next bem nebulosa, mas é isso que o sistema oferece.


Posts relacionados


Início