Voltamos a renderizar html no servidor
Um pouco da nossa experiência com websites e frameworks javascript e o caminho que nos levou até "voltar" a renderizar html's do lado do servidor.
Com o crescimento dos frameworks JavaScript e a tendência em criar aplicações com o mínimo de processamento possível, programadores e arquitetos passaram a adotar o padrão SPA, renderizados no lado do cliente, para desenvolvimento de aplicações web.
Neste artigo, contaremos a nossa jornada e explicaremos o porquê votamos a processar e renderizar as páginas HTML no lado do servidor. Mostraremos o embasamento de nossas decisões e o porquê escolhemos o NextJS como framework de desenvolvimento para nosso site.
Acompanhe nosso artigo e descubra os resultados e impactos dessa mudança.
Uma breve história do next.me
O ano é 2017 e a versão 1.0 do website next.me foi lançada como uma SPA (com renderização no lado do cliente), com as melhores tecnologias do mercado (da época), ReactJS e webpack.
“uma ‘Single-page application’ (aplicação de uma página) é uma implementação de aplicativo web que carrega apenas um único documento e então, o corpo da página é atualizado via API’s JavaScript...Então assim, permite o usuário a usar um website sem ter que carregar uma página completa do servidor, o que pode resultar em ganho de performance e uma experiência mais dinâmica, com algumas desvantagens em troca como SEO, maior esforço de manutenção, a implementação de navegação e um trabalho considerável para monitorar a performance”.@moozila SPA (Single-page application)-
Uma SPA com carregamento em “client side”, funciona da seguinte forma:


Com isso, sites de busca, também não indexavam nosso conteúdo.

next.me 2.0
Em 2020 com novas campanhas, o next decidiu remodelar seu site. Como não aproveitar e também atualizar as tecnologias, buscando melhorar a performance para SEO e campanhas?
Mas, como desenvolver e hospedar websites modernos, utilizando ReactJS e entrega-lo de maneira eficiente e acessível para usuários e mecanismos de busca?
A preparação.
Montamos um time, imprimimos e colamos todas as páginas da nova versão do site na parede da sala de reuniões.
Compramos uma garrafa térmica de 2 litros e nos trancamos por duas semanas para estudar, tanto os componentes de design (que futuramente originariam o @nextweb/ui-kit), quanto compreender os problemas da versão 1 que deveríamos evitar a todo o custo.
Entre cafés e pães-de-queijo, testamos frameworks, recursos de cloud, estudamos os “Core Web Vitals”, fizemos POC’s, POC’s e mais POC’s, até que compreendemos os requisitos técnicos iniciais para estruturarmos a arquitetura do projeto.

Os requisitos técnicos
Ser Mobile First.
[PORCENTAGEM DE CLIENTES QUE USAM MOBILE] do nosso público utilizam dispositivos mobile para navegação na internet. Com isso, o site precisa ser otimizado para ser leve, rápido e com um excelente design para dispositivos mobile.
First Meaningful Paint (atual FCP)
As páginas do site deverão mostrar o conteúdo instantaneamente, sem ter que esperar ou depender de javascript.
Conteúdo dinâmico.
O site deve ser plugado em um CMS e precisa ser atualizado em “tempo real”.
Tem que funcionar no I.E.
Imprevistos acontecem [EMOJI DE OLHO].
Imagens Otimizadas
Imagens e vídeos são artefatos críticos para uma página ter uma boa performance
Segundo o “Core Web Vitals”, as imagens precisam ser servidas no tamanho correto, com a compressão correta e de maneira otimizada para cada dispositivo.
Os problemas da v1
Vamos estudar o comportamento de uma SPA dentro do site next.me 1.0, utilizando a linha de tempo de renderização do “profiler” do Lighthouse.
Na imagem abaixo temos os primeiros dez segundos de renderização da página home. Não se preocupe com o excesso de informação, mais abaixo analisaremos este relatório com você.

O que são estas linhas e o que elas representam no ciclo de vida de renderização de um site?

Em vermelho (ou salmão), temos a linha da rede. Nela está sendo exibido o tempo que o navegador levou para baixar algum arquivo (js, html, css, imagens, etc).
Em verde, temos a linha de pintura de tela. Nela, podemos visualizar o que está sendo mostrado na tela do usuário.
Em amarelo, temos a linha de algumas das principais métricas de performance para a web (vamos falar sobre isso já já).
Aqui estão alguns dos principais eventos da linha do tempo.

Ou seja, em média (com dados de laboratório) um usuário levava 7.6 segundos para visualizar o primeiro frame de nosso site (o FCP).
Segundo o time do Google:
“Para fornecer uma boa experiência ao usuário, os sites devem se esforçar para ter uma First Contentful Paint de 1,8 segundos ou menos.”--
Ou seja, o comportamento padrão de uma SPA (renderizada no lado do cliente) dificulta muito a pintura e entrega do primeiro frame.
O tamanho do bundle
Outro grande problema de uma SPA, é o tamanho do arquivo inicial do aplicativo.
Hoje é muito fácil utilizar técnicas de code-spliting (separar os códigos em multiplos bundles) e lazy loading (carregar budles por prioridade) porém, o comportamento padrão de uma SPA é colocar todo o código do seu site em um único arquivo.

