Svelte comparado com React e Vue

Svelte é o novo prodígio entre frameworks front-end! Leia mais e saiba o que é o Svelte, sua sintaxe, como começar a usar e muito mais.

Ir para o artigo

O primeiro artigo sobre Svelte no blog poderia ser uma apresentação sucinta, mas vamos fazer melhor: apresentar o Svelte comparado com React e Vue, que são os 2 principais frameworks JavaScript do momento.

Vamos ser honestos: muitas coisas em desenvolvimento para web são mais difíceis do que deveriam ser. Alguns dias, pode parecer que tudo no mundo do front-end é desnecessária e excessivamente rebuscado e complicado.

O que é Svelte?

Basicamente, você poderia pensar no Svelte como uma estrutura de user interface (UI) de front end semelhante a React, Vue etc. Svelte é o mais novo dentre os grandes, mas parece que, definitivamente, já aprendeu com seus “irmãos mais velhos” e tem muito a oferecer em termos de Developer Experience (DX) e otimização.

Como acontece com qualquer estrutura de front-end, é possível usar o Svelte para construir componentes, que, no desenvolvimento web moderno, são os “blocos de construção” para qualquer UI. Conforme os eventos acontecem e o estado e os dados mudam (por exemplo, um usuário adicionando um item ao carrinho), os componentes são atualizados automaticamente para refletir essas mudanças na interface.

OK, mas isso já acontece com React e Vue… Então, como Svelte é diferente?

Como Svelte é diferente?

Svelte foi criado por Rich Harris, ex-desenvolvedor e editor gráfico do New York Times — na data de publicação deste artigo, trabalhando na Vercel.

O mundo das notícias é rápido, então, as interfaces e visualizações interativas que Harris estava criando para o Times precisavam ser construídas o mais rápido possível. Mas, uma vez que é fundamental que as notícias sejam acessíveis a todos, esses bits de interatividade também devem ser tão pequenos e eficientes, tanto quanto possível.

Harris precisava de uma solução que fosse extremamente rápida e fácil de construir, mas que fosse rápida e fácil para qualquer leitor em qualquer dispositivo ou rede, não importando o quão limitado. Em muitos casos, os enormes bundles JavaScript que são subprodutos de outros frameworks não eram adequados…

Então, Harris decidiu construir sua própria solução. E foi assim que Svelte nasceu.

Desde o início, é possível ficar consistente e agradavelmente surpreso com quão pouco código é preciso para fazer as coisas no Svelte — e como é bem perto do JavaScript, HTML e CSS que todos nós já conhecemos.

Tradução: “Svelte é React sem todas as besteiras.”

De fato, não é incomum ter que desaprender muitas das soluções mais complicadas comuns em outros frameworks (algo comum para os que conhecem e adotam o Svelte).

Em muitíssimos casos que, normalmente, tentaríamos uma solução alternativa ou tropeçaríamos em um problema ao usar outro framework, Svelte é deliciosamente direto.

Comparando Svelte com React e Vue

Conforme mencionado, Svelte é semelhante a outros frameworks front-end. Então, vamos olhar um pouco mais de perto nos detalhes de como o Svelte difere: seu foco build-time em vez de run-time e a simplicidade de sua sintaxe.

O “segredo” de Svelte: build no navegador

Aplicativos Svelte entregam uma excelente performance. Isso é possível porque Svelte tem uma abordagem diferente de outros frameworks de front-end, fazendo o máximo que pode na etapa de build — quando o código é compilado inicialmente — em vez de executar no lado do cliente.

Na verdade, tecnicamente falando, Svelte não é um framework JavaScript; é um compilador.

Explicando melhor, React, Vue e a maioria das outros frameworks front-end são executadas no navegador. Eles primeiro são carregados e depois seus métodos são chamados para executar os código (não muito diferente do jQuery e inúmeras bibliotecas semelhantes). Você pode carregar React, Vue etc. em uma tag de script, em um CodePen, ou então colocá-los em qualquer ambiente que desejar.

Geralmente, há uma ferramenta de build envolvida para reduzir o tamanho do bundle final gerado quando se trabalha com esses frameworks em ambiente de produção. Mas, pelo menos até certo ponto, você está inevitavelmente enviando a própria estrutura para o navegador e a carregando lá.

Svelte não funciona assim; não é possível “carregar o Svelte” no navegador ou brincar com ele no CodePen (embora o Svelte REPL funcione bem). Svelte não é um script.

Em vez disso, para criar um aplicativo Svelte, é preciso instalar o repositório Svelte em sua máquina. Você escreve os códigos, então, o compilador processa o que você escreveu em um JavaScript mínimo e autocontido antes mesmo de chegar ao navegador — não muito diferente de como o Sass é compilado em CSS puro.

Diagrama que compara Svelte com React mostrando os passos que cada um faz do componente à renderização no DOM.
Svelte vs. React: do componente ao DOM

