hyejuPortfolio
Back
PORTFOLIO개인 포트폴리오 사이트
PORTFOLIO 목업
간단 소개이미지간단 소개

이 포트폴리오는 프론트엔드 개발자로서의 기술 역량과 프로젝트 경험을 보여주기 위해 제작한 웹사이트입니다. 최신 스택(Next.js, TypeScript, TailwindCSS 등)을 활용하여 애니메이션, 실시간 기능(Socket.io), 프로젝트별 상세 페이지를 구현했으며, 기여도와 트러블슈팅 과정을 기록했습니다. 사용자 친화적인 인터랙션과 시각적 요소를 통해 개발 역량뿐 아니라 디자인 감각과 사용자 경험에 대한 고민을 담았습니다.

작업 기간이미지작업 기간

2025.06. - 2025.08.

프로젝트 유형이미지프로젝트 유형

개인 프로젝트

프로젝트 관련 링크이미지프로젝트 관련 링크
기술 스택이미지기술 스택
#Next.js v15
#Typescript
#TailwindCSS
#Socket.io
#Vercel
#Render
#Github Actions
구현한 기능이미지구현한 기능
  • 포트폴리오 기능 1

    Socket.io 기반 접속자 수 집계

    • 이벤트 기반 접속자 수 관리

      서버에서 connection / disconnect 이벤트를 감지하여 viewers 값을 실시간 증감 사용자가 접속하면 viewers++, 접속 종료 시 viewers-- 처리

    • 실시간 브로드캐스트

      접속자 수 변동 발생 시 updateViewers 이벤트를 모든 클라이언트에 즉시 전송 모든 클라이언트가 동일한 접속자 수 상태를 공유하도록 보장

    • 클라이언트 상태 동기화

      클라이언트는 socket.io-client로 서버와 연결 updateViewers 이벤트를 수신할 때마다 React useState를 업데이트하여 UI에 즉시 반영

  • 포트폴리오 기능 2

    Render 무료 서버 환경 최적화

    • 서버 슬립 방지

      GitHub Actions 워크플로우를 작성하여 5분마다 서버에 Ping 요청 Render 무료 서버의 비활성화 문제를 방지해 항상 응답 가능한 상태 유지

    • API 호출 절감

      기존 Polling(3초마다 호출) 대비 요청 횟수 약 85% 감소 서버 리소스 낭비 방지 및 안정성 확보

  • 포트폴리오 기능 3

    커스텀 UX 요소

    • CustomCursor 컴포넌트

      마우스 위치 추적 및 hover 상태에 따른 커서 크기/효과 변경선

    • 시각적 차별화

      mix-blend-difference 적용으로 다양한 배경에서 가독성 확보 포트폴리오 사이트의 인터랙티브 경험 강화

트러블 슈팅이미지트러블 슈팅

접속자 수 집계 방식 개선

초기에는 3초마다 /api/viewers를 호출하는 Polling 방식으로 접속자 수를 관리했으나, Render 무료 서버 특성상 불필요한 요청이 누적되면서 응답 지연과 다운타임이 발생하였습니다.
해결 과정

해결 과정

WebSocket 기반 Socket.io 로 전환하여 이벤트 발생 시점에만 접속자 수 업데이트

서버에서 연결/해제 이벤트 감지 후 모든 클라이언트에 즉시 브로드캐스트

GitHub Actions 워크플로우를 추가해 5분마다 Ping → 서버 슬립 방지

결과

결과

API 호출 횟수 약 85% 감소

접속자 반영 속도 3초 지연 → 실시간(0ms 체감)

서버 다운타임 월 10~15회 → 0회

사용자 경험(UX) 개선

배운 점

배운 점

Polling과 WebSocket의 차이를 이해하고 불필요한 요청 최소화 방법 습득

Socket.io를 활용한 실시간 아키텍처 설계 경험

Github Actions 로 서버 가용성을 유지하며 CI/CD 파이프라인 구축 경험

전체 서비스 라이프사이클(개발→배포→운영) 경험 습득

CustomCursor 성능 최적화

mousemove 이벤트는 마우스가 1px 움직일 때마다 발생하여, 1초에 수백 번씩 state 업데이트(setPosition)를 유발하여 불필요한 리렌더링을 초래하고 애플리케이션에 부담을 주었습니다.
해결 과정

해결 과정

requestAnimationFrame 도입: 브라우저의 렌더링 주기에 맞춰 state를 업데이트하도록 로직을 변경

requestAnimationFrame 을 통해 모니터 주사율(e.g., 60fps)에 맞춰 1초에 60번만 렌더링이 일어나도록 제어 → 불필요한 렌더링을 막고 애니메이션을 부드럽게 만듦

useCallback으로 함수 메모이제이션: move 함수를 useCallback으로 감싸 useEffect의 의존성 관리

→ 컴포넌트 리렌더링 시 불필요하게 이벤트 리스너가 해제되고 다시 등록되는 과정을 방지하여 안정성을 높임

결과

결과

마우스 이동 시 렌더링 횟수: ~n00 fps → ~60 fps (약 90~95% 감소)

렌더링 지연: 8~12 ms → 2~3 ms (약 75~83% 감소)

커서 애니메이션 부드러움: 끊김 발생 → 부드러운 움직임으로 사용자 몰입감 증가

배운 점

배운 점

requestAnimationFrame을 활용하면 브라우저 렌더링 주기에 맞춰 효율적으로 state 업데이트 가능

불필요한 이벤트 리스너 재등록을 방지하면 성능 안정성과 코드 유지보수성이 향상됨

성능 최적화는 UX 개선과 직결되며, 작은 디테일도 사용자 경험에 큰 영향을 줄 수 있음

React와 브라우저 이벤트를 함께 사용할 때는 렌더링 비용을 항상 고려해야 함

PORTFOLIO | FE 현혜주 포트폴리오