리액트 개발 도구로 디버깅이 불가능한 오류들은 크롬 개발자 도구로 확인할 수 있다.
## 7.1 크롬 개발자 도구
크롬 개발자 도구를 잘 사용하고 싶다면 시크릿탭을 사용하는 것을 추천한다. -> 브라우저 확장 프로그램의 간섭을 피할 수 있다.
## 7.2 요소 탭
현재 페이지를 구성하는 HTML과 CSS 요소를 확인할 수 있다.
### 요소 화면
직접 코드를 수정할 수 있다. (태그명, 클래스, 속성, 스타일, ...)
- 프로덕션 환경에서도 테스트 할 수 있다는 장점
- 리액트 코드를 수정하면 핫 리로딩을 거쳐야 하지만 요소 탭에서 수정하면 거치지 않아도 된다는 장점
### 중단점
코드에 의해서 DOM이 변경되는 경우를 디버깅 할 수 있다.
요소에 중단점을 걸 수 있는데, 그 중단 기준이 되는 이벤트에는 이런 것들이 있다.
- 하위 트리 수정
- 속성 수정
- 노드 삭제
이런 이벤트들이 발생하면, 렌더링을 중단하고 그 이벤트를 발생시킨 소스의 코드를 보여준다.
### 요소 정보
요소와 관련된 정보를 보여주는 부분
- 스타일
- 계산됨
- 레이아웃
- 이벤트 리스너
- DOM 중단점
- 속성
- 접근성
## 7.3 소스 탭
웹 어플리케이션을 불러올 때 필요한 소스를 모두 확인할 수 있다. (CSS, HTML, 폰트, ...)
파일을 직접 열어서 확인하면 되고,
프로덕션 환경에서는 코드가 압축되어 있을 것이기 때문에 알아보기 힘들겠지만, 개발 모드에서는 유용하게 사용할 수 있다.
일반적인 코드 에디터에서 수정하는 것과의 다른 점은 우선 중단점을 걸어서 디버깅 할 수 있다는 점이다.
코드 에디터에서도 debugger를 선언해서 사용할 수 있지만 브라우저 도구에서는 코드를 오염시키지 않고도 디버깅을 할 수 있다는 장점이 있다.
이 중단점은 외부 라이브러리에도 걸어둘 수 있다.
\* 이 소스 탭은 요소 탭과 더불어서 디버깅 시에 자주 쓰이는 탭이므로 잘 알아둡시다!
## 7.4 네트워크 탭
해당 웹 페이지에 접속한 순간부터 발생하는 모든 네트워크 관련 작동이 기록된다.
하단에서 총 요청 건수와 다운로드한 리소스 크기를 확인할 수 있는데, 특히 모바일 환경 같은 겨웅에는 요청이 많거나 리소스 크기가 크면 비용 이슈가 발생할 수 있다. 이럴 때는 리소스 압축이나 이미지 최적화 같은 조치를 취해주는 것이 좋다.
### 스크린샷 캡쳐 기능
네트워크 요청 흐름에 따라 자연스럽게 웹 페이지가 완성되는지를 확인할 수 있다.
### 네트워크 탭에서 확인하면 좋은 것들
1. 불필요한 / 중복된 요청이 있는지
2. 리소스 크기가 너무 크지 않은지
3. 리소스 다운로드 속도가 적절한지, 오래 걸리는 리소스가 무엇인지
4. 올바른 우선순위로 리소스가 다운로드되는지
## 7.5 메모리 탭
메모리 누수나 속도 저하, 웹 페이지 프리징 현상을 확인할 수 있다.
리액트 개발 도구와 비슷하게 프로파일링 작업을 먼저 해야 한다.
1. 힙 스냅샷 : 현재 시점의 메모리 상황
2. 타임라인의 할당 계측 : 시간의 흐름에 따른 메모리 변화 확인. 로딩이 되는 과정의 메모리 변화나 페이지에서 어떤 상호작용이 발생했을 때의 메모리 변화 같은 것 확인 가능
3. 할당 샘플링 : 메모리 공간을 차지하고 있는 자바스크립트 함수 확인
### 자바스크립트 VM 인스턴스 선택
현재 실행중인 VM을 확인하고 디버깅하고 싶은 VM 환경을 선택한다.
왼쪽에는 환경별 힙 크기가 나와 있는데, 이 페이지가 JS 힙을 얼마나 차지하고 있는지를 확인한다. 실행에 따라 실시간으로 바뀌는데, 이 값이 크면 브라우저에 부담이 된다.
### 힙 스냅샷
현재 페이지의 메모리 상태를 확인하는 프로파일이다.
촬영 시점을 기준으로 사진 촬영하듯 메모리 현황을 보여준다.
예) 버튼을 클릭하면 천만개의 랜덤한 값을 배열에 push하는 페이지의 메모리 상태 확인하기
1. 페이지 진입 직후에 스냅샷
기본적으로 리액트와 전역 객체 정보가 메모리에 올라가 있다.
2. 버튼 클릭 후에 스냅샷
두 스냅샷 사이에 할당된 객체를 필터링해서 볼 수 있다.
여기서 확인 가능한 정보 : 모든 객체인지, 어떤 함수로 발생된건지, 객체 내부의 값도 확인 가능
> [!note] 얕은 크기와 유지된 크기
> - 얕은 크기 : 객체 자체가 보유하는 메모리 바이트
> - 유지된 크기 : 해당 객체 뿐 아니라 다른 부모가 존재하지 않는 모든 객체의 크기 합
> 예) X 생성자 안에서 Y 생성자 호출하는 경우
> X의 얕은 크기 (52) 유지된 크기 (100)
> Y의 얕은 크기 (48) 유지된 크기 (48)
> => X의 얕은 크기는 내부 객체 Y를 제외한 X 자체의 크기가 된다.
> [!note] 얕은 크기, 유지된 크기, 그리고 메모리 누수
> 얕은 크기는 작지만 유지된 크기가 큰 객체를 먼저 의심해보자.
> 어떤 객체의 유지된 크기가 크다는 것은 복잡한 참조 관계를 갖고 있다는 것을 의미한다. => 메모리 점유 가능성 높음
스냅샷은 두개 이상 찍어서 비교하는 방식으로 활용하는 것이 좋다.
기본적으로 메모리에 존재하는 정보들이 있기 때문에 diff를 비교하는 것이 더 쉽다.
> [!tip]
> - 메모리를 통해서 useMemo나 useCallback으로 메모한 값이 실제로 렌더링 사이에 유지되는지도 확인할 수 있다.
> - 기명 함수로 바꾸면 더 쉽게 확인할 수 있다.
### 타임라인 할당 계측
**시간의 흐름에 따른 메모리의 변화**를 기록한다 -> 그래서 많은 부담이 발생함
- 시간의 흐름에 따른 메모리의 변화
- 그 변화를 일으킨 변수가 무엇인지
- 그 변수가 어느 정도의 크기인지
같은 것들을 확인할 수 있다.
### 할당 샘플링
시간의 흐름에 따라 발생하는 메모리 점유를 확인한다. (타임라인 할당 계측과 어느정도는 비슷하다.)
이 변화를
- 실행 스택별로 분석하고
- 함수 단위로 분석한다
는 차이점이 있다.
할당 샘플링으로 가장 많은 바이트를 차지하는 함수의 작업을 확인할 수 있다.
이런 점에서 타임라인 할당 계측과 비슷하긴 한데, 타임라인 할당 계측보다는 브라우저에 가해지는 부담이 적다.
## 7.6 Next.js 환경 디버깅
클라이언트 사이드 랜더링에서는 메모리 누수의 영향 정도는 사용자 환경에 따라 달라진다. 메모리 누수가 실제로 브라우저 성능에 영향을 주는지도 사용자 환경에 따라 달라진다. (사용자 PC의 성능이 괜찮다면 약간의 메모리 누수는 성능에 영향이 없을 수도 있다.)
반면에 서버 사이드 랜더링에서의 메모리 누수는 실제로 서버 자체에 부담이 된다. 이런 부담이 쌓이다 보면 전체 서비스 운영에도 영향을 줄 수 있다.
다행스럽게도 서버 사이드 랜더링 환경도 크롬 개발자 도구를 이용해서 디버깅 할 수 있다.
### 디버그 모드로 실행
`NODE_OPTIONS='--inspect'` 와 함께 실행하면 디버그 모드로 실행할 수 있다.
이렇게 디버그 모드로 실행한 뒤에는 `chorme://inspect` 로 접속해서 devtool of node를 선택한다. -> 디버깅 가능
### Next.js 서버에 트래픽 유입
[ab(ApacheBench)](https://httpd.apache.org/docs/2.4/en/programs/ab.html)라는 벤치마크 툴을 이용해서 서버 트래픽을 늘려볼 수 있다.