Essa abordagem permite tamanhos de bundles extremamente pequenos, o que, por sua vez, traduz-se em melhor velocidade de carregamento e performance. Um bundle menor pode ser enviado ao navegador com mais rapidez e parseado pelo navegador mais rapidamente.

Também, React e Vue usam “virtual DOM” para renderização, que, embora seja mais rápido do trabalhar com o próprio DOM para fazer alterações, ainda tem suas próprias implicações/limitações de desempenho.

De maneira diferente, graças ao compilador do Svelte, não é preciso se preocupar com isso: componentes são vinculados diretamente a seus nós DOM. Para mais detalhes, leia o artigo do próprio Rich Harris “Virtual DOM is pure overhead”.

Criação de componentes Svelte

Uma das coisas mais interessantes no Svelte é sua filosofia “HTML em primeiro lugar” (HTML-first). Com poucas exceções, o código Svelte é HTML e JavaScript inteiramente legível. Na verdade, tecnicamente, é possível chamar o código Svelte de “um pequeno superconjunto de HTML”.

Assim como se escreve componentes em React em .jsx e Vue em .vue, Svelte tem arquivos de componente .svelte. Um componente Svelte, geralmente, tem a seguinte aparência:

Para dar uma exemplo real, veja o comparativo entre código Svelte, React e Vue para fazer um botão que conta quantos cliques recebeu:

Algumas diferenças importantes entre a versão Svelte e as outras:

  • Svelte é reativo por padrão. Isso significa que quando uma variável é reatribuída (reassigned), cada lugar em que é usada ou referenciada também é atualizado automaticamente — tanto o React quanto o Vue exigem que você inicialize explicitamente variáveis reativas.
  • A versão Svelte é a mais curta. Tanto em termos de contagem de linhas quanto de caracteres. Embora isso não seja necessariamente significativo por si só, um código mais curto tende a ser menos sujeito a erros, desde que seja legível (e os códigos Svelte, definitivamente, são).
  • Svelte não é exigente com HTML. React precisa de um retorno com um único elemento, e Vue precisa de uma única tag <template> envolvendo toda a marcação. Svelte pode ter qualquer HTML, em qualquer lugar — e com todos os seus atributos intactos, ao contrário de JSX, a linguagem de templating de facto do React.

Um comparativo Svelte/React/Vue mais prático

Mostrar quantas vezes um botão foi clicado não é particularmente útil, então, vamos a algo um pouco mais realista: um botão que alterna algum conteúdo oculto.

É um exemplo interessante, pois apresenta 2 conceitos importantes no Svelte:

  1. Renderização condicional (Conditional rendering). Como usar ifs no código;
  2. Valores calculados (Computed values). Variáveis dinâmicas que mudam dependendo da situação.

Eis o comparativo de como Svelte, React e Vue lidam com esses conceitos:

A maneira de Svelte de lidar com valores calculados é o operador $: mostrado acima; acrescente isso a qualquer nome de variável, e ele será reavaliado (reevaluated) toda vez que algum(ns) valor(es) que ali consta(m) depender(em) de alterações — neste caso, buttonText é reavaliado cada vez que isTextShown muda.

React permite fazer algo semelhante, mas, com Vue, já é preciso usar funções computed. Outras diferenças dignas de nota:

  • Svelte e Vue não exigem que você “envolva” (wrap) a marcação em um único elemento; React, sim — embora não seja de se espantar se o React descobrir uma maneira de eliminar esse requisito.
  • Em React e Vue, é preciso envolver os elementos condicionais em HTML e/ou sequenciá-los. Svelte permite colocar qualquer marcação válida dentro dos blocos #if e também não exige que os vincule a um elemento.

Comparando form bindings

Aqui está outro exemplo rápido e prático, para comparar bindings de formulário entre Svelte, React e Vue: um controle deslizante de volume, também conhecido como slider.

Observe como o fluxo de dados do React é unilateral; ele precisa que se atualize explicitamente a variável de volume sempre que sua entrada correspondente mudar. Em outras palavras: é preciso fazer a entrada ler a configuração de volume e atualizar a configuração de volume através de 2 duas etapas diferentes.

De maneira diferente, Svelte e Vue oferecem vinculação de dados bidirecional (two-way data binding); você apenas diz à estrutura que sempre que a entrada ou o valor muda, o outro deve ser atualizado para refletir isso.

Um detalhe interessante é que também é possível adicionar vinculação de dados bidirecional a props de componente no Svelte:

Isso permite que o componente-filho ChildComponent passe as alterações para o componente-pai e vice-versa.

React é contra essa ideia porque, explicando novamente, valoriza muito a imutabilidade e o fluxo de dados unilateral. Muitos podem considerar esse dogma mais inibidor do que útil…

Lógica de comparação

