⚡ 프로필 렌더링 최적화 – 데이터 로딩 방식 개선기

조준형·2025년 4월 11일
0

CHOP!

목록 보기
18/20
post-thumbnail

기존에는 Profile.tsx 컴포넌트 내부에서 Wing을 통해 데이터를 바로 요청하고, 그 결과를 받아서 렌더링하는 방식으로 구성되어 있었다. 하지만 이 방식은 렌더링 타이밍이 비동기 요청에 묶이는 구조였기 때문에, 프로필 화면이 표시되기까지 시간이 오래 걸리는 문제가 있었다.

🐢 기존 구조: 컴포넌트 안에서 바로 요청

useEffect(() => {
  const myProfileWing = GetMyProfileWing();
  const response = await shootingStar.launch(myProfileWing);
  setMyProfileData(response.data);
}, []);

이렇게 하면 useEffect 내부에서 데이터를 받아올 때까지 기다려야 컴포넌트가 의미 있는 데이터를 갖게 됨

여러 요청이 겹칠 경우(유저 정보, 프로필 정보, 팔로잉/팔로워 등) 초기 렌더 속도에 악영향

⚙️ 개선 방식: 공통 유틸 함수 분리

우리는 이 요청 로직을 아래와 같이 유틸 함수로 분리했다:

// utils/my/profile.ts
export const getMyProfile = async () => {
  const profileWing = GetMyProfileWing(profileParams);
  const response = await shootingStar.launch<ProfileData>(profileWing);
  return response.data;
};

export const updateMyProfile = async (body: KeplerBody) => {
  const patchWing = PatchMyProfileWing(body);
  const response = await shootingStar.launch<ProfileData>(patchWing);
  return response.data;
};

✨ 장점

  • 공통 로직을 분리해서 여러 곳(Profile, MenuBar 등)에서 재사용 가능

  • 코드의 가독성과 유지보수성 향상

  • useEffect 내부 코드가 간결해지고, 실제 렌더링 타이밍도 보다 명확해짐

  • 코드 흐름을 테스트하거나 수정할 때 단위 테스트와 디버깅이 쉬움

🧪 실제 사용 예

useEffect(() => {
  const fetchData = async () => {
    const myProfile = await getMyProfile();
    setMyProfileData(myProfile);
  }
  fetchData();
}, []);

🚀 성능 개선 체감 포인트

  • useEffect에 로직이 덜 얽혀서 렌더링 로딩이 눈에 띄게 빨라짐

  • 중복된 API 호출이 줄어들고, 공통 로직의 실행 시점을 제어하기 쉬움

  • 특히 여러 API 호출이 겹치는 Profile 페이지나 MenuBar 같은 경우에 UX 향상이 분명히 느껴짐

🤔 왜 더 빨라졌을까?

유틸 함수로 분리했다고 해서 네트워크 요청 속도가 갑자기 빨라지는 것은 아니다. 하지만 다음과 같은 구조적 이점들이 결과적으로 사용자에게는 '더 빠른 UI'처럼 체감되도록 만든다.

  1. 렌더링 타이밍이 명확하게 분리된다
  • 비동기 요청을 유틸 함수 바깥으로 빼냄으로써, React의 렌더링 시점과 요청 타이밍이 덜 얽히게 된다.
  • 이는 곧 React의 리렌더 사이클이 불필요하게 지연되지 않도록 해준다
  1. 상태 관리 흐름이 깔끔해진다
  • useEffect 내에서 비즈니스 로직이 쌓이면 상태 관리가 복잡해지고, 상태 변화에 따라 발생하는 사이드 이펙트도 늘어난다
  • 유틸 함수로 분리하면서 데이터 흐름이 선형적으로 정리되어 버그 가능성이 줄어든다
  1. 중복 호출 및 불필요한 리렌더링 방지
  • 여러 컴포넌트에서 같은 데이터를 요청할 때, 유틸 함수 내부에서 메모이제이션이나 캐싱 처리를 할 수 있는 구조로 발전시킬 수 있다
  • 예를 들어, 한 번 요청한 프로필 데이터를 메모리에 저장해두고, 이후 동일한 요청에는 서버 호출 없이 그 값을 재사용하는 구조로 만들 수 있다
  • 이렇게 하면 불필요한 API 호출을 줄이고, 전체 애플리케이션의 네트워크 비용도 절감할 수 있다
  1. 디버깅 및 테스트 용이
  • 데이터 요청 단위가 명확하게 함수화되면, 개별 API 요청 단위로 mocking 하거나 테스트하기 쉬움

결국 이 모든 구조적 장점이 결합되면서, 사용자 입장에서는 딜레이가 적고 즉각적인 인터페이스처럼 느껴지게 되는 것이다.

📦 회고

"자주 쓰는 요청은 유틸 함수로 분리하라"

이번 개선에서 배운 건 단순한 성능 최적화뿐만 아니라,
공통으로 사용하는 요청 로직은 유틸화하면 가독성 + 유지보수 + 재사용성까지 다 잡을 수 있다는 점이었다.

앞으로도 데이터 요청이 반복되는 패턴이 있다면, 전략적으로 유틸 분리부터 고려해야겠다.

profile
코린이

0개의 댓글