JiSoo's Devlog

[모던 리액트 Deep Dive] 7장 본문

Frontend/React

[모던 리액트 Deep Dive] 7장

지숭숭숭 2024. 5. 23. 20:45

크롬 개발자 도구

크롬 개발자 도구란 크롬에서 제공하는 개발자용 도구로, 웹페이지에서 일어나는 거의 모든 일을 확인할 수 있다

디버깅하고 싶은 페이지 접속 → 메뉴에서 보기 → 개발자 도구

or

웹페이지에서 마우스 우클릭한 뒤 검사 클릭

 

웹사이트를 제대로 디버깅하고 싶다면? 시크릿 모드라 불리는 개인정보 보호 모드에서 페이지와 개발자 도구 열기

이유는 브라우저에 설치된 각종 확장 프로그램 때문

브라우저 확장 프로그램은 웹페이지 방문 시 확장 프로그램의 실행을 위해 전역 변수나 HTML 요소에 실제 웹 애플리케이션이 제공하지 않은 다른 정보를 추가할 수 있다

이 정보는 개발자가 추가한 정보도 아니고 다른 사용자에게서는 볼 수 없기에 디버깅에 방해가 될 수 있다

개인정보 보호 모드에서는 각종 확장 프로그램이 실행되지 않기에 순수하게 웹페이지와 관련된 정보만 확인 가능

* 일부 설정에 따라 개인정보 보호 모드에서도 실행될 수 있는 프로그램이 있다면 꼭 끄거나 삭제하기

 

 


 

 

요소 탭

현재 웹페이지를 구성하고 있는 HTML, CSS 등의 정보를 확인할 수 있다

왼쪽에는 HTML트리, 오른쪽에는 왼쪽에서 선택한 요소와 관련된 각종 정보가 나타난다

 

요소 화면

HTML 트리에서 원하는 태그를 클릭하면 브라우저 페이지의 해다 요소가 강조되고 해당 태그와 관련된 정보 확인 가능

요소 화면에서는 단순히 현재 HTML을 보는 것뿐만 아니라 직접 코드를 수정해 어떻게 보이는지 빠르게 확인할 수 있다

만약 배너와 같이 코드에 의해 클래스나 속성값이 동적으로 제어되는 DOM이 있다면 요소의 중단점을 사용해 디버깅 가능

중단 위치 설정해 두면 관련 작업이 일어날 때마다 렌더링을 중단하고 해당 요소 변경을 일으킨 소스코드를 보여준다

 

요소 정보

요소 정보에서 확인할 수 있는 주요 내용

- 스타일 : 요소와 관련된 스타일 정보

- 계산됨 : 해당 요소의 크기, 패딩, 보더, 마진과 각종 CSS 적용 결괏값을 알 수 있는 탭

- 레이아웃 : CSS 그리드나 레이아웃과 관련된 정보 확인 가능

- 이벤트 리스너 : 현재 요소에 부착된 각종 이벤트 리스너 확인 가능

- DOM 중단점

- 속성 : 해당 요소가 가지고 있는 모든 속성값

- 접근성 : 웹 이용에 어려움을 겪는 사람을 위한 스크린리더기 등이 활용하는 값

 

 


 

 

소스 탭

소스 탭에서는 웹 애플리케이션을 불러오기 위해 실행하거나 참조된 모든 파일을 확인할 수 있다

자바스크립트 파일부터 CSS, HTML, 폰트까지 다양한 파일 정보 확인 가능

소스 탭에서 유용한 것을 살펴보려면 디버깅하고 싶은 파일을 직접 열어야 한다

프로덕션 모드의 경우 파일이 모두 압축돼 있어 디버깅하기 매우 불편하지만 개발 모드에서는 유용하게 사용 가능

소스 중단점을 생성해 자바스크립트 실행을 중단시키고 디버깅 수행 가능

→ 코드에 debugger를 선언하는 것과 동일한 역할을 하지만 소스코드를 오염시키지 않아 더 유용!

 

소스 탭 오른쪽에서 제공하는 정보

- 감시 : 감시하고 싶은 변수 선언하고 해당 변수의 정보 확인 가능

- 중단점 : 현재 웹사이트에서 추가한 중단점 확인 가능, 열려있는 파일뿐만 아니라 웹페이지 전체에 걸쳐 소스탭에서 추가한 모든 중단점 확인 가능

- 범위 : 현재 중단점에서의 스코프

- 호출 스택 : 현재 중단점의 콜스택 확인 가능, 자바스크립트 코드가 실행되며 생성되는 실행 콘텍스트가 어떻게 저장되어 현재 어떤 모습을 하고 있는지 직접 볼 수 있다

- 전역 리스너 : 현재 전역 스코프에 추가된 리스너 목록 확인 가능

- XHR/가져오기, DOM, 이벤트 리스너, CSP 위반 중단점 : 소스의 중단점 이외에 다양한 중단점 확인 가능

 

 


 

 

네트워크 탭

네트워크 탭에는 해당 웹페이지를 접속하는 순간부터 발생하는 모든 네트워크 관련 작동이 기록된다

HTTP 요청부터 웹 소켓에 이르기까지 웹페이지가 외부 데이터와 통신하는 정보를 확인하고 싶을 때 참조

왼쪽에는 실제 해당 페이지를 불러오는 과정에서 발생한 네트워크 요청을 볼 수 있다

