-
CSS-in-JS 성능 최적화: snowflake animation FPS 3배 향상카테고리 없음 2025. 3. 26. 16:56


개선 전 / 개선 후 (차이가 눈에 보일 정도인 것 같기도 하고..)
+ https://ideal-dl.tistory.com/26 내용인 Automator를 통해 Mac으로 기록한 영상을 gif로 변환했다.계절 별로 background image와 banner effect만 교체하는 home 전용 header를 사용하는 구조에서,

위와 같은 경고 메시지와 더불어 animation에서 과도한 성능저하가 탐지됨.
개선 전
// SnowEffect.tsx const SnowEffect = () => { const snowflakes = new Array(25).fill(0); return ( <SnowEffectContainer> {snowflakes.map((_, idx) => ( <Snow key={idx} index={idx} /> ))} </SnowEffectContainer> ); };// style.ts (일부) export const Snow = styled.div<{ index: number }>` width: ${() => randomRange(8, 20)}px; height: ${() => randomRange(8, 20)}px; animation: ${(props) => fallAnimation(props.index)} ${() => randomRange(5, 10)}s linear infinite; animation-delay: ${() => randomRange(0, -10)}s; `;Snow.tsx 컴포넌트에서 randomRange 함수와 fallAnimation을 개별적으로 호출해 스타일을 계산.
(렌더링 시마다 실행되므로, 25번 반복 호출)랜덤 값과 스타일 속성을 미리 배열에 계산하여 전달하고 재사용함으로써 성능을 개선한다.
개선 후
// SnowEffect.tsx const SnowEffect = () => { const snowflakes = Array.from({ length: 50 }, () => ({ $size: randomRange(8, 20), $delay: randomRange(0, -10), $duration: randomRange(5, 10), $startX: randomRange(-150, 150), })); return ( <SnowEffectContainer> {snowflakes.map((flake, index) => ( <Snow key={index} $size={flake.$size} $delay={flake.$delay} $duration={flake.$duration} $startX={flake.$startX} /> ))} </SnowEffectContainer> ); };// style.ts (일부) export const Snow = styled.div.attrs<SnowProps>( ({ $size, $delay, $duration, $startX }) => ({ style: { width: `${$size}px`, height: `${$size}px`, left: `${$startX}vw`, animationDelay: `${$delay}s`, animationDuration: `${$duration}s`, }, }), )<SnowProps>` animation: ${fallAnimation} linear infinite; `;

refresh 반영 이후부터 정확히 1000ms를 측정하여
[ FPS = 1000 / 프레임 렌더링 시간(밀리초) ]를 기준으로 개선 전은 5FPS, 개선 후는 15FPS로 개선됨.

TBT도 50%로 300밀리초(0.3초)정도의 프레임이 개선되며 메인 스레드 차단 시간을 줄어들었고
Home.tsx 경로 내에서 사용자 입력에 대한 응답성이 기대한 것보다 더 향상되었다.
(TBT는 사용자가 웹과 상호작용할 때 느끼는 전반적인 반응성과 직결)