🚀   새로운 블로그로 이전했습니다.

styled-components 과 emotion, 도대체 차이가 뭔가?

2022.02.10
6분

React에서는 보통 CSS-in-JS을 통해 스타일 작업을 진행한다.
그중에서 styled-components, emotion이 가장 유명하고 많이 사용된다.

<div css={[style, themes[theme], sizes[size]]} />
  
const themes = {
  primary: css`
    color: red;
  `,  
  secondary: css`
    color: blue;
  `
}
const sizes = {
  small: css`
    fontSize: 0.75rem;
  `,
  medium: css`
    fontSize: 1rem;
  `
}

하지만 도대체 차이가 뭘까?


type ThemeType = keyof typeof themes;
type SizeType = keyof typeof size;


제공하는 기능 비교


libraryAttaching PropsMedia QueriesGlobal StylesNested SelectorsServer Side RenderingTheming SupportComposition
styled-componentsYesYesYesYesYesYesYes
emotionYesYesYesYesYesYesYes
  • 전반적인 스타일 기능은 똑같다.
  • 둘다 sass문법을 사용하기에 스타일 문법에도 차이가 없다.
  • 참고




사용 트랜드






용량? 성능?


블로그, 사이트들을 참고하면 대게 emotion이 styled-components보다 조금 가볍고 빠르다고 한다.

먼저 https://bundlephobia.com/ 를 참고해서 최신 라이브러리 번들 사이즈를 살펴보자.

보통 emotion을 사용한다면 위 두가지 라이브러리를 모두 사용한다.
emotion 패키지 차이는 여기 참고.

눈대중으로 보면 라이브러리 용량이 비슷해보인다. (1~2 kb 차이)
다만 @emotion/react만 사용한다면 용량이 1.5배 정도 차이가 난다.



그렇다면 속도 차이는 어떨까?

다양한 자료를 참고해보면 emotion이 근소하게 더 빠르다.
참고 1, 참고 2, 참고 3

하지만 2020 styled-component v5 ?
여기 참고에 따르면 styled-components가 조금 더 빠르다고 한다.

결론. 성능상 둘은 유의미하게 차이가 나지 않는다.
emotion의 퍼포먼스가 전반적으로 더 좋게 나오고 있고 라이브러리 버전에 따라서 차이가 발생할 수 있다.





emotion의 차별점


css props 기능

  • 인라인 스타일을 작성하지만 클래스가 되는 매직 ✨
<div style={{color: "red"}}/>

기존 style 속성은 HTML 인라인 스타일로 주입이 된다.
스타일 우선순위를 다루기 어렵고 스타일 재활용도 힘들다.

<div css={{color: "red"}} /> {/* 혹은 */}
<div css="{css`color:" red`} />

emotion jsx에서 제공해주는 css 속성을 활용하면 이를 클래스로 변환해준다.
기존 인라인으로 사용할 수 없었던 media query, pseudo selector, nested selector 등을 사용할 수 있다.


  • css props를 결합하여 복잡한 스타일링을 진행할 수 있다.

    <div css={[style, themes[theme], sizes[size]]} />
      
    const themes = {
      primary: css`
        color: red;
      `,  
      secondary: css`
        color: blue;
      `
    }
    const sizes = {
      small: css`
        fontSize: 0.75rem;
      `,
      medium: css`
        fontSize: 1rem;
      `
    }
    

    위와 같이 css 변수를 조립하여 컴포넌트 스타일링을 진행할 수 있다.

    type ThemeType = keyof typeof themes;
    type SizeType = keyof typeof size;
    

    typescript로 자동 타입지정까지 할 수 있는 이점이 있다.

    css override는 덤



SSR



개인적으로 생각하는 단점

  • 파일마다 /** @jsx jsx */ 라는 JSX Pragma를 작성해야하는데 이를 설정하기 귀찮다.
  • 이는 React의 jsx와 똑같은 원리이다.
    import React from "react"을 해줘야 컴파일이 된다.

    emotion의 jsx로 변환되어야 emotion의 css props 문법을 사용할 수 있다.
    <img src="avatar.png" />jsx('img', { src: 'avatar.png' })

react처럼 webpack단에서 이를 자동으로 주입시킬 수 있지만 역시 설정하기 귀찮다...
개인적으론 storybook 웹팩 설정에서 꽤나 골머리 아팠다...





결론


  • 유의미한 성능차이가 있는 것이 아니다. 라이브러리 버전에 따라 달라질 수 있다.

  • 개발팀에서 더 익숙한 것을 사용하면 될 것 같다.

  • emotion의 css props로 css를 더 활용도 높게 조립할 수 있다. 하지만 안쓰면 그만이다.

  • SSR에서는 emotion 세팅시 더 간편하다.



참고

https://ideveloper2.dev/blog/2019-05-05--thinking-about-emotion-js-vs-styled-component/
https://github.com/andreipfeiffer/css-in-js/blob/main/README.md#styled-components
https://brunch.co.kr/@kmongdev/17