개발 속도를 높이는 효과적인 디버깅 전략 with React

황준·2025년 3월 30일
3

좋아하는 글

목록 보기
3/8
post-thumbnail

✅ 개요

개발 과정에서 우리는 끊임없는 소프트웨어의 변화에 직면합니다.
새로운 기능이 추가되거나 기존 코드가 수정될 때마다, 프로그램이 의도대로 작동하는지 다양한 범위에서 검증이 필요합니다. 이러한 검증 과정에서 가장 중요한 것이 바로 디버깅입니다.

개발자로서 저의 경력 중 가장 힘들었던 경험은 TV 웹뷰 개발 프로젝트였습니다.
이 분야는 참고할 수 있는 자료가 제한적이었고, 웹 개발 환경에서 사용하던 개발자 도구들이 작동하지 않았습니다.
문제 해결을 위해 화면에 직접 결과값을 출력하고, 다양한 방법으로 코드를 변형해가며 문제의 원인을 추적해야 했습니다.

이 경험을 통해 효과적인 디버깅 방법의 중요성을 깊이 깨닫게 되었고, 그 이후로 디버깅 기술 향상에 관심을 갖게 되었습니다.

그러면서 좋은 방법들이 생겼고, 이러한 방법들이 개발 속도 향상에 큰 도움이 되었습니다.
많은 분들이 아실 수도 있지만, 모르는 분들에게 전달할 수 있다면 큰 도움이 될 것 같아 이 글을 작성하게 되었습니다.

디버깅(debugging)
컴퓨터 프로그램이나 하드웨어 장치에서 오류를 찾아 수정하는 작업입니다. 버그(bug)를 제거한다는 의미에서 유래되었으며, 현대 소프트웨어 개발의 핵심 프로세스 중 하나입니다.



1. 화면 중심으로 컴포넌트 개발하기: LocatorJs

클래스 이름이나 텍스트를 활용하여 IDE에서 컴포넌트를 찾았습니다.
이 과정에서 발생하는 잦은 컨텍스트 스위칭은 개발 속도를 저하시키는 주요 요인이었습니다.

이 문제를 해결하기 위한 고민 끝에 발견한 도구가 바로 LocatorJs입니다.


화면에서 요소를 선택하면 해당 컴포넌트 파일을 자동으로 열어주는 Chrome 확장 프로그램입니다.

이 도구를 활용하면 다음과 같은 장점이 있습니다:

  • 화면에 보이는 컴포넌트의 소스 코드를 즉시 확인 가능
  • 컨텍스트 스위칭을 최소화하여 개발 집중력 향상
  • 코드 검색 시간을 대폭 단축하여 생산성 증가

특히 저희 팀은 Module Federation을 사용하고 있어, 다양한 모듈 간의 이동이 잦습니다. LocatorJs 덕분에 특정 모듈을 찾는 시간이 크게 단축되었습니다.

이 효율성 때문에 현재 팀 전체가 이 도구를 적극 활용하고 있습니다.
Cursor나 WindSurf 같은 최신 IDE를 사용하는 개발자들도 custom Link 설정을 통해 LocatorJs와 연동할 수 있어 더욱 편리합니다.

LocatorJs의 작동 원리와 상세한 설정 방법에 대해서는 제가 이전에 작성한 글 LocatorJS 작동원리 및 사용법을 참고하시면 도움이 될 것입니다

링크: LocatorJS 작동원리 및 사용법



2. 컴포넌트 중심으로 화면 찾기: React Devtools

LocatorJs가 화면에서 컴포넌트를 찾는 방법이라면, 그 반대 과정도 필요합니다.
특히 컴포넌트나 로직이 어느 화면에서 사용하는지 확인해야 유지보수를 마무리할 수 있습니다.

컴포넌트 파일 위치는 알지만, 실제로 어디에 렌더링되는지 찾는 것은 오래 걸립니다.
특히 공용 컴포넌트를 수정할 때는 다른 화면에 의도치 않은 사이드 이펙트가 발생할 수 있어 더욱 주의가 필요합니다.
이런 상황에서 큰 도움이 되는 도구가 바로 React Devtools입니다.

