목차
1. 배경
2. 과정: Tailwind로 전환한 이유
1. 배경
해당 reracle 프로젝트는 초기에는 4명의 팀원과 함께 협업하여 진행되었습니다. 하지만 프로젝트가 진행되면서 팀의 방향성에 이견이 생겨 협업이 중단되었고, 결국 프로젝트를 혼자 이어가게 되었습니다. 단독으로 프로젝트를 운영하면서, 스타일링 라이브러리를 다시 고민하게 되었습니다. 특히, 코드 복잡성을 줄이고, 스타일링 효율을 높이며, 성능 최적화를 이루고자 Styled-components에서 Tailwind CSS로 전환하기로 결정했습니다.
import { useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import styled from 'styled-components';
import { wasteCategories } from '@/lib/constants/wasteCategories';
import { useSearchStore } from '@/lib/store/useSearchStore';
const StyledSearchContainer = styled.div`
position: relative;
width: 37vh;
`;
const StyledSearchInput = styled.input`
width: 37vh;
height: 5vh;
font-size: 2vh;
border: none;
font-family: var(--font-weight-medium);
color: var(--color-gray-dark);
&:focus {
outline: none;
box-shadow: none;
}
`;
const ResultsContainer = styled.ul`
position: absolute;
width: 37vh;
height: auto;
top: 5vh;
list-style: none;
margin-top: 1vh;
background-color: #ffffff;
border: 1px solid var(--color-purple);
border-radius: 0.5vh;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
z-index: 1000;
`;
const ResultItem = styled.li`
padding: 1.2vh;
font-size: 2vh;
cursor: pointer;
&:hover {
background-color: #f0f0f0;
}
`;
const SearchBar = () => {
const [searchQuery, setSearchQuery] = useState<string>('');
const [searchResults, setSearchResults] = useState<
{
categoryId: string;
id: string;
name: string;
img?: string;
disposalMethod?: string;
}[]
>([]);
...
return (
<StyledSearchContainer>
<form onSubmit={handleSubmit}>
<StyledSearchInput
type="text"
value={searchQuery}
onChange={handleSearch}
placeholder="검색어를 입력하세요"
/>
</form>
{searchResults.length > 0 && (
<ResultsContainer ref={resultContainerRef}>
{searchResults.map((item) => (
<ResultItem key={item.id} onClick={() => handleItemClick(item.categoryId, item.id, item.name)}>
{item.name}
</ResultItem>
))}
</ResultsContainer>
)}
</StyledSearchContainer>
);
};
export default SearchBar;
2. 과정: Tailwind로 전환한 이유
1) 런타임 성능 저하 가능성
스타일을 컴포넌트 렌더링 시점에 생성하기 때문에, 렌더링 성능이 저하될 가능성이 있습니다. 이러한 성능 저하는 기본적으로 웹페이지 사용자의 경험을 떨어뜨리는 요소가 될 수 있습니다. TailwindCSS는 미리 컴파일된 CSS 클래스를 사용하므로 성능이 더욱 향상됩니다.
2) 번들 크기 감소
- Styled Components
- 최소화된 크기: 30.2 kB
- Gzip 압축 후 크기: 11.1 kB
- Tailwind CSS
- 개발 빌드 (압축 전): 2413.4 kB
- 최소화된 크기: 1967.4 kB
- Gzip 압축 후 크기: 190.2 kB
- Brotli 압축 후 크기: 46.2 kB
- 최적화 후: 일반적으로 10 kB 미만 (Gzip 압축 후)
styled-components는 스타일을 JavaScript 객체로 관리하여 번들 크기가 커질 수 있습니다. 반면, Tailwind CSS는 많은 유틸리티 클래스를 생성하지만, PurgeCSS를 사용해 사용하지 않는 스타일을 제거하면 번들 크기를 줄일 수 있다.
3) CSS 관리의 단순화
Styled-components는 스타일을 JavaScript 객체로 관리하여 번들 크기가 커질 수 있습니다. 반면, Tailwind CSS는 많은 유틸리티 클래스를 생성하지만, PurgeCSS를 사용해 사용하지 않는 스타일을 제거하면 최종 번들 크기를 크게 줄일 수 있습니다. 최소화된 크기 기준으로, Styled-components는 30.2 kB인 반면, Tailwind CSS는 최적화 후 일반적으로 10 kB 미만으로 줄어들 수 있습니다.
4) 개발자 경험(DX) 향상
Tailwind는 CSS를 인라인으로 작성하는 방식이므로 스타일을 적용하고 결과를 즉시 확인할 수 있습니다. 스타일을 빠르게 반복하고 수정할 수 있어 개발 속도가 빨라집니다. 반면, styled-components는 스타일 정의와 컴포넌트 구조 사이에 코드가 추가되면서 가독성이 떨어질 수 있습니다.
5) React DevTools의 간결함 유지
Styled-components는 DevTools에서 내부 컴포넌트가 과도하게 생성되어 트리가 복잡해지는 반면, Tailwind는 간결한 컴포넌트 트리를 보여주어 디버깅을 간편하게 합니다.
출처
'FE' 카테고리의 다른 글
REracle: 비용 효율적인 서비스 운영 (1) | 2024.12.29 |
---|---|
React PWA에서 푸시 알림 구현하기: 사용자 경험을 한 단계 업그레이드하세요 (3) | 2024.12.29 |
[최적화] suspense, lazy로 초기로딩 개선 (1) | 2024.07.23 |
단위, 통합 테스트와 테스트 도구: 이론 (1) | 2024.07.13 |
CORS 훑어보기 (0) | 2024.06.27 |