Next.js

CSS-in-JS vs Tailwind CSS: Next.js에서 무엇이 더 나을까?

윤서이 2024. 10. 8. 23:36

최근 토이 프로젝트에서 Next.js와 함께 Emotion을 사용해 스타일링을 시도했습니다. 그런데 한 분이 "Next.js는 CSS-in-JS에 이슈가 있어요!"라고 조언해 주시더라고요. 왜 그런 걸까 궁금해졌고, 공식 문서에서도 Tailwind CSS를 추천하는 이유가 뭘까 고민해 보았습니다. 이번 글에서는 Next.js에서 CSS-in-JS 대신 Tailwind CSS를 추천하는 이유와 각 방식의 장단점을 정리해 보았습니다. 🤔

 

Tailwind CSS란?

Tailwind CSS는 다양한 유틸리티 클래스를 제공하는 CSS 프레임워크입니다. 예를 들어 bg-blue-500이나 text-center 같은 클래스만으로 배경색이나 텍스트 정렬을 간단하게 설정할 수 있죠. 스타일을 개별 클래스로 나누어 제공하기 때문에, 디자인을 빠르고 유연하게 구현할 수 있는 큰 장점이 있습니다.

이 유틸리티 클래스들은 작고 독립적이어서 필요한 기능만 골라서 사용할 수 있습니다. 덕분에 불필요한 CSS 코드가 줄어들고, 일관성을 유지하면서도 중복을 최소화할 수 있어요.

<div className="hidden md:flex-col md:flex md:space-y-0">
  <div className="flex-shrink-0 h-[118px] w-[214px] bg-black flex justify-center items-center overflow-hidden">
    <img
     className="w-full"
     src={thumbnailImage}
     onError={handleImageError}
     alt={isLoading ? 'loading' : currentSongTitle}
    />
  </div>
</div>

 

 

CSS-in-JS란?

CSS-in-JS는 말 그대로 자바스크립트 안에 CSS를 넣어 사용하는 방식입니다. 대표적인 예로는 Styled-components와 Emotion이 있습니다. 컴포넌트 단위로 스타일을 독립적으로 관리할 수 있다는 점에서 큰 장점이 있죠. 게다가 동적인 스타일 적용도 가능해 매우 유연하게 스타일을 작성할 수 있습니다.

이 방식은 코드와 스타일링을 한 곳에서 관리할 수 있어서 개발할 때 편리합니다. 특히 컴포넌트 단위로 작성되기 때문에, 특정 컴포넌트의 스타일을 빠르게 찾고 수정할 수 있는 점이 매력적입니다.

const Title = ({ title, className, element }) => {
  return (
    <TitleContainer className={className}>
      <h2>{title}</h2>
      {element}
    </TitleContainer>
  );
};

export default Title;

const TitleContainer = styled.div`
  padding-left: 20px;
  padding-right: 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;

  h2 {
    font-size: ${fontSize.xl};
  font-weight: ${fontWeight.bold};
  }
`;

 

 

Next.js와 Tailwind CSS 조합의 장점은?

Next.js는 SSR(서버 사이드 렌더링)과 SSG(정적 사이트 생성) 기능을 지원합니다. 여기에 Tailwind CSS를 더하면, 빌드 시 최적화된 CSS 파일을 생성하여 성능을 크게 향상시킬 수 있습니다.

1. 최적화된 빌드 과정

Tailwind CSS는 'Purge' 기능을 통해 사용되지 않는 CSS를 빌드할 때 자동으로 제거해 줍니다. 이 과정을 통해 최종 CSS 파일의 크기를 최소화하여 페이지의 로딩 속도가 빨라집니다. 최신 버전의 Tailwind CSS에서는 JIT(Just-in-Time) 모드가 도입되어, 빌드 타임이 아니라 필요한 시점에 스타일을 생성해 개발 속도를 더 빠르게 합니다.

2. 빠른 초기 로딩 속도

