ㅇㅅㅇ

항해플러스 프론트엔드 6기 10주차 회고 본문

항해99 플러스 프론트앤드/10주 과정

항해플러스 프론트엔드 6기 10주차 회고

소 아 2025. 10. 17. 00:15

열 번째 도전기 - 코드 관점의 성능 최적화, 사용자 경험을 위한 마지막 여정

10주간의 항해가 드디어 마지막 과제에 도달했습니다. Chapter 4-2는 프론트엔드 개발의 완성이라 할 수 있는 코드 레벨 성능 최적화를 다루는 과제였습니다. 저희는 이 과제를 통해 단순히 기능을 구현하는 것을 넘어, "사용자가 실제로 느끼는 성능"에 대해 깊이 고민하며 개발자로서의 시야를 확장했습니다.

그리고 이 모든 여정의 끝은 코치님과 팀원들과 함께한 특별한 멘토링 시간이었습니다. 10주간 쌓아 올린 지식과 경험을 '회고의 섬'이라는 형태로 시각화하고, 솔직한 대화를 통해 앞으로 나아갈 방향을 설정하며 뜻깊은 마무리를 했습니다.


과제를 통해 배운 것들

성능 측정의 중요성 - "측정 없이는 최적화 없다"

이번 과제에서 가장 인상 깊었던 부분은 React DevTools의 Profiler를 활용한 성능 측정이었습니다.

// 개선 전: Promise.all이 직렬로 실행
const fetchAllLectures = async () => await Promise.all([
  (console.log('API Call 1', performance.now()), await fetchMajors()),
  (console.log('API Call 2', performance.now()), await fetchLiberalArts()),
  // ... 중복 호출들
]);

// 개선 후: 진정한 병렬 실행과 캐시 시스템
const apiCache = new Map<string, Promise<Lecture[]>>();
const getCachedMajors = () => {
  if (!apiCache.has("majors")) {
    apiCache.set("majors", fetchMajors().then((res) => res.data));
  }
  return apiCache.get("majors")!;
};

처음에는 "이 정도면 충분하지 않을까?"라고 생각했지만, React DevTools Profiler로 실제 측정 결과를 보니 놀라웠습니다.

과제에서 제시된 목표 수치인 API 호출 최적화 20ms, 렌더링 최적화 30ms에서 거의 0ms로 개선되는 것을 직접 확인할 수 있었습니다.

Context 사용의 함정과 해결책

드래그 앤 드롭 최적화 과정에서 가장 큰 도전이었던 부분입니다.

// 문제: 단일 Context로 인한 전체 리렌더링
export const ScheduleProvider = ({ children }: PropsWithChildren) => {
  const [schedulesMap, setSchedulesMap] = useState<Record<string, Schedule[]>>(dummyScheduleMap);
  // schedulesMap이 업데이트되면 모든 컴포넌트가 리렌더링
};

// 해결: Context 분리와 선택적 구독
const subscribeToTable = (tableId: string, callback: (schedules: Schedule[]) => void) => {
  // 특정 테이블만 구독하도록 구현
};

Context를 남용하면 오히려 성능 저하를 일으킬 수 있다는 점을 몸소 체험했습니다. 적절한 Context 분리와 선택적 구독 패턴의 중요성을 깊이 이해할 수 있었습니다.

메모이제이션의 전략적 활용

단순히 React.memo를 모든 곳에 적용하는 것이 아니라, 언제 어떻게 사용해야 하는지에 대한 전략을 세울 수 있었습니다.

  • 컴포넌트 레벨: React.memo로 불필요한 리렌더링 방지
  • 함수 레벨: useCallback으로 참조 안정화
  • 계산 레벨: useMemo로 비용이 큰 연산 캐싱

특히 인피니트 스크롤에서 페이지네이션 시마다 전체 데이터를 다시 필터링하던 문제를 useMemo로 해결했을 때의 성능 향상은 정말 놀라웠습니다.

성능 최적화는 개발 과정의 일부