하단에는 페이지를 불러오는 기간 동안 발생한 요청 건수와 다운로드한 리소스의 크기를 확인할 수 있다

 

네트워크 탭을 통해 집중적으로 확인해 봐야 하는 점

- 불필요한 요청 또는 중복되는 요청이 없는지

- 웹페이지 구성에 필요한 리소스 크기가 너무 크지 않은지

- 리소스를 불러오는 속도는 적절한지 또는 너무 속도가 오래 걸리는 리소스는 없는지

- 리소스가 올바른 우선순위로 다운로드되어 페이지를 자엽스럽게 만들어가는지

 

 


 

 

메모리 탭

메모리 탭에서는 현재 웹페이지가 차지하고 있는 메모리 관련 정보를 확인할 수 있다

애플리케이션에서 발생하는 메모리 누수, 속도 저하, 웹페이지 프리징 현상을 확인할 수 있는 유용한 도구

메모리 탭을 열고 프로파일링 작업을 거쳐야 원하는 정보를 볼 수 있다

프로파일링 유형

- 힙 스냅샷 : 현재 메모리 상황을 사진 찍듯이 촬영 가능

- 타임라인의 할당 계측 : 시간의 흐름에 따라 메모리의 변화를 살펴보고 싶을 때 사용

- 할당 샘플링 : 메모리 공간을 차지하고 있는 자바스크립트 함수를 볼 수 있다

 

자바스크립트 인스턴스 VM 선택 부분에서 현재 실행 중인 자바스크립트 VM 인스턴스 확인 가능

디버깅하고 싶은 VM 환경을 선택하면 된다

 

힙 스냅샷

현재 페이지의 메모리 상태를 확인해 볼 수 있는 메모리 프로파일 도구

힙 스냅샷을 촬영하는 시점을 기준으로 마치 사진으로 촬영하듯 메모리 현황을 보여준다

힙 스냅샷을 통해 메모리 누수 정보를 확인하기 위해서는 메모리 누수가 발생하는 것으로 예상되거나 혹은 위험이 존재할 것 같은 스크립트 전후로 내용을 촬영해 비교하는 것이 좋다

원인을 더욱 정확하게 파악하려면 변수와 함수에 적절한 이름을 주어 수많은 메모리 내용 사이에서 눈에 띄게 하는 것이 도움이 된다

 

타임라인 할당 계측

시간의 흐름에 따라 메모리 변화를 확인할 수 있는 기능

메모리의 변화를 모두 기록하기 때문에 상대적으로 많은 부담이 발생한다

메모리 변화를 일으킨 변수가 무엇인지, 해당 변수가 어느 정도 크기를 차지하고 있는지 등을 확인할 수 있다

 

할당 샘플링

시간의 흐름에 따라 발생하는 메모리 점유를 확인할 수 있다는 점에서 할당 계측과 비슷하지만 자바스크립트 실행 스택별로 분석 가능하고 이 분석을 함수 단위로 한다는 차이점이 있다

프로파일링 할 때 브라우저에 주는 부담을 최소화할 수 있어 장시간에 걸쳐 디버깅을 수행해야 할 때 유리하다

 

 


 

 

 

Next.js의 서버 환경 디버깅하기

 

Next.js 프로젝트를 디버그 모드로 실행하기

"dev": NODE_OPTIONS='--inspect' next dev

 

디버거 연결 준비를 마치고 크롬 브라우저에 chrome://inspect로 이동하면

Open dedicated Devtools for Node 클릭 시 새로운 창에서 개발자 도구가 나타난다

 

Next.js 서버에 트래픽 유입시키기

서버 사이드 렌더링과 같이 서버에서 제공되는 서비스의 경우 서버를 실행한 뒤 사용자가 서서히 유입되면서 메모리 누수가 발생하는 경우가 많아 서버에 직접 트래픽을 발생시켜서 확인하는 편이 제일 확실한 방법이다

 

오픈소스 도구인 ab 사용

ab는 아파치 재단에서 제공하는 웹서버 성능 검사 도구로 HTTP 서버의 성능을 벤치마킹할 수 있는 도구

>> ab -k -c 50 -n 10000 "http://127.0.0.1:3000/"

↑ 이 명령어는 저 주소를 향해 한 번에 50개의 요청을 총 10,000회 시도한다

ab를 사용하면 요청으로부터 응답받는 데 걸린 시간, 바이트 크기 등 다양한 정보 확인까지 가능하다

 

◦ Next.js의 메모리 누수 지점 확인하기

import type { GetServerSidePropsContext, NextPage } from 'next'

const access_users = []

function Home({ currentDateTime }: {currentDateTime: number }) {
  return <>{currentDateTime}</>
}

export const getServerSideProps = (ctx: GetServerSidePropsContext) => {
  const currentDateTime = new Date().getTime()
  
  access_users.push({
    user: `user-${Math.round(Math.random() * 100000)}`,
    currentDateTime,
  })
  
  return {
    props: {
      currentDateTime,
    },
  }
}

export default Home

getServerSideProps는 페이지 접근 요청이 있을 때마다 실행되는 함수이므로 최대한 부수 효과가 없는 순수 함수로 만들어야 한다

만약 이 함수 내부에서 외부 스코프의 변수에 의존하는 작업을 한다면 메모리 누수 상황을 마주할 수도 있다

 

 

728x90