SSR 환경에서는 초기 로딩 속도가 매우 중요합니다. Tailwind CSS는 필요한 스타일만 포함된 작은 CSS 파일을 생성해 주기 때문에 초기 로딩 시 필요한 리소스의 양이 줄어듭니다. 이는 페이지 로딩 속도를 높여주며, 사용자에게 더 나은 경험을 제공합니다.

3. FOUC(Flash of Unstyled Content) 방지

서버에서 렌더링된 페이지가 클라이언트로 전달될 때, 스타일이 바로 적용되지 않으면 페이지가 잠시 동안 스타일 없이 표시될 수 있는데, 이를 FOUC라고 합니다. Tailwind CSS는 유틸리티 클래스 기반의 스타일링을 사용하고, 스타일이 빌드 타임에 이미 포함되어 있기 때문에 SSR을 사용할 때 FOUC 현상을 줄일 수 있습니다. 이는 사용자에게 보다 깔끔하고 부드러운 로딩 경험을 제공하는 데 도움이 됩니다.

 

 

Styled-components의 지원 방식

Next.js는 Styled-components와 같은 CSS-in-JS 라이브러리를 지원합니다. 이 지원은 서버 측에서 스타일을 미리 생성하여 HTML에 주입하는 방식으로 이루어집니다. SSR 과정에서 Styled-components가 생성한 스타일을 추출하고, 이를 초기 HTML에 인라인으로 삽입하여 클라이언트가 페이지를 로드할 때 스타일이 즉시 적용되도록 합니다. 이를 통해 런타임 스타일 생성에 따른 성능 문제를 어느 정도 완화할 수 있지만, 여전히 Tailwind CSS처럼 빌드 타임에 최적화된 정적 CSS를 사용하는 것보다 초기 로딩 속도가 느릴 수 있습니다.

 

 

CSS-in-JS의 호환성 문제?

Next.js와 CSS-in-JS 조합을 사용할 때 가장 큰 문제는 런타임에서 스타일을 생성하고 적용하기 때문에 발생하는 성능 이슈입니다. 특히 SSR 환경에서는 서버 측에서 렌더링된 HTML에 스타일을 추가로 주입하는 과정이 필요합니다. 이 과정에서 스타일을 계산하고 적용하는 데 시간이 걸리기 때문에 초기 로딩 속도가 느려질 수 있으며, 사용자 경험에 부정적인 영향을 미칠 수 있습니다.

반면 Tailwind CSS는 빌드 타임에 모든 스타일을 미리 계산하고 생성하기 때문에, SSR 환경에서 성능 문제를 줄일 수 있는 큰 장점이 있습니다.

 

 

 

 

Tailwind CSS의 단점

그렇다고 해서 Tailwind CSS가 완벽한 것은 아닙니다. 몇 가지 단점이 있습니다.

  • 초기 학습 곡선: 다양한 유틸리티 클래스 이름을 익히는 데 시간이 필요합니다.
  • HTML 복잡성: HTML 요소에 많은 클래스를 추가하면 코드가 길어져 가독성이 떨어질 수 있습니다. 특히 중첩 요소를 다룰 때 클래스 조합이 복잡해질 수 있습니다.
  • 커스터마이징의 어려움: 특정 요소에 커스텀 스타일을 적용하기 어렵고, 추가 설정이 필요할 수 있습니다.

 

https://tailwindcss.com/docs/utility-first

 

결국 Next.js에서 어떤 스타일링 방식을 선택할지는 프로젝트의 성격과 개인의 선호도에 따라 달라질 것입니다. 만약 빠른 로딩 속도와 최적화된 성능이 중요하다면 Tailwind CSS가 좋은 선택이 될 수 있습니다. 반면에 컴포넌트별로 유연하게 스타일링하고 싶다면 CSS-in-JS가 더 적합할 수 있습니다.

여러분은 어떤 스타일링 방식을 더 선호하시나요? 각자의 경험을 공유해 주세요! 다른 개발자들에게 큰 도움이 될 것입니다. 😊