개발 노하우2023-07-22 (토요일)
TailwindCSS 성능 최적화 기법
정디자인•6분 읽기
TailwindCSS 성능 최적화 기법
TailwindCSS는 직관적인 유틸리티 클래스를 통해 빠른 UI 개발을 가능하게 하지만, 대규모 프로젝트에서는 성능 이슈가 발생할 수 있습니다. 이 글에서는 TailwindCSS의 성능을 최적화하는 방법과 모범 사례를 알아봅니다.
번들 크기 최적화
1. PurgeCSS 올바르게 설정하기
TailwindCSS는 기본적으로 많은 유틸리티 클래스를 생성합니다. 프로덕션 빌드에서는 사용하지 않는 클래스를 제거하는 것이 중요합니다:
// tailwind.config.js
module.exports = {
content: [
'./src/**/*.{js,jsx,ts,tsx}',
'./public/index.html',
],
// ...
}
모든 콘텐츠 소스를 포함해야 하며, 동적으로 생성되는 클래스 이름의 경우 다음과 같이 패턴을 지정할 수 있습니다:
// tailwind.config.js
module.exports = {
content: {
files: ['./src/**/*.{js,jsx,ts,tsx}'],
safelist: [
'bg-red-500',
'text-3xl',
/^btn-/, // btn- 으로 시작하는 모든 클래스
],
},
// ...
}
2. JIT(Just-In-Time) 모드 활성화
Tailwind CSS v3부터는 JIT 모드가 기본으로 활성화되어 있습니다. 이 모드는 필요한 유틸리티만 실시간으로 생성하여 개발 환경에서의 성능을 향상시킵니다:
// tailwind.config.js (v2)
module.exports = {
mode: 'jit',
// ...
}
코드 구성 최적화
1. 커스텀 컴포넌트 활용하기
반복적인 Tailwind 클래스 조합은 컴포넌트로 추출하여 재사용성을 높이고 코드 중복을 줄입니다:
// 중복된 클래스 사용
function App() {
return (
<div>
<button className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
버튼 1
</button>
<button className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
버튼 2
</button>
</div>
);
}
// 컴포넌트로 추출
function Button({ children }) {
return (
<button className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
{children}
</button>
);
}
2. @apply 지시문 사용하기
자주 사용하는 클래스 조합은 @apply 지시문을 사용하여 CSS로 추출할 수 있습니다:
/* styles.css */
.btn {
@apply px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600;
}
그러나 @apply의 과도한 사용은 Tailwind의 장점을 줄일 수 있으므로 신중하게 사용해야 합니다.
런타임 성능 최적화
1. 조건부 클래스 결합 최적화
조건부 클래스를 효율적으로 결합하려면 clsx나 classnames 같은 라이브러리를 사용하세요:
import clsx from 'clsx';
function Button({ primary, disabled }) {
return (
<button
className={clsx(
'px-4 py-2 rounded',
primary ? 'bg-blue-500 text-white' : 'bg-gray-200 text-gray-800',
disabled && 'opacity-50 cursor-not-allowed'
)}
>
버튼
</button>
);
}
2. 동적 클래스 생성 최소화
렌더링 성능을 위해 동적으로 클래스 문자열을 생성하는 작업을 최소화하세요:
// 좋지 않은 방식
function BadComponent({ size }) {
// 매 렌더링마다 문자열 생성
const sizeClass = `text-${size}`;
return <div className={sizeClass}>텍스트</div>;
}
// 더 나은 방식
function GoodComponent({ size }) {
// 미리 정의된 매핑 사용
const sizeClasses = {
sm: 'text-sm',
md: 'text-md',
lg: 'text-lg',
};
return <div className={sizeClasses[size]}>텍스트</div>;
}