- Resumo dos problemas enfrentados após atualizar recentemente uma aplicação web para o Svelte 5
- Surgiram comportamentos inesperados por causa do recurso de deep reactivity e do ciclo de vida alterado
- Gostei muito do Svelte 3/4 por bastante tempo, mas daqui para frente acho que não vou escolher Svelte para novos projetos
Necessidade de velocidade
- A equipe do Svelte tentou otimizar desempenho por meio de deep reactivity, e conseguiu extrair uma performance melhor
- Antes disso, ele já oferecia bom desempenho por meio do processo de compilação, e isso era um diferencial em relação a outros frameworks
- Isso acabou criando um framework opaco, difícil de depurar, mas parecia um trade-off aceitável em termos de desempenho e produtividade
Necessidade de velocidade
- A principal mudança em que a equipe do Svelte está apostando no Svelte 5 é a “deep reactivity”, para aumentar o desempenho com uma reatividade mais granular
- Nas versões anteriores do Svelte, esse objetivo era alcançado principalmente com o compilador do Svelte
- O fato de o desenvolvedor não precisar aprender conceitos novos diretamente e poder reorganizar a lógica interna com facilidade destacava a originalidade do Svelte
- Ao mesmo tempo, esse processo de compilação também tornava o framework opaco, dificultando a depuração de problemas complexos
- Bugs no próprio compilador geravam erros cuja causa era difícil de identificar, e às vezes só era possível resolver refatorando totalmente o componente problemático
- Ainda assim, parecia um compromisso razoável entre velocidade e produtividade, então eu tolerava até o incômodo de ter de reinicializar o projeto periodicamente
Svelte não é Javascript
- O Svelte 5 duplica esse trade-off
- A diferença central é que o ponto de compromisso entre abstração e desempenho deixou de ficar só na etapa de compilação e passou a penetrar também na parte de runtime
- Uso de proxies para dar suporte a deep reactivity
- Estado implícito do ciclo de vida do componente
- Essas duas mudanças melhoram o desempenho e fazem a API para desenvolvedores parecer mais elegante
- O que haveria para não gostar? Infelizmente, esses dois recursos podem ser considerados exemplos típicos de leaky abstraction
- No fim, isso cria um ambiente mais complexo para o desenvolvedor lidar
Proxies não são objetos
- Com o uso de Proxy, a equipe do Svelte conseguiu extrair um pouco mais de desempenho do framework sem exigir trabalho extra do desenvolvedor
- Em frameworks como React, ao passar estado por vários componentes, é comum provocar rerenders desnecessários; o Svelte introduziu Proxy para reduzir isso
- O compilador do Svelte já evitava alguns problemas que poderiam surgir no processo de diff do virtual DOM, mas aparentemente a equipe concluiu que Proxy poderia melhorar ainda mais o desempenho
- A equipe do Svelte também mencionou que Proxy contribui para melhorar a experiência do desenvolvedor, defendendo a ideia de que “é possível maximizar tanto a eficiência quanto a facilidade de uso”
- O problema é que o Svelte 5 parece mais simples na superfície, mas na prática adiciona mais abstrações
- Por exemplo, usar Proxy para detectar métodos de array traz a vantagem de não precisar escrever código como
value = value no Svelte 4
- No Svelte 4, o desenvolvedor precisava entender até certo ponto como o compilador funcionava para disparar a reatividade. Já no Svelte 5, passa-se a impressão de que “dá para esquecer o compilador”, mas na prática não é assim
- Na mesma medida em que a nova abstração traz conveniência, também aumenta o número de regras que o desenvolvedor precisa conhecer para que o compilador se comporte como esperado
- Depois de usar Svelte por muito tempo, pessoalmente fui passando a usar mais Svelte stores e menos declarações reativas
- Svelte stores são, em essência, mais próximas de conceitos do JavaScript, a forma de chamar o método
update é simples, e a sintaxe $ era mais um benefício adicional
- Assim como as declarações reativas, Proxy causa o problema de “parecer uma coisa, mas se comportar de forma diferente nas bordas”
- Quando usei o Svelte 5 pela primeira vez, tudo parecia funcionar bem, mas ao tentar salvar estado com Proxy no IndexedDB, ocorreu um
DataCloneError
- Pior ainda, para saber com certeza se um valor é Proxy, é preciso tentar uma clonagem estruturada com
try/catch, o que tem custo de desempenho
- No fim, você passa a ter de lembrar o que é Proxy e usar
$state.snapshot toda vez em contextos externos que não reconhecem Proxy
- Como resultado, ao contrário da intenção original de que “a abstração aumenta a conveniência do desenvolvedor”, isso acaba impondo regras e procedimentos mais complexos
Componentes não são funções
Conclusão
- O que é fácil certamente tem seu apelo, mas, como disse Rich Hickey, fácil não significa simples
- Como Joel Spolsky diz, eu não gosto de comportamentos inesperados
- O Svelte mostrou muita “mágica” ao longo do tempo, mas nesta versão, a quantidade de coisas que é preciso memorizar para usar essa mágica aumentou tanto que o custo superou o benefício
- O objetivo deste texto não é criticar a equipe do Svelte; pelo contrário, reconheço que há muita gente que prefere o Svelte 5 (e React Hooks)
- O importante é o equilíbrio entre oferecer conveniência ao usuário e permitir que o usuário mantenha o controle
- Software realmente bom não se baseia em “esperteza”, e sim em “entendimento”
- À medida que ferramentas de IA evoluem, torna-se importante escolher ferramentas que aproveitem a sabedoria já acumulada e ajudem na compreensão profunda, em vez de ferramentas que façam você não saber o que está fazendo
- Obrigado a Rich Harris e à equipe por toda a experiência agradável de desenvolvimento até aqui. Espero que este texto sirva como um feedback que não seja totalmente impreciso
7 comentários
proxyé conveniente para quem cria, mas deixa quem precisa depurar irritado kkkMeu projetinho paralelo tem o melhor DX com solidjs >m< / felicidade
Acho que, por existirem alternativas como o Svelte, React/nextjs também pôde receber um grande estímulo.
Fundamentalmente, o Svelte é uma language, então espero que ele também mostre bem a direção que uma linguagem para descrever UI deve seguir.
Eu vou usar React
Excesso faz mal
Desvio do caminho
Camada sobre camada
Acho que mudou de um jeito estranho, sendo bastante influenciado por React e especialmente pelo Next.
+pageé difícil de entender se você olhar sem conhecer Svelte, e runes como$statee$derivedparecem estar seguindo o React; sinceramente, a época em que se colocava$:antes das variáveis me parecia melhor. Dá para tolerar uma sintaxe antiga como{#each a in array} {/each}, mas ainda assim continua incômoda. Se a ideia é melhorar o desempenho com reatividade opcional, acho que o SolidJS segue uma direção muito melhor. Como ele usa JSX diretamente, também é relativamente mais fácil migrar vindo de React. É até estranho o quanto o SolidJS recebe relativamente pouca atenção.Parece que os Signals estão caminhando para o Trough of disillusionment do Gartner hype cycle 🤔 Conforme os casos de uso vão se consolidando gradualmente, acho que a avaliação pode melhorar.
Comentários no Hacker News
No começo eu não me interessei muito pelos runes. Mas mudei de ideia quando percebi que era possível importar componentes externos reativos em templates
.sveltee encapsular a reatividade internamente. Isso significa que dá para escrever testes com vitest e ainda aproveitar os benefícios da reatividade. Isso é realmente poderoso e, AFAIK, algo único no mundo frontendEstou desenvolvendo ativamente uma aplicação SvelteKit distribuída comercialmente e queria compartilhar algumas impressões da experiência
+page. Você podia colocar arquivos Svelte onde quisesse, e eles eram renderizados sem atrito, enquanto você ainda tinha os benefícios de um framework modernoÉ uma pena que EmberJS tenha desaparecido. A API foi bastante estável nos últimos 10 anos. Ironicamente, alguém que escreveu apps em EmberJS ao longo da última década provavelmente teria menos dificuldade para migrar do que alguém que fez o mesmo trabalho com React, Svelte, Vue etc.
Os dois links de Github listados pelo autor no topo do post apontam para o mesmo problema, e esse problema tem solução (
use $state.raw)Svelte 5 é a <i>pior</i> forma de não ser JavaScript. Ele não resolve os problemas do js e oferece abstrações vazadas para alguns problemas de frontend. Acho que o Solid segue uma direção melhor que a do Svelte. O Solid não depende de uma nova linguagem. Mas existe um impulso para criar algo que não seja js porque js não é ideal. Elm é um precursor do svelte. Mas acho que dá para fazer algo melhor...[0]
Comecei a usar Svelte 5 porque eu realmente odiava as stores no Svelte 4. Estou usando Sveltekit e Svelte 5 em um projeto novo e preciso dizer... a produtividade do React continua imbatível, mesmo que a tecnologia do Sveltekit e do Svelte seja tecnicamente melhor
+page.server.tsou+page.svelteou alguma variação disso, então fica difícil buscar código com facilidade. As ferramentas do Svelte existem separadamente detsce ESLint, o que torna mais difícil integrá-las ao CI e usá-las no desenvolvimentoDizer que Svelte não é JavaScript por causa de um comportamento inesperado ao passar closures em callbacks parece estranho. Um título melhor seria "Eu não gosto do Svelte 5 porque ele me surpreendeu"
Se você está procurando uma biblioteca com a qual possa construir componentes e apps usando JavaScript puro, dê uma olhada em Lit: Lit
Quer uma experiência frontend sensata? Use JavaScript puro, web components, htmx, Blazor