O arquivo inicial (o maior quadrado em rosa, bundle.js) para montar o site é de 7.0MB o que, num ambiente com simulação de conexão 4g (em laboratório) levou 4.77 segundos.
O plano (JamStack)
Durante os estudos de novas ferramentas e padrões do mercado, encontramos o nextjs e a Jamstack.
O que é a JamStack?
Esta arquitetura de projetos surgiu com a necessidade de modernizar e otimizar as aplicações SPA, tornando-as mais acessíveis e performáticas.
A ideia central é de que, além de possuir uma CDN para tornar a distribuição de conteúdo mais rápida, o conteúdo precisa ser pré-renderizado no lado do servidor, sendo entregue ao usuário o HTML já “pintado”.
Ela pode trazer todos os benefícios de uma SPA, somados aos benefícios de devolver um html já montado para o client.
Você pode saber mais sobre esse padrão de arquitetura aqui.
Os princípios desta arquitetura são:
- JavascriptPor ser uma linguagem extensível, poderosa e dinâmica, o JavaScript permite (com ressalvas) que algoritmo rode tanto no lado do cliente (navegador) quanto no lado do servidor (com NodeJS e Deno).
- Por ser uma linguagem extensível, poderosa e dinâmica, o JavaScript permite (com ressalvas) que algoritmo rode tanto no lado do cliente (navegador) quanto no lado do servidor (com NodeJS e Deno).
- Pré renderingPara entregar o conteúdo de maneira otimizada para navegadores e buscadores, o arquivo HTML precisa ser entregue pré-renderizado, evitando assim a dependência direta de arquivos javascript para mostrar o conteúdo de uma página.
- Para entregar o conteúdo de maneira otimizada para navegadores e buscadores, o arquivo HTML precisa ser entregue pré-renderizado, evitando assim a dependência direta de arquivos javascript para mostrar o conteúdo de uma página.
Veja como funciona:

Em algumas sessões, mostraremos como isso funcionou no mundo real.
- CDNPara entrega de conteúdo de maneira eficiente e distribuída, será necessário servir o site através de uma CDN.
- Para entrega de conteúdo de maneira eficiente e distribuída, será necessário servir o site através de uma CDN.
Segundo a @akamai, no artigo "O que é uma CDN?" (akamai.com)
“Uma CDN (Rede de Entrega de Conteúdo) é um grupo de servidores geograficamente distribuídos que aceleram a entrega do conteúdo da Web, aproximando-o de onde os usuários estão. “
- Micro Serviços
A Execução
A evolução da infraestrutura.
Em 2020 o next iniciou a migração para a cloud da Azure, e uma das premissas iniciais (quanto ao site), foi levar o ambiente equivalente “on-premises” e colocá-lo em num cluster na cloud.

- Na imagem, em vermelho, temos a infraestrutura “atual” (no momento de criação) do site, a qual deverá hospedar o site nos primeiros deploys. Usuários e buscadores solicitariam a um servidor apache os arquivos que foram atualizados com a ferramenta de CI & CD Bamboo, buscado o conteúdo do StaffChannel (que seria alimentado pelo marketing.
- Em azul, temos o novo modelo de infraestrutura, aonde o cliente e os buscadores solicitam há um Cache (uma CDN) os conteúdos, indexados e cacheados de um servidor NodeJS, que por si, atualiza seu próprio conteúdo em um tempo pré-agendado, buscando-o seus dados através de um API middleware.
O resultado
Vamos fazer a mesma analise que fizemos na versão 1.
Na imagem abaixo, temos os primeiros dez segundos de renderização do novo site com os principais eventos.

Nosso tempo de pintura reduziu 844% o tempo de primeira pintura (FCP)
O tempo de primeira pintura passou de 7.6 para 0.9 segundos. Uma melhora considerável para os indicadores de performance.
Antes

Na imagem, o tempo de carregamento médio era 7.6 segundos
Depois

Com renderização no lado do servidor, o tempo de carregamento passou para 0.9 segundos.
Buscadores passaram a gostar de nossas páginas
Por exemplo, com nossa página de mimos, passamos a ser o primeiro resultado orgânico.

Buscando por "renda fixa", junto de "banco next", nossa página de investimentos e nosso post de blog também passaram a ser o primeiro resultado orgânico

Nossos arquivos Javascript ficaram menores.

Somando o peso de todos arquivos da aplicação (ignorando arquivos de analytics), nosso bundle ficou com ~830kb (0.8MB).
Isso ocorre porque o NextJs cria um build individual e otimizado para cada página, contendo apenas o javascript necessário para cada uma delas renderizar.