ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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는 사용자가 웹과 상호작용할 때 느끼는 전반적인 반응성과 직결)

     

     

Designed by Tistory.