React Devtools는 크롬 확장 프로그램으로, 설치하면 개발자 도구에 'Components'와 'Profiler' 두 가지 탭이 추가됩니다. 이 중 'Components' 탭은 현재 페이지의 모든 React 컴포넌트를 트리 구조로 보여줍니다.


React Devtools의 좋은 기능 중 하나는 검색 기능입니다.
상단의 검색창을 통해 컴포넌트 이름을 입력하면, 현재 화면에 렌더링한 컴포넌트를 빠르게 찾을 수 있습니다.

만약 검색한 컴포넌트가 화면에 없다면, 검색 결과가 없다고 명확히 알려줍니다.
상호작용 이후 렌더링하는 컴포넌트의 경우, 상위 컴포넌트 이름을 활용하여 찾는 것이 좋습니다.
예를 들어, 모달이나 드롭다운 메뉴 같은 경우, 상위 컴포넌트로 찾아야합니다.

React Devtools를 통해 코드 수정 시 발생할 수 있는 리스크를 최소화하고, 애플리케이션 전반에 대한 이해를 높일 수 있습니다.



3. 화면 녹화하기: 성능탭

웹 개발 과정에서 순간적으로 발생하는 UI 변화나 로딩 화면을 포착하기는 쉽지 않습니다.
특히 페이지 진입 시 발생하는 이슈나, 인터랙션에 따른 애니메이션, 화면 전환 등은 눈으로 직접 확인하기 어려울 때가 많습니다.
이러한 순간적인 변화를 분석하기 위해 크롬 개발자 도구의 성능 탭(Performance tab)을 활용할 수 있습니다.


성능 탭의 녹화 기능을 사용하면 페이지 로드부터 사용자 인터랙션까지의 모든 과정을 상세히 기록하고 분석할 수 있습니다.
이를 통해 화면이 의도한 대로 작동하는지 확인하고, 성능 문제를 식별할 수 있습니다.

성능 탭에서는 네트워크 요청 타이밍, 자바스크립트 실행 시간, 렌더링 과정, 애니메이션 프레임 등 다양한 정보를 제공합니다. 다만, 이 정보들이 매우 상세하고 방대하여 초보자가 해석하기에는 다소 어려울 수 있습니다.

이러한 사용자 경험(UX) 문제를 해결하기 위해 크롬은 이전에 성능 통계 탭(Performance Insights)을 실험적으로 제공했습니다.
이 기능은 성능 탭의 핵심 정보들을 보기 쉽게 요약해 보여주었습니다.

성능 통계 탭 삭제

최근 크롬에서는 성능 통계 탭을 삭제하고, 대신 성능 탭 내에서 주제별로 정보를 그룹화하여 보여주는 새로운 기능을 추가했습니다.

이 업데이트된 기능은 성능 개선의 주요 포인트를 그룹으로 묶어서 보여줍니다. 특정 그룹에 마우스를 올리면 관련 내용이 성능 타임라인에서 하이라이트 되어, 어떤 부분에 집중해야 하는지 직관적으로 파악할 수 있습니다.


이러한 방식으로 성능 탭을 활용하면 애플리케이션의 성능 이슈를 단계적으로 분석하고, 최적화 방향을 보다 명확하게 설정할 수 있습니다.
성능 통계 패널 지원 중단에 관한 크롬의 공식 발표와 성능 탭 활용 예시에 대한 자세한 내용은 아래 링크에서 확인할 수 있습니다.

링크: 성능 통계 패널 지원 중단
대용량 이미지 블로킹 해결하기(활용 예시)



4. 신뢰할 수 있는 레이어 만들기:테스트 코드 활용하기


