← 포트폴리오로 돌아가기

Wikied

기간: 2024.05 ~ 2024.07 (초기 개발)추가 작업 및 리팩토링: 2024.08 ~ 2025.03

개발 인원: 1명

프로젝트 소개

Wikied는 사용자들이 자유롭게 인물에 대한 문서를 생성하고 편집할 수 있는 플랫폼입니다. 생성한 위키 페이지의 링크를 복사하여 친구들과 공유할 수 있으며, 그들이 함께 작성하도록 초대할 수 있습니다. 또한, 자유게시판에서 글을 작성할 수 있으며, 많은 좋아요를 받은 글은 베스트 게시글에 오를 수 있습니다.

기술 스택

CSSModules logoCSSModules
TypeScript logoTypeScript
React logoReact
NextJs logoNextJs
ReactQuery logoReactQuery
Zustand

주요 작업

낙관적 업데이트 적용으로 UI 반응 속도 개선

API 응답 대기 시간으로 인한 UI 반응 속도 저하 문제를 낙관적 업데이트 적용으로 해결

  • React QueryuseMutation 훅을 활용한 낙관적 업데이트를 적용하여, 데이터 변경 요청 시 UI를 즉시 변경하고 응답 실패 시 롤백하는 기능을 구현
  • UI 반응 속도를 약 60% 개선하여 사용자 인터랙션에 대한 즉각적인 피드백 제공 및 데이터 정합성 유지

검색 기능 성능 최적화

사용자 입력 중복으로 인한 불필요한 API 호출 및 서버 부하를 줄이기 위한 검색 기능 성능 최적화를 진행

  • lodashdebounce 를 적용하여 사용자 입력이 멈춘 후 500ms 뒤에만 API 호출되도록 구현
  • 엔터키 입력이나 검색 버튼 클릭 시 대기 중인 debounce 작업을 즉시 취소하는 로직 추가
  • 16자 입력 시 API 호출 횟수를 약 94% 감소시켜 서버 부하와 네트워크 트래픽 크게 절감

Streaming SSR 적용으로 렌더링 성능 최적화

전체 페이지가 로딩된 후에야 렌더링되는 문제를 해결하기 위해 Streaming SSR을 도입하여 초기 로딩 속도와 사용자 경험을 개선했습니다.

  • React Suspense 기반의 Streaming SSR을 활용, 비동기 데이터가 필요한 컴포넌트(댓글 등)를 지연 렌더링 처리
  • LCP를 약 12.5% 개선하고, 주요 콘텐츠가 먼저 노출되도록 구현하여 사용자 체감 속도 향상

SVG 최적화 및 초기 렌더링 속도 개선

최적화되지 않은 SVG로 인한 초기 렌더링 지연 문제를 해결하기 위해 SVG 최적화 전략을 수립하고 적용했습니다.

  • SVGR, SVGO 등을 활용하여 SVG를 컴포넌트화하고 용량을 최적화
  • LCP를 약 28% 개선하고 렌더링 시간을 약 44% 단축하여 초기 화면 노출 속도 향상

페이지네이션 성능 최적화

페이지 전환 시 데이터 중복 요청으로 인한 로딩 시간 증가 및 사용자 경험 저하를 해결

  • React QueryuseQuery 훅과 placeholderData 옵션을 사용하여 페이지 전환 시 이전 데이터를 즉시 표시하며 새로운 데이터를 백그라운드에서 요청하는 방식 적용
  • 로딩 시간을 약 44% 단축, 화면 깜빡임 감소, 최대 지연 시간을 약 51% 개선하여 사용자에게 부드러운 페이지 전환 경험 제공

효율적인 문서 작성 인터페이스 구축

마크다운 기반 편집기 구현을 위해 React Quill 라이브러리를 도입하여, 비기술적인 사용자도 쉽게 문서를 작성할 수 있는 환경 구축

  • React Quill 라이브러리를 선택하고, 프로젝트 요구사항에 맞게 초기 설정 및 통합 작업 진행
  • 텍스트 형식, 링크 등 핵심 편집 기능을 구현하여 개발 시간 단축생산성 향상에 기여
  • 라이브러리 활용을 통해 사용자 접근성 및 편의성을 개선