Embora já tenha sido mostrado, vale a pena dar uma olhada mais uma vez num comparativo de como Svelte, React e Vue lidam com renderização condicional (conditional rendering).

Assim que um componente <Hello /> seria condicionalmente renderizado nos 3 frameworks:

Obviamente, todos permitem else (e else if).

Aqui está um exemplo de como um componente <WelcomeBanner /> seria mostrado se o usuário estivesse conectado ou, caso contrário, um componente de formulário de login:

Loops

Svelte permite loops dentro da marcação, sem exigir que se vincule o loop a nenhum elemento ou usar map() em um array — e, na maioria dos casos, sem ser necessário digitar a chave (key) de cada item.

Suponha que existe um array chamada posts, com objetos contendo informações de postagens:

Também é bom poder colocar qualquer marcação dentro de blocos each de Svelte; não precisa ser um único elemento.

Outras razões para usar Svelte

Embora os exemplos acima já sirvam com uma boa amostra de potencial neste comparativo entre Svelte, React e Vue, o Svelte tem muitas outras características, dentre as quais:

  • Tudo fica junto em um arquivo. Semelhante aos componentes .vue de arquivo único, os arquivos .svelte mantêm a lógica, a marcação e os estilos de componente juntos.
  • CSS escopado (scoped) por padrão. É o comum de acontecer nos frameworks deste tipo e o Svelte também faz assim.
  • Transições e animações nativas. Uma API integrada robusta significa que não há necessidade de recorrer a uma biblioteca externa.
  • “Stores” nativas. Svelte já vem com uma versão lightweight de um Redux ou Vuex da vida — isso mesmo: é nativo!
  • Shorthands. Maneiras fáceis de binding de classes, lidar com props e modificadores de eventos (que fazem falta ao se trabalhar com outros frameworks).

Há muito mais o que se dizer sobre como o Svelte torna as coisas fáceis e como ele é avançado e, ao mesmo tempo, simples. E, claro, ainda vamos falar muito do Svelte aqui no dpw. :)

Até mesmo o site de documentação e tutoriais do Svelte está muito à frente no jogo; a coisa toda é um REPL (ambiente de codificação) ao vivo, em que é possível escrever seu próprio código Svelte e vê-lo rodando ao vivo!

CSS no Svelte

Uma das partes favoritas de muitos devs que mexem com Svelte é como ele torna a estilização bem fácil e divertida.

Para adicionar estilos a um componente no Svelte, simplesmente cria-se uma tag <style> no arquivo .svelte do componente. Qualquer CSS dentro dele terá como escopo, por padrão, o próprio componente.

Se preferir, é possível usar Sass com modificações mínimas e adicionando lang="scss" à tag <style>. Isso é possível graças ao svelte-preprocess.

Svelte Preprocess tem suporte para várias “linguagens” embutidas, incluindo Sass, PostCSS e TypeScript. Além disso, ele adiciona um recurso Sass extremamente interessantet: torna-se possível adicionar conteúdo para preceder (prepend) ao carregar o Sass dos componentes. Assim, se você tiver, por exemplo, todas as variáveis Sass em um arquivo externo, é possível importar isso automaticamente para cada componente.

Estilização condicional

Estilização condicional com Svelte é muito fácil graças a seus shorthands. Vejamos um pouco mais de perto como é possível aplicar uma classe .enabled a um componente com base em um valor booleano:

Se você já usou algum estilo condicional em outros frameworks, deve ter feito algo mais ou menos semelhante. Mas os ternários podem ser um pouco prolixo e difíceis de ler, especialmente quando um dos lados nem mesmo está fazendo nada.

Como em React, dá para encurtar isso para uma condicional de “curto-circuito”:

É um pouco estranho, mas, se já estiver acostumado com React, fica tudo bem. Como alternativa, em Svelte, podemos fazer isso:

Que é uma diretiva própria do Svelte também fácil de ler; você pode simplesmente ver qual classe será aplicada com base no valor JS.

E ainda é possível dar um passo adiante se o nome da classe e o nome da propriedade forem idênticos:

Também vale a pena mencionar que é possível ter quantos atributos class forem necessários (dinâmicos ou não) em um único elemento:

Estilo scoped vs. global

Se for preciso que o CSS de um componente seja global, é possível fazer isso por regra com a diretiva :global().

Ou, se preferir/for necessário, tornar a tag inteira global:

Uma palavra de aviso, no entanto: estilos globais podem persistir uma vez carregados na página, uma vez que Svelte produz os estilos de seu componente como um arquivo CSS standalone.

Portanto, se você tiver uma tag de estilo global em um componente que carrega apenas condicionalmente, seus estilos podem permanecer mesmo depois que o componente for removido da página, potencialmente aplicando-se aos elementos de lá também.