복잡한 알고리즘이나 데이터 처리 로직을 구현할 때, 코드가 의도대로 동작하는지 확인하는 과정은 중요합니다.
초기에는 console.log를 통해 함수의 결과값을 확인하는 방식을 사용했습니다.
하지만 이러한 방식은 몇 가지 명확한 단점이 있었습니다.

  • IDE <-> 콘솔로그창 컨텍스트 스위칭이 잦아짐
  • 로그 확인을 위해 필요한 상황을 매번 재현해야 함
  • 이전 테스트 결과와 비교가 어려움

이러한 문제점을 해결하기 위해 Jest의 Watch 모드를 활용했습니다.

테스트 코드를 작성하고 실시간으로 변경 사항을 확인하면서 함수를 개발하는 방식으로 전환했습니다.

복잡한 상태 관리 경험: 드래그 앤 드롭 & 데이터 변환

제가 테스트 코드의 중요성을 느꼈던 경험은 복잡한 드래그 앤 드롭 기능을 구현할 때였습니다.

이 기능 구현을 위해 다음과 같은 복잡한 데이터 흐름을 처리해야 했습니다.

  1. 서버에서 배열 형태의 데이터를 받음
  2. 받은 데이터를 트리 구조로 변환하여 UI에 표시
  3. 사용자가 드래그 앤 드롭으로 UI 상태 변경
  4. 변경된 트리 구조를 다시 배열로 변환
  5. 변환된 배열을 서버에 전송

각 단계마다 다양한 문제가 발생할 가능성이 있었습니다.
더불어 드래그 앤 드랍 구현 경험도 없었습니다.

서버 API도 초기 단계였기 때문에 Query와 Mutation 관련 문제가 빈번했고, 기획 변경에 따라 알고리즘도 계속 수정해야 했습니다.
이런 상황에서 매번 5개 레이어를 모두 확인하며 문제를 찾는 것은 너무나 비효율적이었습니다.

테스트 코드로 신뢰할 수 있는 레이어 구축하기
결국 저는 테스트 코드를 활용하여 이 복잡한 문제를 해결했습니다.

주요 데이터 변환이 이루어지는 2번(배열→트리)과 4번(트리→배열) 레이어에 테스트 코드를 작성했습니다.
기획 변경이 생겨도 테스트 코드를 수정하여 신뢰할 수 있도록 대응했습니다.

이렇게 신뢰할 수 있는 레이어가 구축되자, 문제가 발생했을 때 1, 3, 5번 레이어 중 어느 곳에 문제가 있는지만 확인하면 되었고, 디버깅 과정이 훨씬 간소화되었습니다.

결론
복잡한 시스템을 디버깅할 때는 "신뢰할 수 있는 레이어"를 구축하는 것은 중요합니다.
테스트 코드를 통해 특정 레이어나 함수가 정확히 작동한다는 확신을 가질 수 있다면, 문제 발생 시 확인해야 할 영역이 크게 줄어듭니다.
특히 여러 단계의 데이터 변환이 이루어진다면 테스트 코드를 권장드리고 싶습니다.

5. 응집도가 낮은 함수: 로깅 시스템 사용하기

최근 URL 변경이 빈번하게 발생하는 레거시 페이지를 수정하는 작업을 진행했습니다.
이 페이지에서는, 다양한 조건에 따라 useEffect 내에서 라우터가 자동으로 변경되는 구조가 있었습니다.

문제는 이러한 라우팅 로직이 여러 컴포넌트에 분산되어 있고 많아서, 추적하기 어려웠습니다.

초기에는 각 라우팅 로직마다 console.log를 삽입하는 방식으로 디버깅을 시도했지만, 개발이 완료되면 console.log를 지우고, 기획 변경마다 매번 console.log를 넣고 지우는 일은 비효율적이었습니다.

체계적인 로깅 시스템의 필요성
이러한 경험을 통해 확인하는데 많은 비용이 드는 함수는 체계적인 로깅 시스템이 필요하다는 것을 깨달았습니다.

NestJS와 같은 백엔드 프레임워크에서는 로깅 시스템을 통해 서버 전체에서 어떤 함수가 실행되었는지 빠르게 확인할 수 있습니다.