반응형 디자인 적용으로 최적화된 사용자 경험 제공

모바일, 태블릿, 데스크탑 등 다양한 디바이스에서 일관되고 최적화된 사용자 경험을 제공하기 위해 반응형 디자인을 적용

  • 다양한 화면 크기에 맞춰 레이아웃과 콘텐츠가 자동으로 조정되도록 구현
  • 어떤 디바이스에서도 일관되고 최적화된 UI/UX를 제공하여 사용자 편의성과 접근성을 개선

트러블슈팅

Streaming SSR 적용으로 초기 렌더링 속도 개선

📌 문제 배경

초기에는 Article 페이지 전체 콘텐츠가 모두 준비된 후에야 화면이 렌더링되는 구조였습니다. 이로 인해, 사용자가 첫 번째 주요 콘텐츠를 보기까지 지연이 발생했고, LCP가 2.4초로 기준선에 근접한 느린 수준이었습니다. 특히, 댓글(CommentSection)처럼 비동기 데이터를 필요로 하는 컴포넌트가 병목으로 작용하여 초기 화면 렌더링을 지연시켰고, 사용자 체감 속도가 저하되는 문제가 있었습니다.

🔍 원인 분석

  • 모든 컴포넌트가 준비될 때까지 HTML 전송이 지연
  • 비동기 컴포넌트가 초기 렌더링 병목을 유발
  • React의 SSR 방식이 전체 페이지를 묶어 렌더링하는 구조로 UX에 불리하게 작용

🛠 해결 과정

  1. React Suspense 기반의 Streaming SSR 적용
    • Next.js의 App Router 환경과 React Suspense를 활용하여, 주요 콘텐츠와 댓글을 독립적인 <Suspense>로 분리
    • fallback={<Skeleton />}을 사용해 주요 콘텐츠(ArticlePage)는 먼저 렌더링되고, 댓글(CommentSection)은 백그라운드에서 병렬 로딩
  2. 서버 콘솔 로그를 통해 Streaming SSR 적용 여부 검증
    • 각 컴포넌트에 console.log()를 삽입하여 순차 렌더링 확인
    • ArticlePage → CommentSection 순서로 출력되어 Streaming 방식으로 전달되고 있음을 확인

✅ 결과

  • LCP 약 12.5% 단축(2.4초 → 2.1초)
  • 주요 콘텐츠가 더 빨리 렌더링되어 사용자 체감 속도 개선
  • 댓글 컴포넌트를 백그라운드에서 로딩하여 UX 분리 및 체감 성능 향상

🧠 배운 점

Streaming SSR을 적용하면 모든 콘텐츠를 기다리지 않고 주요 콘텐츠를 먼저 렌더링할 수 있어, 초기 반응성(LCP)사용자 경험을 효과적으로 개선할 수 있음을 체감했습니다. 특히, React Suspense와 Next.js의 지원을 활용하면 점진적인 페이지 로딩 전략이 구현 가능하며, 이는 UX와 SEO 모두에 긍정적인 영향을 미친다는 점을 실감했습니다.

SVG 최적화 및 렌더링 성능 개선

📌 문제 배경

초기 프로젝트에서는 SVG 아이콘을 직접 인라인으로 삽입하거나, public/ 폴더에 저장한 후 <Image> 태그로 불러오는 방식으로 사용했습니다. 하지만, SVG 파일 용량이 커지고, 불필요한 속성이 포함되어 렌더링 속도가 저하되는 문제가 발생했습니다. 특히, 자주 사용되는 아이콘이 여러 번 렌더링되면서 초기 로딩 시간이 증가했고, Lighthouse 성능 점수에서도 LCP(최대 콘텐츠 페인트) 지연이 확인되었습니다.

