크롬 퍼포먼스 탭과 debugger 키워드로 효율적인 디버깅하기

들어가며

이번 글에서는 제목과 같이 크롬 퍼포먼스 탭과 debugger 키워드를 활용하여 좀 더 효율적으로 디버깅을 하는 방법에 대해 공유해보려고 합니다.

미리 짜여진 상황이 아니기 때문에 그동한 접하지 못했던 개념이나 코드를 마주칠 수 있는데, 크게 신경 쓰지 않고 문제를 해결하는 전반적인 과정에 대해 유심히 봐주시면 좋을 것 같습니다.

문제 발생

회사 내 프로젝트와 관련되어 있는 이슈이다 보니 자세히 내용에 대해 풀진 못 하지만.. 간단히 설명하자면, 기존에 적용되어있던 반경에 대한 로직을 갈아엎고 새로운 로직을 적용하는 내용입니다.

기능 구현 자체는 큰 무리 없이 진행하였지만, 얼추 완성하고 보니 한 가지 버그가 있다는 것을 깨달았습니다.

바로 아래와 같이 지도를 움직일 때나 GIF에는 나오진 않았지만 확대, 축소 시 +와 - 버튼이 사라지는 이슈였죠.

문제 상황

처음부터 해당 프로젝트의 코드를 작성했었다면 문제를 좀 더 빠르게 파악할 수 있었겠지만, 코드의 구조나 컨텍스트 등을 완전히 파악하고 있는 상태가 아니었기 때문에 갈피를 제대로 잡지 못했습니다.

그렇게 의미없는 console 구문을 남발하며 허공에 삽질을 하는 도중.. 문득 크롬의 퍼포먼스 탭이 떠올랐고 이를 활용해보면 어떨까하고 생각하다 바로 실행에 도입했습니다.

퍼포먼스 탭이란?

크롬의 퍼포먼스 탭에 대해 잘 모르시는 분들을 위해 약간의 설명을 하자면, 해당 탭은 크롬에 탑재된 여러 디버깅 툴들 중 하나로서, 프로파일링이 진행된 시점 동안의 성능을 체크해주는 역할을 합니다.

간단히 말해, 어떤 일들이 일어났는지 자세히 보여주는 역할을 한다고 얘기할 수 있을 듯 하네요.

Network, Frames, Interactions 등의 여러 카테고리들이 존재하며, CPU 그래프는 아래 사진과 같이 다양한 상태들을 수치화하여 보여줍니다.

그래프를 구성하는 다양한 요소들

FPS나 CPU에 나타나는 그래프를 통해 이뤄지는 연산의 정도를 알 수 있으며, 높이가 높을 수록 많은 연산이 수행된다고 파악할 수 있습니다.

이 외에도 네트워크의 속도 조절, CPU에 Throttling 적용 등 사용자 설정에 따라 다양한 조건을 부여할 수 있다는 점 알아두시면 좋을 듯 합니다.

보통 성능을 최적화하고자 할 때 해당 탭을 자주 사용하지만, 기본적으로 Main 카테고리에서는 사이트 내의 코드를 기반으로 실행되는 메서드들의 정보를 중심으로 알려주기 때문에 이를 실제로 활용해보기로 결정했습니다.

해결 시작

일단 문제 해결을 위해서는 문제가 발생한 시점의 정보를 지니고 있어야 합니다.

문제가 발생한 시점 확인

실제로 버튼이 사라질 때 FPS와 CPU의 그래프에서 변동이 생겼고, 우리는 어떠한 로직의 실행으로 인해 버튼이 사라졌다는 것을 유추할 수 있게 됩니다.

해당 시점에서 실행된 로직에 중점을 두기 위해 타임 포커싱의 범위를 아래와 같이 좁혔고, 그 결과 SampleRegionStore이라는 클래스의 clearSampleRegions 함수가 호출됐다는 것을 알 수 있었습니다.

호출된 메서드 확인

즉, 실행된 어떠한 로직은 바로 SampleRegionStore.clearSampleRegions가 되는것이죠.

debugger 키워드와의 호흡

문제를 발생시킨 로직을 알았으니, 이젠 어떻게 해당 로직이 실행되었는지 파악 할 차례입니다.

해당하는 파일의 함수(clearSampleRegions)에 debugger를 걸어봅시다.

debugger 키워드 설정

* debugger 키워드는 해당 키워드가 설정된 위치에 도달하기까지 호출된 함수들의 콜스택을 쉽게 확인할 수 있게 해주기 때문에 이런 상황에서 굉장히 유용합니다.

디버거 콜스택

위 사진에서 확인할 수 있듯이, clearSampleRegions 함수가 호출되기에 앞서 굉장히 많은 함수들이 호출됐다는 것을 알 수 있습니다.

콜스택을 쭉 타고 올라가보면 문제의 clearSampleRegions 함수가 호출된 곳은 바로 SampleRegionStore의 getSampleRegions 함수라는 것을 알 수 있으며,

getSampleRegions 함수

최종적으로 호출의 시작점은 바로 RegionEditorStore 내의 이벤트 리스너 코드라는 것을 파악할 수 있게 됩니다.

Idle 이벤트 리스너 코드

즉, 지도를 움직였을 때 Idle 이벤트가 트리거 됐고, 최종적으로 clearSampleRegions 함수가 호출되어 버튼들이 초기화되었다는 결론에 도달할 수 있게 되었습니다.

각각의 코드가 호출된 순서를 간단히 표현해보자면 아래와 같습니다.

1. Idle 이벤트 트리거

2. SampleRegionStore 내의 getSampleRegions 함수 호출

3. getSampleRegions 내의 clearSampleRegions 함수 호출

문제 해결

이제 얻은 정보들을 기반으로 문제를 해결 할 차례입니다.

SampleRegionStore의 getSampleRegions 함수에서 특정 조건을 부여하여 clearSampleRegions가 호출되지 않도록 수정할 수 있지만, 애초에 해당 페이지에서는 getSampleRegions 메서드 자체가 필요하지 않은 상황이었기 때문에 Idle 이벤트 리스너가 트리거 됐을 때 조건을 부여하는 것이 낫다고 판단하였습니다.

따라서, 반경을 적용한 시점에서의 버튼 초기화 방지라는 문제 해결의 목적에 맞게 반경이 존재 할 경우에는 그대로 함수를 종료하여 이후의 코드가 실행되지 않고 Early Return 되도록 수정하였고,

그 결과, 지도를 움직였을 때나 확대, 축소 시 버튼이 사라지지 않고 그대로 남아있는 모습을 확인할 수 있었습니다.

해결 후의 모습

마무리

이번 글에서는 실제로 제가 회사 프로젝트에서 기능을 개발하고 버그를 해결하며 깨달은 점들에 대해 공유하고 싶었습니다.

이와 비슷한 상황이 아니더라도 언어 자체나 에디터, 브라우저에서 제공하는 디버깅 기능을 잘 활용하면 좀 더 유연하고 효율적인 디버깅이 가능하다는 점 알아두시면 좋을 것 같습니다.

글 봐주셔서 정말 감사합니다.

* 개인 블로그에 작성했던 내용이지만, 내용이 팀 블로그에 더욱 알맞을 듯 하여 을 옮겼습니다!

--

--