티스토리 뷰

[정의]

CSS-in-JS는 스타일 정의를 css나 scss파일이 아닌 JavaScript로 작성된 컴포넌트에 바로 삽입하는 기법이다.

 

[사용 배경]

기존 웹 사이트는 HTML, CSS, JavaScript를 각자 별도의 파일로 두었는데, React나 Vue, Angular와 같은 모던 자바스크립트 라이브러리가 인기를 끌면서 컴포넌트 기반 개발 방법의 주류가 됨에 따라 한 컴포넌트에 HTML, CSS, JavaScript를 모두 포함하는 패턴이 많이 사용되고 있다. 

 

inline-style과의 차이점?

CSS-in-JS는 컴포넌트 안에 css를 정의하는 인라인 스타일과 비슷하지만 인라인 스타일은 지양하는 것이 좋습니다.

[inline style의 단점]

  • CSS 속성의 중복, 재사용성이 떨어진다.
  • 의사 클래스, 의사 요소, 미디어 쿼리, 키 프레임 등 애니메이션 같은 CSS의 기능을 활용할 수 없다.
  • 앱의 규모가 커질수록 유지 보수가 어렵다.
  • 인라인 스타일은 HTML 내부에 CSS를 작성하는 것이므로 코드 가독성이 떨어진다.

[동작방식 차이]

inline style은 인라인 태그로 style을 정의하는 반면 CSS-in-JS는 style 태그를 따로 정의하고 해당 태그에 class화 시켜서 연결하는 방식으로 동작한다.

 

또한, JSX 문법을 사용하는 React의 경우에서는 모든 속성이 props 객체의 일부가 된다. 그러니 style 부분의 비교는 항상 false가 나오게 되고 다시 렌더링될 때마다 스타일 객체가 다시 계산되어서 성능이 저하될 수 있다.

 

CSS-in-JS의 장단점

[장점]

  • CSS의 컴포넌트화로 스타일시트의 파일을 유지보수할 필요가 없다. CSS 모델을 문서 레벨이 아닌 컴포넌트 레벨로 추상화한다. (모듈성)
  • CSS-in-JS는 자바스크립트 환경을 최대한 활용할 수 있다.
  • JS와 CSS 사이의 상수와 함수를 쉽게 공유할 수 있다.
  • 현재 사용중인 스타일만 DOM에 포함한다.
  • Sass 문법까지 사용 가능하며 변수 사용이 가능하여 기존에 수많은 클래스의 중첩으로 제어하던 부분을 쉽게 제어할 수 있습니다.
  • CSS-in-JS는 짧은 길이의 유니크한 클래스를 자동으로 생성하기 때문에 코드 경량화의 장점이 있습니다.

[단점]

  • 러닝 커브
  • 새로운 의존성
  • 별도의 라이브러리를 설치해야하므로 번들 크기가 커진다.
  • 인터렉션한 페이지일 경우 CSS 파일을 따로 관리하는 방법에 비해 느린 성능을 보여줄 수 있다.
CSS-in-JS 단점 추가 설명 >
StyleSheet의 Script 변환은 그만큼 HTML 파싱에 사용되는 Script의 코드가 늘어났다는 것을 의미합니다. 브라우저 렌더링이 StyleSheet와 Script로 나누어 병렬처리 되던 것이 오직 Script로 이루어짐에 따라 그 만큼 속도가 느려집니다. 
CSS가 먼저 제공되어 렌더링 시 형태가 잡혀있는 기존 방식에 비해 컴포넌트가 렌더링되며 형태가 잡히기 때문에 원형의 모습이 잠깐 노출(FOUC)됩니다. 이는 사용자 경험을 저하시킵니다. 

[FOUC 문제 해결방법]
사용하는 StyleSheet를 생성해 올려주는 기능이 필요하다. 여기에 SSR문제가 겹친다면 문제는 더 복잡해진다고 합니다. 프레임워크에서 이러한 이슈를 직접 지원하는 경우도 있지만 아닌 경우, 직접 구현해야 합니다. 

 

FOUC(Flash of unstyled content)
스타일 시트가 적용되기 전 마크업 된 그대로의 모습이 잠깐 보이는 현상입니다.
-> 간단히 말하면, 스타일링이 미처 되지 못한 콘텐츠가 차후에 스타일 적용이 완료되면서 깜빡거리는 현상을 말합니다.

개인적으로 리액트에서 styled-component를 사용하면서 FOUC현상을 겪어본 적이 없는데 받아오는 데이터가 너무 작아서 인지.. 어떤 이유인지 잘 모르겠어서 styled-component의 FOUC 현상에 대해서 찾아봤다. 

  • 알아본 결과,  styled-component 자체에서 SSR을 제공하여 해결하고 있다는 글을 발견하였다. 
  • 또한, lazy loading을 통해 css가 제대로 입혀지기 전의 요소를 화면상에 안 보여주는 방법이 있다는데 내 코드에서의 컴포넌트들은 백엔드에서 데이터를 받아서 표시해주기 때문에 비동기처리를 따로 해놨다. 로딩 스피너로 데이터가 다 오기 전에는 컴포넌트를 보여주지 않게 해놨는데 아마 이 부분에서 내가 FOUC현상을 발견하지 못한 것이 아닌가 싶다. 
  • 마지막으로 브라우저 별로 깜빡임 현상의 결과가 다른데 IE의 경우 FOUC 현상이 심하다고 한다. 나머지 브라우저는 FOUC를 방지하기 위해 CSS를 다 읽기 전에는 요소를 화면에 표시하지 않는다는데 7년 전 자료라 더 찾아보니 FOUC 자체가 IE의 고질적인 문제라는 점을 발견했다;;
  • slow 3G로 네트워크를 제한해서 봤는데도 발견하지 못한 이유를 찾은 거 같다. 결국 FOUC는 브라우저의 렌더링 방식 문제라고 보면 될 거 같다. 

 

+ 2023 01 16 UPDATE

[문제 상황]

리액트 프로젝트 시, styled-component 와 일반 컴포넌트가 구분이 잘 되지 않는 문제 

[해결 방안]

S-dot import 방식을 사용하여 기존 컴포넌트와 스타일드 컴포넌트로 만들어진 컴포넌트 구분

[주의점]

*S-dot import 방식의 단점

"import *를 사용하면 번들러 트리 셰이킹 때, 미사용 코드 제거가 안 되지만 스타일드 컴포넌트는 미사용 코드가 거의 없기 때문에 괜찮다고 생각합니다!" 라는 내용을 참고

 

https://github.com/starkoora/wanted-pre-onboarding-challenge-fe-1/issues/27#issuecomment-1380189352

 

[질문] styled-component로 스타일 만들 때 class를 혼합해서 사용해도 될까요? · Issue #27 · starkoora/wanted

위에 코드 처럼 큰 틀은 styled-components로 감싸고 안에 요소들은 class로 지정해서 스타일 주곤 하는데 1주차 강의 때 멘토님이 코드 가독성, 변수 네이밍 규칙 통일 이러한 것들을 잠깐 언급 하셨는

github.com

 

참고자료 출처: https://jongminfire.dev/css-in-js

 

CSS-in-JS

CSS-in-JS? CSS-in-JS는 스타일 정의를 css나 scss 파일이 아닌 JavaScript로 작성된 컴포넌트에 바로 삽입하는 스타일 기법이다. 기존 웹사이트는 HTML, CSS, JavaScript…

jongminfire.dev

 

댓글