🔍 원인 분석

  • SVG 파일이 최적화되지 않아 불필요한 속성과 중복된 코드가 포함
  • SVG가 직접 인라인으로 삽입되면서 DOM이 복잡해짐
  • 필요하지 않은 fill, stroke 속성이 유지되면서 스타일 오버라이드가 어려움
  • SVG 파일 크기가 커질수록 브라우저 렌더링 속도 저하

🛠 해결 과정

  1. SVGR을 활용하여 React 컴포넌트로 변환
    • SVG 아이콘을 React 컴포넌트로 변환하여 필요할 때만 렌더링하도록 변경
    • fill, stroke 속성을 props로 받아 동적으로 스타일 변경 가능하도록 처리
  2. SVGO를 사용하여 불필요한 속성 제거 및 용량 최적화
  3. SVG 사용 방식 개선
    • 자주 사용되는 아이콘 → SVGR을 활용한 React 컴포넌트 변환
    • 한 번만 사용되는 이미지 → public/ 폴더에 저장 후 next/image 활용

✅ 결과

  • LCP 시간 28% 단축
  • 불필요한 SVG 속성 제거 후 렌더링 시간 약 44% 단축
  • React에서 불필요한 리렌더링을 줄이면서 최대 지연 시간 약 51% 감소

🧠 배운 점

SVG 최적화는 단순한 파일 크기 감소뿐만 아니라 렌더링 성능과 유지보수성에도 큰 영향을 준다는 것을 확인했습니다. SVGRSVGO를 함께 활용하면 아이콘을 효율적으로 관리할 수 있고, 브라우저 성능도 최적화할 수 있습니다.

Next.js 내장 모달 라우팅 vs React 포털 선택

📌 문제 배경

Next.js의 내장 모달 라우팅을 사용하여 모달을 열고 닫는 기능을 구현할 때, URL 변경이 계속 발생하면서 Params와 배경 상태를 일관되게 관리해야 하는 문제가 생겼습니다. 모달 상태를 라우팅과 동기화하려다 보니 코드가 복잡해지고, URL과 UI 상태를 일관되게 유지하는 데 추가적인 관리가 필요해졌습니다. 이러한 과정에서 라우팅 의존성이 과도하게 커지는 점이 불편함을 느꼈습니다.

🔍 원인 분석

  • Next.js 내장 모달 라우팅을 사용한 방식에서는, URL 상태와 모달의 상태를 동기화하려면 복잡한 코드가 필요
  • URL이 변경되는 특성상, 모달 상태와 UI를 관리하는 과정이 번거로움

🛠 해결 과정

  1. Next.js 내장 모달 라우팅을 사용한 방식에서는, URL 상태와 모달의 상태를 동기화하려면 복잡한 코드가 필요했지만, URL이 변경되는 특성상, 모달 상태와 UI를 관리하는 과정이 번거로워짐
  2. 이를 해결하기 위해, Root Layout에서 React 포털을 사용하여 모달을 URL과 독립적인 상태로 관리했으며 이렇게 하면 URL 변경 없이 모달의 상태를 간단하게 관리할 수 있었고, UI와 라우팅의 복잡성을 줄일 수 있게됨

✅ 결과

  • URL과 독립적으로 모달 상태를 관리하여 유지보수성 개선
  • UI와 라우팅의 복잡성을 줄여 코드 간소화 및 개발 생산성 향상

🧠 배운 점

Next.js 내장 모달 라우팅은 URL을 통해 모달 상태를 기록하고 브라우저 히스토리를 유지하는 데 유용하지만, 복잡한 UI 상태 관리가 필요한 경우에는 과도한 접근 방식이 될 수 있습니다. 반면에, React 포털을 사용한 모달은 URL과 독립적인 상태 관리가 가능하며, 간단한 UI 관리가 필요할 때 효율적인 방법입니다. 프로젝트에서 상황에 맞는 기술을 선택하는 중요성을 깨닫게 되었고, 단순한 UI 관리에는 React 포털, 상태 관리와 라우팅 연동이 중요한 경우에는 내장 모달 라우팅을 사용하는 것이 효과적이라는 점을 알게 되었습니다.