제가 하고 있는 프로젝트의 sass-loader를 점진적으로 거둬내기에 앞서 문제점과 css-in-js의 특징을 알아 봤습니다.
webpack의 build/rebuild 속도가 너무 느린데, 느린 build 속도의 대부분은 sass-loader에서 병목이 발생하였습니다.
sass-loader
가 느린 이유는 다음과 같습니다.
sass-loader
가 트랜스파일한 SASS 파일은 캐시되지 않습니다.CSS Modules
를 활용하여 각각의 component에서 Import하여 sass를 사용했을 경우, stylesheet가 모두 모듈화되어 각각 고유한 sass 프로세스가 되고, 빌드 환경에 따라 그 속도는 더 최악이 될 수 있다고 합니다.😢sass
와 sass-loader
를 제거하고, PostCss와 CSSNext를 도입하여 build 시간을 50%나 줄였다고 합니다.우선 sass-loader
가 태생이 매우 느린 build performance를 보이고 있었기 때문에 이를 제거해나갈 고민을 하였습니다. 여러 방식을 찾아보다가 css-in-js
를 도입하기로 결정했습니다. 그 결정의 이유는 다음와 같습니다.
별도의 style file 형식이 아닌 javascript 코드 내에서 css를 작성하는 방식입니다.
기존 css 관리 방식의 어려움을 느껴 고안된 방식이라고 합니다.
styled-component
, emotion
등 다양한 css-in-js 라이브러리가 존재합니다. 앞으로 편의상 이런 라이브러리를 통칭하여 css-in-js라고 부르겠습니다.
모든 css-in-js 라이브러리들은 css module
처럼 고유한 css classname을 생성합니다. 따라서, classname 충돌이나 naming에 크게 신경쓰지 않아도 됩니다. component 기반의 개발 방식에서는 굉장히 중요하고, 개발 생산성을 높일 수 있는 특성입니다.
transition
만 선언해도 자동으로 vendor prefix를 붙혀줍니다./* WebKit browsers: Chrome, Safari, most iOS browsers, etc */
-webkit-transition: all 1s ease;
/* Firefox */
-moz-transition: all 1s ease;
/* Internet Explorer and Microsoft Edge */
-ms-transition: all 1s ease;
/* old pre-WebKit versions of Opera */
-o-transition: all 1s ease;
/* standard */
transition: all 1s ease;
css에 비해 javascript inline styles
는 성능이 좋지 않습니다.external css file
을 가지고 있을 경우, browser에 캐싱이 가능하지만 각각의 요소에 스타일을 입히는 inline-style의 경우, 캐싱이 불가능하여 성능에 부정적인 영향을 줍니다.
pseudo classes
, elements
, media query
, keyframe animations
도 지원합니다.
은탄환은 없습니다.
css-in-js
방식도 몇 가지 trade-off가 있습니다.
emotionjs
, styled-component
와 같은 js library에 종속적이기 때문에 js가 구동되지 않는 환경에서는 스타일을 사용할 수 없습니다.css-in-js의 퍼포먼스 저하 문제를 검색하다 알게된 나온 개념입니다.
css global variable
로 변수 할당을 통해 CSS로 추출됩니다. 따라서, CSS 파일 크기는 조금 커질 수 있지만, 한 번 style load 후, 동적인 연산이 적게 되는 이점이 있습니다.
안녕하세요. 글 잘봤습니다. 하나 궁금한 점이 생겨서 질문 올려요.
zero-runtime css-in-js 도 sass랑 동일하게 빌드 타임에 css 파일을 생성한다면 빌드 시간이 늘어나는 이슈는 없나요?