Por que a Spot está largando o CSS-in-JS
Encontrei um artigo que diz porque a Spot, uma plataforma de comunicação para equipes, decidiu abandonar o CSS-in-JS. Acredito que esse debate seja extremamente relevante para desenvolvedores frontend.
Pontos positivos
- Estilos com escopo local: é possível declarar um CSS com escopo específico para determinado componente, sem correr o risco de usar a mesma classe em dois lugares diferentes sem querer. O que veio à minha mente na hora, e o autor também ressalta no artigo: módulos CSS também fornecem estilos com escopo definido localmente.
- Colocação (colocation): ter o código relevante o mais próximo possível de onde é utilizado. Com CSS-in-JS, você pode escrever seus estilos diretamente dentro do componente React que os usa, ao invés de ter um arquivo
.css
com vários estilos que dificultará identificar o que é utilizado e o que não é. O artigo diz que módulos CSS também permitem colocar estilos com os componentes, embora não no mesmo arquivo (imagino que ele esteja dizendo que precisará de um arquivo.jsx
e um.module.css
, por exemplo). - Você pode usar variáveis JavaScript em estilos: é possível colocar código JavaScript dentro da estilização. Isso dá mais facilidade para criar estilo baseado no estado ou propriedades do componente.
Pontos neutros
- É a nova tecnologia "quente": está com bastante hype envolvido, e isso traz mais pessoas, o que aumenta o hype.
Pontos negativos
- CSS-in-JS adiciona sobrecarga no tempo de execução: a biblioteca de CSS-in-JS é responsável por serializar seus estilos em CSS puro a ser inserido no documento.
- CSS-in-JS aumenta o tamanho do pacote: como exemplo, o Emotion tem 7,9 kB minificado e zipado, e o styled-components tem 12,7 kB. Portanto, nenhuma das bibliotecas é enorme, mas tudo se soma à sua aplicação.
- CSS-in-JS bagunça o React DevTools: para cada elemento que usa a prop
css
, o Emotion renderizará os componentes<EmotionCssPropInternal>
e<Insertion>
:
Pontos feios
- A inserção frequente de regras CSS força o navegador a fazer muito trabalho extra: isso tem mais a ver com as relações dessas bibliotecas com o React, e o artigo menciona uma dicussão que aborda essa questão mais profundamente.
- Com CSS-in-JS, há muito mais coisas que podem dar errado, especialmente ao usar SSR e/ou bibliotecas de componentes: existem vários issues no repositório do Emotion, por exemplo, mencionando problemas desse tipo.
Performance
No artigo é explicada a metodologia de comparação em um componente usado na Spot, os resultados estão abaixo (em milésimos de segundo). O tempo de carregamento melhorou, em média, 48%:
O que substituiu o CSS-in-JS na Spot
A Spot passou a usar Módulos SASS, que são simplesmente módulos CSS escritos em Sass. Assim, é possível ter os estilos de escopo local dos módulos CSS e os recursos de tempo de build do Sass, essencialmente sem custo de tempo de execução. Com isso, perde-se apenas o benefício 3 do CSS-in-JS: a capacidade de usar variáveis JavaScript em estilos.
Para melhorar a experiência do desenvolvedor (DX), a Spot decidiu criar um sistema de classes utilitárias: classes CSS que definem uma única propriedade CSS no elemento. É como classes do Tailwind ou do Bootstrap, por exemplo:
<div className="d-flex align-items-center">...</div>
No momento de escrita do artigo, a Spot estava usando módulos Sass e classes utilitárias para novos componentes há várias semanas e muito satisfeitos com isso. A DX é semelhante ao do Emotion e o desempenho do tempo de execução é muito superior — parece ter feito diferença no projeto deles:
Para nós da Spot, o custo de desempenho do tempo de execução do Emotion superou em muito os benefícios da DX, especialmente quando você considera que a alternativa de módulos Sass + classes utilitárias ainda tem uma boa DX enquanto fornece desempenho muito superior.
Eu uso módulos Sass nos meus projetos e já senti a dificuldade em não poder usar variáveis JavaScript, mas sempre consegui me virar. Nunca usei CSS-in-JS e nem as classes utilitárias. Quem já teve experiências com esse tipo de situação, compartilhe aqui para agregar mais à essa discussão.
Do meu ponto de vista, a única novidade foi que o CSS-in-JS atrapalha o desempenho, mas tenho dúvida se isso é tão relevante no projeto — provavelmente varia de projeto pra projeto.
Como curiosidade, o TabNews faz uso do styled-components
, mas não tenho experiência com a base de código.