"일단 돌아가게 만들고 나중에 최적화하자"는 마인드가 얼마나 위험한지 깨달았습니다.
초기 설계부터 성능을 고려하는 것이 얼마나 중요한지, 그리고 사용자 경험에 직접적인 영향을 미치는 성능 최적화가 단순한 "추가 작업"이 아니라 개발의 핵심 요소라는 것을 배웠습니다.


멘토링에서의 팀 회고 - 함께 성장한 10주

‘회고의 섬(Retrospective Island)’에 남긴 발자취

마지막 멘토링에서는 코치님과 팀원들과 함께 ‘회고의 섬(Retrospective Island)’을 통해 10주간을 되돌아보는 특별한 시간을 가졌습니다. 각자 다른 색깔의 포스트잇에 생각을 적어가며 섬 모양의 마인드맵을 완성해 나가는 과정에서, 함께 성장해온 시간들을 시각적으로 정리할 수 있었습니다.
정리하고 나누는 동안, 각자의 10주가 얼마나 다르고 또 닮아 있었는지 느낄 수 있었습니다. 그렇게 서로의 여정을 들여다보며, 함께였기에 완주할 수 있었다는 생각이 들었습니다.

코치님과의 찐 마지막 멘토링

이 시간이 끝나고 이어진 마지막 멘토링 시간에 저는 “이제 끝나고 나면 무엇을 하면 좋을까요?”라고 여쭈었습니다. 복습이나 정리를 하라는 답을 예상했지만, 코치님께서는 잠시 웃으시며 “이직이 목적이었잖아요. 이제 이력서를 넣어야죠.”라고 말씀하셨습니다.

순간 조금 당황스러웠습니다. 누군가에겐 틀린 말씀은 아니었지만, 제가 고민하던 방향과는 조금 다른 궤도에서 나온 답변이었기 때문입니다. 저는 퍼블리셔로 일하다가 개발로 확장하려는 과정에 있었기에 그 말이 낯설면서도 묘하게 실감 나게 들렸습니다. 아마 그때 처음으로, 이제 정말 배운 것을 세상 속으로 내보낼 때가 되었구나 하는 생각이 들었던 것 같습니다.


마무리

이번 과제는 ‘성능 최적화’를 주제로 한 10주차의 마지막 과제였습니다. 기능을 단순히 구현하는 것을 넘어, 코드 한 줄이 사용자 경험에 어떤 영향을 주는지를 직접 체감할 수 있었던 시간이었다고 생각합니다. React DevTools를 통해 렌더링 비용을 시각적으로 확인하면서, ‘잘 돌아가는 코드’와 ‘좋은 코드’의 차이를 처음으로 명확히 느꼈습니다. 또한, 불필요한 렌더링을 줄이기 위해 구조를 다시 고민하면서 코드의 효율성과 설계의 중요성을 함께 이해할 수 있었습니다.

이번 과제를 통해 저는 개발이 단순히 문제를 해결하는 일이 아니라, 보이지 않는 부분까지 책임지는 일이라는 것을 배웠습니다. 눈에 보이지 않던 구조와 흐름을 이해하는 순간, 개발의 깊이를 한층 더 실감할 수 있었습니다.


추천인 코드

제 후기를 보고 프로그램에 관심이 생기셨다면, 감사한 마음으로 수강료 할인을 받을 수 있는 추천인 코드를 드립니다.
수강 신청 시 추천인 코드 WlHJDO 입력하면 20만 원 할인이 적용되며, 자세한 커리큘럼과 일정은 아래 링크에서 확인하실 수 있습니다.
추천인 코드 : WlHJDO

https://hanghae99.spartacodingclub.kr/plus/fe

 

항해 플러스 | 도전을 넘어 개발자 커리어 도약으로

빅테크 시니어 코치진이 사수가 되어 드립니다. 시니어 개발자의 멘토링, 실무 포트폴리오, 동료 개발자들과의 인사이트 나눔까지.

hanghae99.spartaclub.kr