여기에 영향을 받아 확인해야 하는 범위가 넓은 프론트엔드 함수에도 로깅 시스템을 도입해보기로 했습니다.

커스텀 로깅 시스템 구축
이 문제를 해결하기 위해 개발 환경에서만 작동하는 커스텀 로깅 함수를 만들었습니다.

export function _log(message: Parameters<typeof console.log>[0]): void {
  if (!isProd) {
    const formattedMessage = `[${LOGGER_MODULE}]: ${message}`;
    console.log(formattedMessage, '\nComponent Path:' + getComponentPath());
  }
}

이 로깅 시스템을 도입한 후, 라우팅 변경이 발생하는 정확한 위치와 조건을 훨씬 빠르게 파악할 수 있었습니다.

  • 디버깅 대상 범위를 대폭 축소하여 효율성 증가
  • 개발 환경에서만 작동하여 프로덕션 코드에 영향 없음
  • 기획 변경 시에도 별도의 코드 수정 없이 문제 원인 파악 가능

이와 관련하여 아래 글로 정리하였습니다.

링크: 효과적인 로깅 시스템 구축하기

빌드 결과 확인하기:빌드-소스맵 활용

프론트엔드 개발에서 로컬 환경에서는 정상적으로 작동하지만, 빌드 후 배포 환경에서는 예상과 다르게 동작하는 경우가 종종 발생합니다.

특히 저는 TailwindCSS와 Module Federation을 함께 사용하는 프로젝트에서 이러한 문제를 자주 경험했습니다.

이런 상황에서 어떤 부분부터 디버깅해야 할지 판단하는 것은 어려웠습니다.
그러나 소스맵(Source Map)을 활용하면 빌드된 코드와 원본 코드 사이의 연결 고리를 통해 효과적으로 레이어를 나누어 디버깅할 수 있습니다.

소스맵을 활용한 디버깅 전략
소스맵을 활용한 디버깅 과정은 다음과 같습니다.

  • 빌드 결과물 확인: 먼저 빌드 결과물이 정상적인지 확인합니다. 소스맵을 통해 빌드된 코드가 원본 코드와 어떻게 매핑되는지 확인할 수 있습니다.
  • 문제 영역 식별: 빌드 결과물이 정상이라면 배포 환경의 문제를 확인하고, 빌드 결과물에 이상이 있다면 원본 코드를 검토합니다.

TailwindCSS와 소스맵
TailwindCSS를 사용할 때 소스맵 디버깅은 특히 유용합니다. TailwindCSS는 사용하지 않는 CSS를 자동으로 제거하는 트리 쉐이킹(Tree Shaking)을 수행하기 때문에, 작성한 클래스가 실제 빌드 결과물에 포함되었는지 확인하는 것이 중요합니다.

소스맵 설정 및 활용 팁
소스맵을 설정하는 것은 비교적 간단합니다. Webpack과 같은 번들러의 devtool 옵션을 통해 소스맵을 활성화할 수 있습니다.

소스맵 설정에 대한 자세한 내용은 Webpack DevTools 공식 문서에서 확인할 수 있습니다.
TailwindCSS와 Module Federation과 같은 현대적인 도구를 사용할 때 소스맵을 활용한 디버깅은 개발 효율성을 크게 높여주는 필수적인 기술입니다.

링크: webpack-devtools


마치며

좋은 디버깅 전략은 개발 비용을 줄여줍니다.
많은 방법을 아는 것보다 상황에 맞는 적절한 방법을 선택하는 것이 제일 중요하다고 생각합니다.

지금까지 디버깅에 관한 꾸준한 고민과 실험을 통해 개발 효율성을 높일 수 있었고, 제가 모르는 더 좋은 방법들이 많을 것이라고 생각합니다.
더 좋은 방법이 있다면 편히 알려주시면 감사하겠습니다.
긴 글 읽어주셔서 감사합니다!

profile
잘하고 싶은 사람

0개의 댓글