리액트는 자바스크립트 안에서 HTML 엘리먼트를 생성하고 조작할 수 있도록 하여 독립적인 컴포넌트 단위의 개발을 가능케 하였다. 그러나 아직도 CSS는 별도로 작성되어야 했기 때문에 진정한 의미의 캡슐화
을 이룰 수 없다는 문제가 있었다. 이를 해결하기 위한 개념이 바로 CSS-in-JS로, CSS의 문법을 이용해 자바스크립트, 혹은 컴포넌트 내부에서 스타일을 작성하도록 해주는 방식이다. 왜 이러한 방법이 등장하게 되었을까?
기존 CSS 작성 방식의 문제점은 무엇인가?
웹을 구성하는 기초인 HTML, CSS, JS 중에서도 CSS의 발전은 나머지에 비해 느린 편이었다. 기존의 CSS가 가지고 있는 대표적인 문제점은 다음과 같다.
사실 CSS-in-JS 이전에 SASS와 같은 CSS 전처리기가 기존 CSS의 문제를 해결하기 위한 대안으로 나와 있었지만 여전히 클래스를 이용해서 조건부 스타일 등을 구현하기 때문에 클래스명에 대해 고민해야 하는 문제가 있었다. 또한 BEM(Block, Element, Modifier)과 같은 방법론도 네이밍 이외의 기존 문제에 대한 근본적인 해결책이 되지 못하였다. 그러나 CSS-in-JS를 사용하면 이러한 문제들은 대부분 해결된다.
이러한 장점만 보면 당장에라도 CSS 작성을 모두 JS 안에서 해결해야 할 것 같지만, CSS-in-JS는 다음과 같은 단점도 존재한다.
번들 크기가 커진다: 가상 DOM으로 모든 웹 구조를 JS 안에서 해결하도록 코드를 작성하는 상황에서 CSS까지 JS로 옮긴다면 다운로드 시간은 더욱 느려질 것이다. 이러한 방법은 초기 로딩 시간이 중요한 프로젝트에 적합하지 않다. SSR(Server Side Rendering)을 이용하면 번들 파일을 받기 전에 먼저 콘텐츠를 볼 수 있지만, 동적 인터랙션이 필요한 경우 문제가 될 수 있다.
인터랙션 성능 저하: 기존 CSS는 모든 스타일을 미리 만들어 두어 바로 적용할 수 있지만 CSS-in-JS 방식은 상태가 변할 때 마다 JS 안에서 새롭게 CSS를 파싱하고 코드 블럭을 생성한 후 HTML에 입히게 된다. 이러한 방식은 기존 CSS에 비해 느려질 수밖에 없으며 다양한 인터랙션 기능이 포함된 프로젝트에선 적합하지 않다.
다음과 같은 단점을 염두에 두어 작성하려는 콘텐츠가 어떠한 요구사항을 가졌는지에 따라 기존 Sass 등의 전처리 도구와 CSS-in-JS를 병합해서 사용하는 것이 현재로썬 제일 나은 방법이라고 생각된다.
결론적으로 CSS 방법론은 특정 방식이 독점적인 우위를 가지고 있지 않은 상황이다. 기존 CSS 방식을 기반으로 단점을 보완할 것인가, 아니면 완전히 독립적인 스타일링을 구현할 것이냐는 두고 볼 부분이다.
참고
styled-components 공식문서
CSS-in-JS에서 CSS-in-CSS로 바꿔야 하는 이유
[번역] CSS-in-JS에 관해 알아야 할 모든 것