Isso pode levar a alguma confusão, uma vez que “global” significa global apenas uma vez carregado; o componente deve ser montado antes que esses estilos estejam realmente disponíveis.

Por causa disso, alguns devs consideram como uma boa prática sempre usar um seletor-pai wrapper mesmo ao lidar com estilos escopados.

Props e comunicação de componentes

A maneira como Svelte permite passar dados e eventos entre componentes evidencia a grandeza de sua flexibilidade.

Se você gosta da maneira como React lida com as coisas, pode passar métodos para seus componentes-filho e manter o fluxo unilateral intacto. Se você gosta do $emit de Vue, pode despachar eventos personalizados de componentes filhos e ouví-los no pai.

Como mencionado acima, você também pode fazer bind de props para habilitar o fluxo de dados bidirecional (two-way data flow) ou apenas ter ambos os componentes inscritos na mesma store de Svelte — ou até mesmo misturar e combinar. A escolha é sua.

Para criar um prop em um componente Svelte, você simplesmente cria uma variável usando a palavra-chave export:

O código acima indica uma prop obrigatória; se você quiser criar uma opcional, basta atribuir um valor padrão:

Essa sintaxe pode parecer um pouco estranha no início, já que, geralmente, estamos acostumados a exportar como uma forma de distribuir as coisas — ela é, reconhecidamente, uma das peculiaridades de Svelte, mas se torna familiar rapidamente. Pense nisso como um componente que exporta a responsabilidade por um valor para um componente pai.

Para efeitos de comparação, vejamos como é feito em Svelte, React e Vue:

Em qualquer um dos casos acima (já que ambas props são apenas strings), seria possível usar o componente da seguinte maneira:

Algumas coisas a serem destacadas:

  • Perceba que React não tem nenhum tipo de prop (ou qualquer forma de exigir uma); é preciso importar uma biblioteca para isso, provavelmente PropTypes — também é possível escrever a lógica no componente, mas isso não escala bem.
  • Embora Svelte permita que definir props obrigatórias, ele não tem prop typing embutido, como Vue. Isso ocorre principalmente porque Svelte é totalmente compatível com TypeScript. A expectativa parece ser “se você quiser prop typing, pode simplesmente usar o TypeScript para isso”.

Como começar a brincar com Svelte

Aqui no dpw, somos grandes fãs e entusiastas de Svelte e, apesar de este ser o primeiro artigo a respeito no blog, há alguns anos já falamos dele em nossas mídias sociais — aliás, ousaria dizer que somos um dos primeiros “canais” brasileiros de webdev a falar sobre o Svelte!

Se você achou o Svelte muito legal e agora quer começar a brincar com ele, existem 2 maneiras principais de avançar neste ponto.

Svelte REPL

Provavelmente, o Svelte pode ter o melhor tutorial e documentação de qualquer framework que se possa encontrar por aí nesses dias.

Há uma introdução maravilhosa no Svelte Tutorial que funciona como um ambiente de codificação ao vivo onde você aprende Svelte pouco a pouco e tenta terminar os desafios de código Svelte incompletos ao longo do caminho — ou, se desejar, apenas clicar em “mostrar” para ver a lição completa.

É divertido e envolvente e cobre todos os conceitos de Svelte — do simples ao complexo — extremamente bem. Recomenda-se fortemente, tanto para aprendizado, quanto para referência.

Seu próprio projeto com Svelte

Há um guia de início rápido do Svelte com orientações sobre como instalar o Svelte. Resumindo, basta executar (assumindo que você já tem npm instalado):

Se você não estiver familiarizado com esses comandos:

  • O npx permite que você execute algo do NPM, mas sem realmente instalá-lo em sua máquina. Neste caso, queremos apenas executar o degit uma vez; não precisamos mantê-lo para nada depois disso.
  • degit clona um repo (neste caso, o projeto template de sveltejs), mas sem seu histórico git, o que torna as coisas muito mais rápidas; é como se você estivesse iniciando um novo projeto.

Naturalmente, você pode substituir “my-svelte-project” por qualquer nome que desejar para o seu projeto local. Depois de um npm install, execute npm run dev para iniciar um servidor de desenvolvimento que mostrará seu projeto e será atualizado automaticamente conforme você salva as alterações.

Conclusão

Uma das muitas maneiras de se conhecer alguma coisa é através da comparação dessa coisa com algo que já seja conhecido. Essa foi a intenção de fazer essa comparação entre Svelte, React e Vue.

Espero que você esteja tão animado com Svelte quanto nós estamos! Encorajamos você a experimentar por conta própria, mesmo que seja apenas brincando no Svelte Tutorial. Se você ainda não experimentou, são grandes as chances de você ficar positivamente surpreso!

Usamos cookies para melhorar sua experiência e para ajudar a entender como nosso site é usado. Ao utilizar este site, você aceita o uso de cookies. Consulte nossa política de privacidade para obter mais informações.