MIC GOLF - 1
MIC GOLF - 2
MIC GOLF - 3
MIC GOLF - 4

기업 협업으로 구현한 골프용품 쇼핑몰 플랫폼 - 관리자 기능과 사용자 경험을 통합한 이커머스 서비스

ReactTypeScriptTailwind CSSZustandTanstack QueryFramer MotionReact Hook FormVite

주요 기능 개발

  • 프로젝트 세팅, 배포 및 프로젝트 자동화(CI/CD)
  • 회원가입, 비밀번호 찾기, 아이디 찾기, 이메일 로그인, 소셜 로그인 (naver, kakao), 반응형
  • 메인 페이지 UI, 기능 구현, 반응형
  • 메인 페이지 CRUD 관련, 백오피스 구현
  • 장바구니 UI 구현, 반응형
  • 결제페이지 UI 구현, 결제 기능 추가(단순 결제, 비즈니스 로직제외) 반응형
  • Floating Label, header, footer 공통 컴포넌트 구현

트러블슈팅 경험

스크롤 이벤트 성능 100배 이상 개선

Home Page 컴포넌트에서 사용자가 스크롤 할 때 스크롤 위치에 맞춘 배경을 구현하기 위해 상태를 업데이트하는 로직을 작성했으나, useEffect 내부의 handleScroll 이벤트 핸들러가 과도한 리렌더링을 유발했습니다.

문제 원인

    useEffect(() => {
    const handleScroll = () => {
    // INFO: 스크롤 위치 계산
    const scrolled = window.scrollY;
    const maxScroll = window.innerHeight;
    const progress = Math.min(scrolled / maxScroll, 1);
    setScrollProgress(progress);
    console.log("진행도: ", progress);
    };
    }, []);
  • window.addEventListener("scroll", handleScroll)은 이벤트가 매우 빈번하게 발생해 상태 업데이트와 리렌더링 횟수가 증가합니다.
  • 조건적으로 출력되는 UI가 아니라 즉각적인 반응이 필요해 디바운스나 스로틀링 기법을 적용할 수 없었습니다.
  • 불필요한 연산이 계속 실행되며 말도 안 되는 수치의 상태 업데이트가 발생했고, 렌더링 증가로 브라우저 성능에도 악영향을 줬습니다.

해결 과정

const HomePage = () => {
return (
<>
{/* INFO: 백드롭 이미지 */}
<section className="relative">
<div
className="fixed z-10 h-[100vh] w-full"
style={{
backgroundImage: "이미지 경로",
backgroundSize: "cover",
}}
/>
<div className="absolute z-20 mt-[100vh] h-[400vh] w-full bg-white"></div>
</section>
{/* INFO: 백드롭 위에 보여질 컨텐츠 영역 */}
<section className="mt-screen relative px-[130px]">
<h1>Best Product</h1>
<div>
<div></div>
</div>
</section>
</>
);
};
  • position: fixed를 활용한 배경 고정 — 이미지를 고정하고, 스크롤 시 배경이 줄어드는 듯한 효과를 CSS로 연출해 상태 업데이트를 제거했습니다.
  • CSS 단위와 레이어 활용 — 100vh로 배경 높이를 고정하고, z-index를 조절해 상위 컨테이너가 자연스럽게 배경 위를 지나가도록 구성했습니다.
  • 렌더링 단 한 번만 수행 — JavaScript 상태 업데이트 없이 모든 전환을 CSS만으로 처리해 이벤트 핸들러 호출을 없앴습니다.

결과

스크롤 이벤트 성능 100배 개선
  • 기존 100회 이상 호출되던 스크롤 이벤트가 최초 1회만 호출

배운 점

  • CSS를 잘 활용하면 불필요한 이벤트를 극적으로 줄일 수 있다.
  • 정말 JS 이벤트가 필요한지, CSS로 구현 가능한지 항상 검토해야 한다.