O que eu gostaria de ter sabido antes de migrar 50 mil linhas de código para React Server Components
(mux.com)- A Mux migrou mux.com e docs.mux.com para React Server Components e constatou que separar a fronteira entre execução no servidor e no cliente afeta diretamente o tamanho do bundle e o custo de hydration
- RSC permite que componentes busquem dados diretamente no servidor e façam streaming do resultado, de modo que partes da tela possam aparecer primeiro mesmo com chamadas de dados lentas
- Os maiores obstáculos na migração real foram a falta de suporte a CSS-in-JS, as restrições de React Context em Server Components e a complexidade de rastrear continuamente as fronteiras entre servidor e cliente
- No app directory do Next.js 13, o padrão é Server Component, e é possível uma adoção gradual descendo
use clientaos poucos a partir da raiz - Padrões como Suspense,
loading.js, manter bibliotecas apenas no servidor e usarserver-onlydevem ser aplicados com cuidado só onde houver ganho de performance necessário, levando em conta também o custo cognitivo da equipe
O escopo da migração da Mux para RSC
- A Mux, ao reestruturar o site de documentação e fazer um rebranding, migrou mux.com e docs.mux.com para Server Components
- React Server Components podem ser aplicáveis e valer a pena também em codebases reais, mas vêm acompanhados de restrições e complexidade
- Esta experiência foi organizada em torno de por que RSC é necessário, onde ele se encaixa bem, em que situações é complicado e como introduzi-lo gradualmente em uma codebase real
O problema que o RSC busca resolver após CSR e SSR/SSG
- As abordagens iniciais de renderização no servidor, com tecnologias como PHP, buscavam dados no servidor e executavam trabalhos pesados de CPU antes de enviar HTML leve ao cliente
- CSR/SPA passou a enviar o código de renderização em JavaScript para o cliente, permitindo lidar mais rapidamente com interações, mas mostrou fraquezas em cenários em que mecanismos de busca não executam JavaScript, em que segredos precisam permanecer no servidor ou em dispositivos fracos e conexões lentas
- SSR/SSG é a abordagem em que ferramentas como Next.js e Gatsby geram HTML e JavaScript juntos no servidor e os enviam ao cliente
- O usuário pode ver o HTML imediatamente
- Quando o JavaScript carrega, o site se torna interativo
- Mecanismos de busca também conseguem ler o HTML
- Mesmo no SSR/SSG tradicional, ainda existem custos
- É preciso enviar ao cliente grande parte do JavaScript usado para gerar a página e fazer a hydration, em que o cliente executa tudo de novo e conecta ao HTML
- Se a renderização no servidor demorar por causa de chamadas lentas ao banco de dados ou de muita execução de código, o usuário precisa esperar
O que muda com React Server Components
- React Server Components são componentes React executados no servidor, e não no cliente
- Frameworks com suporte a RSC permitem separar explicitamente onde o código vai rodar
- Server Components: código que deve rodar apenas no servidor
- Client Components: código que deve rodar no cliente
- Quando o local de execução é separado, diminui o JavaScript enviado ao cliente e também o trabalho necessário durante a hydration
- Um Server Component pode buscar dados diretamente dentro do próprio componente
- É possível usar bibliotecas Node ou
fetch - Dá para reduzir a necessidade de buscar todos os dados no nível da página com
getServerSidePropse ir repassando por props - Também diminui os casos em que é preciso gerenciar estados complexos de loading com
useEffect
- É possível usar bibliotecas Node ou
- Quando a busca de dados termina, o Server Component pode fazer streaming do resultado para o cliente
- Assim, dá para mostrar o restante do site primeiro enquanto componentes lentos ainda estão carregando
- Também é possível buscar dados no servidor em resposta a ações do usuário no cliente e fazer streaming da resposta, mas isso, estritamente falando, não é RSC, e sim React Actions
As partes complicadas do RSC
- CSS-in-JS atualmente não funciona em Server Components
- Na migração da Mux para RSC, a maior parte do trabalho foi sair de styled-components e ir para Tailwind CSS
- Se a codebase depender muito de CSS-in-JS, será necessária uma migração separada
- React Context só pode ser acessado em Client Components
- Para compartilhar dados entre Server Components sem props, provavelmente será preciso usar módulos comuns
- Não existe em Server Components um bom mecanismo para restringir dados a apenas uma subárvore específica da aplicação React
- No site de documentação da Mux, isso não foi um grande problema porque as áreas que usavam Context já eram muito interativas e de qualquer forma precisavam ir para o cliente
- No site de marketing, compartilhar tema virou um problema
- Cada componente do pre-footer precisava saber que estava sobre um fundo verde para poder usar uma borda verde-escura
- Em vez de Context, isso foi contornado com uso intensivo de CSS custom properties
- RSC dá flexibilidade sobre onde o código executa e como os dados são buscados, mas em troca aumenta a complexidade
- Novos desenvolvedores precisam verificar o tempo todo “o que roda no servidor e o que roda no cliente”
- Em cada PR surgiam feedbacks sobre código enviado desnecessariamente ao cliente
- Durante o desenvolvimento, era comum adicionar
console.logpara confirmar se o log vinha do servidor ou do navegador - Caching também adiciona uma camada extra de complexidade
A forma básica de usar RSC no Next.js 13
- Na época em que foi escrito, a implementação de RSC pronta para produção era o app directory do Next.js 13
- No app directory do Next.js 13, o componente escrito por padrão é um Server Component
- No estado padrão, o código da página não é enviado ao cliente
- Apenas o HTML é entregue ao cliente
- Ao adicionar
asynca um Server Component, é possível buscar dados dentro do componente - Um Server Component com busca de dados lenta pode ser envolvido com
React.Suspense- O cliente vê primeiro a UI de fallback
- Quando o servidor termina de buscar os dados e renderizar, o componente resultante é enviado por streaming
- Um boundary de Suspense pode ser usado não só para streaming de dados, mas também para selective hydration, ajustando a prioridade de hydration de áreas específicas conforme a interação do usuário
- Para código que precisa rodar no cliente, adiciona-se
"use client"no topo do arquivo- Isso é usado em componentes que precisam de estado no cliente e interação, como listeners de
onClickouuseState - Todos os componentes importados por um componente com
"use client"também são enviados ao cliente
- Isso é usado em componentes que precisam de estado no cliente e interação, como listeners de
- Bibliotecas sem suporte a RSC podem ser importadas em um Client Component e incluídas no bundle do cliente
- Um exemplo é o componente
ClientMuxPlayer, que envolve@mux/mux-player-react
- Um exemplo é o componente
Critérios para escolher entre Server Component e Client Component
- Server Components são adequados para código que não precisa ser enviado ao cliente
- Renderização do corpo de posts de blog
- Trabalhos pesados como syntax highlighting de blocos de código
- Busca de dados
- Client Components são adequados para UI que responde à entrada do usuário ou cujo estado muda com o tempo
useState- Event listeners
- Interações no lado do cliente
- Se o app inteiro for feito com Client Components, ele funciona de forma parecida com frameworks SSR tradicionais
- Não é necessário converter o app inteiro de uma vez para Server Components; é possível adotar gradualmente começando pelos pontos com maior ganho
Três etapas para introduzir gradualmente em uma codebase real
- O playbook usado pela Mux tem três etapas
- Adicionar a diretiva
"use client"na raiz do app - Mover essa diretiva o máximo possível para baixo na árvore de renderização
- Aplicar padrões avançados quando surgirem problemas de performance
- Adicionar a diretiva
- Na etapa 1, adiciona-se
"use client"aopage.tsxde nível mais alto do Next.js 13 para que tudo funcione como antes - Se for preciso buscar dados no servidor, adiciona-se um Server Component como pai do Client Component
- O Server Component busca os dados
- Os dados buscados são passados por props ao Client Component
- Isso pode substituir o papel anterior do
getServerSideProps
- Na etapa 2,
"use client"é movido do componente de topo para componentes filhos- Em
<Title />, que não precisa de código no cliente, a diretiva pode ser removida para enviar apenas HTML puro - Em
<Player />, que precisa de código no cliente,"use client"continua necessário
- Em
- Essa abordagem ajuda a considerar Server Components em novos componentes e em refatorações, além de contribuir para reduzir um pouco o tamanho do bundle
Padrões aplicados quando havia problemas de performance
- O site de documentação da Mux é majoritariamente gerado de forma estática, mas a changelog sidebar vem de um CMS
- Ao envolver a sidebar com Suspense, o restante do app não precisa esperar até a conclusão do fetch no CMS
- A convenção loading.js do Next.js 13 também usa Suspense e streaming internamente
- Para manter bibliotecas grandes no servidor, é preciso ajustar como Client Components e Server Components são distribuídos
- Um exemplo é manter a biblioteca de syntax highlighting Prism no servidor
Como misturar Server Component dentro de Client Component
- Todo componente importado por um Client Component também vira Client Component
- Se você quiser colocar um Server Component como filho de um Client Component, não deve importá-lo diretamente; ele precisa ser passado por
childrenou props- O Server Component é renderizado no servidor
- O resultado serializado é passado ao Client Component
- A forma errada é importar diretamente um Server Component dentro do arquivo de Client Component
- A forma correta é subir até o Server Component pai mais próximo e passar o Server Component ao Client Component como filho ou prop
Não dá para dividir um arquivo meio servidor, meio cliente
- Não é possível fazer com que metade de um arquivo seja Server Component e a outra metade seja Client Component
- A Mux usou com frequência um padrão de dividir a funcionalidade em dois arquivos
CodeBlock.server.js: importa a biblioteca pesada de syntax highlighting e renderiza no servidorCodeBlock.client.js: usauseStateeonClickpara permitir que o usuário alterne entre exemplos de código
- Como os exemplos renderizados no servidor são passados ao Client Component via props, o trabalho exclusivo do servidor não vai parar no bundle do cliente
- Se
index.jsreexportarCodeBlock.server.js, o usuário pode importar apenasCodeBlocksem precisar se preocupar com a separação interna entre servidor e cliente
Como garantir que algo rode só no servidor
- No começo, durante o desenvolvimento, eram adicionados
console.logpara verificar se o log aparecia no servidor ou no navegador - Para garantir que código exclusivo do servidor não entre no bundle, é possível importar o server-only package
server-onlyé útil para evitar que bibliotecas grandes ou chaves secretas acabem indo parar no lugar errado- O Next.js oferece proteções para impedir que variáveis de ambiente entrem por engano no bundle do navegador
- Colocar
server-onlyno topo do arquivo também ajuda na manutenção- Quem cuida do código entende imediatamente que aquele arquivo roda no servidor
Custos e benefícios na hora de decidir pela adoção
- React Server Components não são um recurso gratuito
- Os custos incluem não só as restrições de CSS-in-JS e React Context, mas também os seguintes pontos
- Entender os locais de execução entre servidor e cliente
- Entender hydration
- Custos de infraestrutura
- Complexidade do código causada por misturar Client Components e Server Components
- A complexidade amplia a superfície para entrada de bugs e pode reduzir a manutenibilidade do código
- O framework reduz essa complexidade, mas não a elimina
- Os benefícios esperados são os seguintes
- Bundles menores
- Execução mais rápida
- Melhorias de performance importantes para SEO
- Padrões avançados de carregamento de dados para sites complexos e ricos em dados
- Se a equipe estiver preparada para arcar com o custo cognitivo adicional e os ganhos de performance forem suficientes, RSC pode ser uma boa escolha
1 comentários
Opiniões do Hacker News
Na renderização do lado do servidor, o cliente recebe HTML que pode ver imediatamente
Também percebi isso: se você coloca um arquivo de texto simples no servidor, ele chega ao navegador bem rápido
Se você coloca outro arquivo de texto simples que termina em
.css, o navegador sabe como processá-lo, então os elementos da primeira tela podem se mover e até ficar bem bonitosÉ um truque bacana, mas ainda é secundário em relação a conteúdo útil que possa ser lido na primeira tela
Não sei como “vamos adicionar recursos para tornar o hipertexto mais poderoso” virou “agora implementem vocês mesmos uma aplicação usável em cima deste grande monte de recursos inconsistentes”
Antes de entrar em RSC, é melhor parar um pouco
Seja o que for que você queira construir, isso pode ser feito de forma muito mais fácil, rápida e escalável com um framework full-stack de verdade ou com um framework web clássico
Dá para usar Rails/Django/Laravel/… com Turbolinks/Htmx/…, ou simplesmente espalhar um pouco de JavaScript do lado do cliente
Se você conhece Elixir/Phoenix, também pode levar várias vantagens junto
Por mais que muita gente tuíte sobre isso, não se deve ir mais fundo em RSC
Pessoas com menos de 10 anos de carreira na área vão repetir os problemas básicos que existiam nos antigos sites em vanilla PHP, e eu já vi até hooks de SQL inline dentro de componentes React
Desta vez, ainda há muito mais complexidade acidental por cima
Mantenha a sanidade, lance produtos reais rapidamente e ganhe dinheiro para comprar uma Lamborghini
CORBA é uma forma de misturar componentes locais e remotos; é madura e funciona em várias linguagens
Então por que todo mundo não usa? A maioria dos desenvolvedores de hoje provavelmente nem ouviu falar
Se quiser criar outra arquitetura de componentes distribuídos, deveria estudar por que CORBA e seus descendentes não se consolidaram amplamente
A pista é que fronteiras de componentes ocultas criam complexidade oculta
Por outro lado, os campos de “HTML renderizado no servidor” e “HTML renderizado no cliente” funcionam bem
Acho que é uma sorte considerável poder usar as duas opções em cada projeto web
Espero que o trabalho em RSC não obscureça o suporte do React a apps com renderização puramente no cliente
A menos que você precise absolutamente de uma aplicação frontend rica e progressiva completa, na maioria dos casos o LiveView resolve tudo por meio de componentes server-side com o mínimo de JavaScript
Além disso, cada usuário ganha uma thread do lado do servidor, permitindo empurrar ativamente mudanças para o frontend do usuário sem usar handlers JavaScript explícitos
Parece que a indústria sofre de amnésia em ciclos de 10 anos
Havia motivos muito válidos para se afastar de UIs renderizadas no servidor
Claro, o argumento de otimização para motores de busca sempre existe, mas, se essa é a preocupação, basta criar um site tradicional com templates no servidor
A grande maioria das aplicações de página única não precisa de SSR nem da complexidade que vem com ele
As primeiras interfaces do dashboard eram todas renderizadas com Phoenix, e só incluíamos React individualmente nas páginas que realmente precisavam de interações avançadas no cliente
Como nosso primeiro produto era um dashboard de analytics, essa situação logo passou a representar quase todo o dashboard, e foi natural migrar para uma aplicação de página única completa usando a API que já expúnhamos aos clientes
Isso foi em 2016, então LiveView ainda não existia, mas não tenho certeza se tomaríamos uma decisão diferente mesmo se recriássemos esse produto hoje
O post do blog é sobre a aplicação que sustenta o site público de marketing, com requisitos bem diferentes, mas queria dizer que nós também usamos e gostamos de Elixir/Phoenix
Parece que estou envelhecendo
Os frameworks de hoje são grandes e complexos demais
Até um simples “Hello world” na web precisa de um pipeline enorme de build e compilação, e agora ainda colocaram componentes do lado do servidor
Fico realmente curioso para saber qual é o tamanho desse overhead
Não sei por quantas camadas de código de frameworks de front-end e back-end um exemplo de Hello world passa para rodar
Vou voltar para um framework de componentes simples de 10 KB, que recompila quando eu aperto F5
É otimizar cedo demais para recursos sofisticados que talvez apareçam no futuro
É parecido com dizer que é preciso contratar engenheiros para tirar amostras de núcleo e fazer modelagem sísmica antes de construir um galinheiro
Desenvolvedores jovens estão começando a perceber isso agora
Assim como deixamos para trás horrores como SOAP e XML e migramos para tecnologias mais simples e fáceis de usar, esta geração também está reaprendendo que complexidade faz mal
Talvez o desenvolvimento de software volte a ser divertido por alguns anos, antes que a nova geração faça bagunça de novo
Um pipeline pode ser tão complexo ou tão simples quanto o caso de uso específico exigir
Pode ser feito só com arquivos estáticos, com um pequeno Makefile usando um único comando
esbuild, ou com uma configuração gigante de Webpack com 30 pluginsDá para escolher o que quiser de acordo com os requisitos e a complexidade do que se está tentando construir
Além disso, avaliar uma ferramenta pela facilidade de criar um Hello world simples só é útil quando o trabalho de fato é criar esse tipo de app
Sempre que SSR ou seus derivados entram na conversa, acabo me perguntando se não estão acrescentando complexidade desnecessária
Componentes de renderização no servidor do React parecem ter ido longe demais e ir contra o fluxo natural da experiência de desenvolvimento
Se a complexidade da aplicação dobra, as armadilhas de codificação aumentam e os desenvolvedores ficam mais lentos e confusos, tudo isso em troca de um pequeno ganho de desempenho, fico em dúvida se vale a pena
Sites PHP antigos e apps Rails sem single-page app também funcionaram bem por muito tempo
Tive essa experiência ao criar uma nova aplicação com Next.js e a nova estrutura de diretório
appPrimeiro, é difícil inferir o que acontece no servidor e o que acontece no cliente
Para saber, é preciso investigar, mas quando se está escrevendo código rapidamente, na maior parte do tempo isso acaba não recebendo muita atenção
Uma pequena alteração pode facilmente fazer uma grande parte da página de repente passar do servidor para o cliente
Sei que antes do lançamento final vou precisar fazer uma verificação cuidadosa e demorada página por página, e isso não é nada agradável
Segundo, como boa parte das bibliotecas React existentes usa hooks, elas presumem que serão executadas no cliente
Isso pode puxar o código para o cliente
O objetivo de brigar com o novo paradigma é ter renderização do lado do servidor para carregamento rápido e otimização para mecanismos de busca, mas, se as bibliotecas importadas não colaboram bem, isso vira um desperdício total
Terceiro, o novo paradigma do diretório
appdo Next.js tem bugsAinda é novo e muito complexo, então rotas dinâmicas, rotas paralelas e as interações entre elas podem quebrar completamente
Abri uma issue diretamente no GitHub do Next.js e ela recebeu muitos comentários de “também acontece comigo”
Uma das abordagens que eu usava foi corrigida recentemente por um desenvolvedor da Vercel, mas eu já tinha adotado outra abordagem para contornar o problema
O mais irritante é que o ambiente de desenvolvimento usa lazy loading e mágica de cache
Parece que ele tenta calcular as diferenças da página e enviar atualizações parciais por algo como WebSocket, mas pode quebrar totalmente e entrar em um estado irrecuperável
Às vezes, uma recompilação dispara alguma comunicação do servidor para o cliente e, quando volto para a aba do Chrome, ela fica completamente travada, e preciso matar o processo pelo gerenciador de tarefas do Chrome
No geral, ainda está em uma fase muito nova e com muitas arestas ásperas
Muitos hooks também funcionam no lado do servidor e, na prática, não fazem nada além de inicializar valores
É curioso que PHP e JavaScript fossem, na prática, quase a mesma sintaxe
A diferença era mais ou menos o símbolo
$ou a palavra-chavevar, mas o NodeJS disse: “queremos executar JS no servidor”E, 15 anos depois, o JavaScript acabou alcançando isso e ficou, na prática, parecido com PHP, só que com mais abreviações e uma curva de aprendizado mais íngreme
Claro que fazer streaming de dados do servidor para componentes de cliente com Suspense é legal
Estou usando NextJS 13, e gosto do fato de ele tornar SSR tão fácil quanto sempre foi possível em PHP; recomendo muito
Quando as pessoas o chamavam de “fractal de mau design”, isso era 100% merecido, e fazia sentido procurar outro lugar para resolver o problema
Hoje o PHP é uma linguagem muito melhor e vale a pena revisitar, mas não devemos fingir que ele sempre foi tão bom quanto é agora
E também não se deve julgar o NodeJS pelo ecossistema React
A quantidade enorme de APIs e wrappers necessários para rodar sistemas baseados em React é responsabilidade da comunidade React
É uma síndrome de Estocolmo clássica
Muitos avanços modernos só se tornaram possíveis porque os navegadores melhoraram primeiro
Não é exatamente que tenhamos dado uma volta completa; é mais como uma massa que, vista de muito longe, parece um círculo
Por um lado, ele foi inovador no sentido de que o modelo de concorrência permitia criar backends mais rápidos, mas faltavam muitos recursos das linguagens de backend existentes, como Java ou PHP, e por isso muitos padrões foram reinventados
A própria linguagem levou anos para chegar ao nível de “segurança” que Java já tinha e para o qual PHP estava caminhando
Tecnologias comprovadas e padronizadas, como XML e as garantias contratuais que ele podia oferecer, também foram abandonadas por motivos como serem pesadas e JSON ser bom para humanos lerem e escreverem
Sinto que perdemos muito tempo e esforço ao abandonar XML
Documentar APIs REST/JSON ainda é doloroso
Há 20–25 anos, já era possível gerar modelos de dados e parsers a partir de payloads XML
Até hoje não sei qual era exatamente o grande problema do XML
No fio, ele era um pouco mais pesado que JSON, mas isso era um problema solucionável usando compressão ou transformando-o em um protocolo binário com EXI (https://www.w3.org/TR/exi/)
Não sei se o EXI realmente pegou, mas na época eu tinha bastante expectativa, porque sabia o quanto XML circulava por aí
Na época, I/O não bloqueante trazia um grande ganho de desempenho
Mas, na cabeça dos desenvolvedores modernos, ele parece ter sido rebaixado a uma ferramenta burra para cuspir JSON ou hospedar toolchains
Provavelmente estão usando o que é familiar, mas usar React em um site de documentação, em vez de um gerador de site estático pronto com cache ou um CMS, parece desperdício
Do ponto de vista do desenvolvedor, React pode ser mais divertido
A Stripe iniciou o fluxo de mostrar trechos de código com a chave de API da conta já incluída, para que seja possível testar na hora
Sites de documentação de frontend quase sempre incluem exemplos executáveis que você pode manipular diretamente dentro da própria documentação
Fazer o bootstrap de um projeto novo é fácil e rápido demais, literalmente mais fácil do que iniciar um projeto em HTML puro
O que estou deixando passar?
Além disso, tenho curiosidade genuína sobre o ponto de vista de quem está dando downvote
É conteúdo estático; não entendo por que não gerar como HTML com um pouco de JavaScript para a caixa de busca
O motivo para usar React é usar uma única linguagem em todo o frontend
Dá para evitar a divisão em que uma pessoa usa React em um site e outra usa Gatsby/Hugo em outro
Next.JS consegue fazer o mesmo que Gatsby/Hugo, mas com mais recursos e baseado em React
Tenho idade suficiente para lembrar a época em que o servidor renderizava tudo, e CSS e Javascript eram usados para incrementar a página renderizada
A web se tornou um lugar sombrio e superengenheirado demais
É quase difícil de acreditar
Por isso, minha forma de criar apps é renderizar primeiro no servidor e incrementar depois
Dropdowns recolhíveis ou drag and drop com jQuery são recursos legais de ter, mas também me lembro claramente do inferno de gerenciamento de estado da era js/jQuery, e não quero voltar para lá
Brincadeira; minha primeira página no Geocities era HTML com só coisas como contador de visitantes e marquee
Minha primeira aplicação/projeto em PHP feito na escola também ainda não usava JS; para menus e cabeçalhos estáticos usávamos frames, e os dados eram enviados ao backend simplesmente por submissão de formulário
Houve uma época assim
No meu primeiro estágio de um ano incluído no curso universitário, usamos backend Java, templates JSX na camada de apresentação e PrototypeJS para coisas como diálogos ou acordeões animados
Naquela época, animação era “alterar a altura deste elemento algumas vezes por segundo”
No meu primeiro emprego, usei bastante JS para incrementar páginas com coisas como adicionar ao carrinho e carrossel de imagens, e aquela era a era do jQuery
No emprego seguinte, fizemos de forma péssima, com BackboneJS, uma UI para funcionários de suporte ao cliente consultarem coisas tipo SAP
O trabalho seguinte também foi refazer em BackboneJS um frontend de banco de investimentos para clientes
Aquilo era um caso de uso muito adequado ao que na época chamávamos de aplicação de página única
Não precisava de otimização para mecanismos de busca, a renderização puramente no frontend era rápida o bastante, era centrada em APIs, e aquele era o período em que as pessoas estavam percebendo que dava para usar a mesma API na web e no mobile
Na minha opinião, as ferramentas de desenvolvimento web nunca foram melhores do que agora, e a experiência do usuário também melhorou enormemente ao longo dos anos
O que chamávamos de AJAX cresceu de um brinquedo extra elegante para um elemento básico cotidiano na forma de componentes de cliente e single-page apps
O servidor continua poderoso, se você quiser, mas em apps interativos como dashboards, mapas, jogos, fóruns, apps de escritório e IDEs online, uma capacidade forte do lado do cliente é boa
Graças a isso, apps do dia a dia puderam migrar em grande escala de apps desktop personalizados por sistema operacional para uma plataforma universal que cobre todos os notebooks e desktops
É claro que esse poder exigiu mais complexidade
Escrever um blog ou landing page em HTML/CSS é muito diferente de escrever um web app completo
Angular e React foram criados para ajudar a desenvolver apps várias vezes mais complexos do que antes, numa época em que o runtime de JS e a própria linguagem eram muito mais primitivos que as linguagens server-side da época
No fim dos anos 2010, houve um período realmente doloroso em que vários frameworks JS resolviam apenas pedaços minúsculos do problema
Hoje em dia é menos assim
O Next venceu e virou o padrão, com razão
Ele oferece um nível de abstração adequado para apps de complexidade média e permite misturar bem renderização server-side com páginas client-side
React Server Components tornam essa divisão um conceito de primeira classe mais limpo
Mas isso só faz sentido acima de certo nível de complexidade
Se você não precisa, basta não usar
Para um blog ou site de documentação majoritariamente estático, há arquiteturas mais simples
Ainda é possível escrever HTML e espalhar apenas algumas linhas de JS conforme necessário, e a maioria dos pequenos negócios também pode usar WordPress ou Wix
Mas, se você está criando apps mais complexos, React é realmente um sonho em comparação com a abordagem de ir e voltar ao servidor a cada interação trivial para recalcular a UI e enviar a página HTML inteira toda vez
Esse método fazia você perder contexto, posição na página, formulários meio preenchidos etc., incentivava usar dados de formulário como estado e frequentemente levava à perda de trabalho ao apertar voltar sem querer ou por quedas frequentes do servidor antes da chegada da escalabilidade fácil na nuvem
Na minha opinião, só é superengenharia quando é aplicado de forma errada
Nos casos de uso certos, essas ferramentas são realmente úteis e às vezes essenciais
A parte lamentável talvez seja que elas são ensinadas e incentivadas demais mesmo em situações em que não são necessárias ou até são prejudiciais
No fim das contas, é preciso usar a ferramenta certa para o trabalho
Não estou tentando defender React em vez de Vue, Svelte ou HTMX; quero dizer que a complexidade do lado do cliente também tem utilidade
Tenho a impressão de que o React está se esforçando para acompanhar alternativas mais modernas, fáceis, rápidas e baratas
Mas, em vez de corrigir os problemas fundamentais — rerenderização, memoização frequentemente necessária e abstrações com vazamento —, o React está ficando mais complexo
Eu entenderia esse esforço se o resultado final fosse excelente, mas não é
O React é mais lento no mundo real do que os benchmarks mostram, e o Next é pior
Tenho visto muitos sites muito lentos feitos recentemente com Next
Realmente não entendo
Se a equipe do React quer melhorar o React, precisa corrigir o núcleo
Hoje há dependências demais no ecossistema, então tudo quebra
Target.com, Walmart.com, Microsoft Teams e incontáveis sites usam React
Há também um enorme ecossistema de componentes e empresas construídas sobre ele
Os conceitos centrais estão quebrados, mas corrigi-los significa que todo o resto pode quebrar
Se é para quebrar tudo de qualquer maneira, é melhor usar outra coisa
Agora o React está preso pela massa das dependências e só pode continuar rolando assim
O React parte do princípio de rerenderizar e fazer opt-out, enquanto Vue, Solid, Preact e Svelte fazem opt-in onde é necessário
Esse é um dos principais motivos pelos quais é difícil usá-lo corretamente e ele é vulnerável a certos tipos de bug
Embora por fora pareça JavaScript comum, é preciso ficar se preocupando em continuar fazendo opt-out; em outros frameworks, esses bugs são raros ou quase inexistentes
https://react.dev/blog/2023/03/22/react-labs-what-we-have-be...
Não entendo por que, a esta altura, estão usando React no backend para renderizar HTML
A ideia é voltar para 10 anos atrás?
Hoje em dia alterno bastante entre Svelte e templates do Django, e só o fato de o Svelte conhecer o DOM já torna a experiência muito melhor
Nunca vi algo assim em um sistema de templates que não fosse JS
Também já passei por PHP, jQuery etc.
Além disso, se o frontend já é React, fica muito mais fácil manter toda a geração de HTML em um só lugar
Além disso, há suporte a tipagem estática
Não estou tentando defender que RSC ou React sejam a melhor solução de todos os tempos, mas alguns dos contra-argumentos aqui ainda estão imaturos
Os benefícios de React/RSC não são tecnicamente iguais a um servidor retornar HTML/CSS e um pouco de JavaScript
Ainda é uma única aplicação, e é uma forma de lidar com a fronteira cliente/servidor de maneira mais inteligente em comparação com SSR/hidratação
Eu leria com prazer contra-argumentos mais bem informados sobre se o React se projetou para um beco sem saída e quais seriam as rotas de escape, mas voltar para PHP não é a resposta
React nem é tão difícil assim de aprender, e há um motivo para até não desenvolvedores pegarem o básico depois de algumas semanas de bootcamp
JSX é objetivamente superior aos sistemas de templates de Django, PHP e Rails
Metade dos contra-argumentos jogados de qualquer jeito provavelmente nem fez benchmark do próprio projeto com algo como o Lighthouse