자바스크립트가 잘못되고있다고 추론될 때, console.log을 사용하는 대신에 크롬 개발자도구의 디버길 툴을 사용하는것을 고려해라. 보통 아이디어는 코드에서 의도적으로 중단시킬 곳인 중단점을 설정하고, 코드를 한번에 한줄씩 실행시켜나가는 것이다. 코드를 진행해가며, 너는 모든 현재 정으된 솢성과 변수들의 값을 보고 변경할 수 있고, Console에 js를 실행시킬 수 있고, 등등이다.
console.log()대신에 breakpoint를 사용하자. breakpoint를 사용하면 개발자도구는 그 시간에 모든 변수의 값을 보여준다. 때때로 너가 알지 못하는 변수가 코드에 영향을 줄 수 있다. debugger 창의 Event Listener Breakpoints에서 breakpoint를 원하는 Event Listener들을 설정할 수 있다.
Mouse - click 이벤트에 breakpoint를 설정한 모습
step over next function call을 하여 함수 내부를 보지 않고 한줄씩 디버깅하거나, step into next function call을 하여 함수가 있다면 함수 내부로 들어가 디버깅하거나, step out of current function으로 현재 함수에서 나가는 step들을 적절히 활용해 디버깅 하자.
한줄씩 실행시키지 않고 내가 원하는 부분만 디버깅하고싶다면 line-of-breakpoint를 설정하자. Sources창의 Page에서 js코드의 줄을 클릭하면 파란색으로 바뀐다. 그리고 Resume script execution을 하여 한번에 원하는 줄에서 멈춘다.
Scope창과 Watch창을 이용해 변수를 확인할 수 있다. Scope창은 현재 디버그의 local과 global변수들을 볼 수 있다. Watch창에서는 변수 뿐만 아니라 수식을 만들어 결과를 확인할 수 있다.
line-of-code breakpoint말고도 다양한 타입의 breakpoint가 있다.
line-of-code: 멈추고싶은 줄 숫자에 좌클릭을 하면 파란색 아이콘이 생긴다. 해당 줄이 실행되기 전에 실행이 중단된다.
conditional line-of-code: 멈추고 싶은 줄 숫자에 우클릭을 하여 add conditional breakpoint를 하여 condition을 넣고 엔터를 누른다. ?와 함께 주황색 아이콘이 생긴다.
log line-of-code: 멈추는 대신에 console에 로그를 남기고싶을 때 사용한다. 멈추고싶은 줄 숫자를 우클릭하여 add logpoint를 하고 console.log하고싶은 메시지를 넣는다. ..과 함께 핑크색 아이콘이 생긴다.
dom change: dom또는 자식이 바뀌면 멈추게 하는 기능이다. elements탭에서 원하는 요소에 우클릭 후 선택하면 된다.
결과는 elements - dom breakpoints창 또는 sources - dom breakpoints창에서 확인할 수 있다.
xhr/fetch: 요청 url의 xhr이 명시된 문자열을 포함하고 있다면 멈춘다. sources창의 xhr/fetch breakpoints창을 확장후 +를 눌러 문자열을 추가한다.
event listener: 이벤트가 발발한후 이벤트 리스너 코드에서 멈추고 싶다면 사용한다. sources창의 event listener breakpoints창을 확장 후 원하는 이벤트를 체크하면 된다.
exception: caught exception과 uncaught exception일 때 멈추게 할 수 있다. caught는 try-catch throw같은 것이고, uncaught는 선언되지 않은 변수의 사용 같은 것이다. sources - breakpoints창에서 원하는것을 체크하면 된다.
function: 특정한 함수가 호출되었을 때 디버그하고싶다면 사용한다. debug(funcName)과 같이 사용한다.
trusted type: xss에 대항하여 보안 보호를 해준다.
Set up a Workspace
기본적으로, Sources 창에서 파일을 편집할 때, 페이지가 재로드되면 변경들은 사라진다. Workspaces는 당신의 파일시스템에 개발자도구에 만든 변경점들을 저장하는것을 가능하게 한다. 근본적으로 이것은 개발자도구를 코드 에디터로 사용할 수 있게 허락한다.
Override web content and HTTP response headers locally
지역 재정의를 통해, XHR과 fetch요구를 포함한 웹 콘텐츠와 HTTP 응답 헤더를 재정의할 수 있어서, 외부 자원을 무시할 수 있다. 이것은 백엔드를 기다릴 필요 없이 원형을 바꿀수 있게 허락한다. 로컬 재정의는 페이지 로드 전반에 걸쳐 개발자도구에서 만든 변경점들을 유지하는것을 허락한다.
작동방식:
개발자도구에서 변경점을 만들면, 개발자도구는 명시된 폴더에 바뀐 파일의 복사본을 저장한다
페이지를 재로드하면, 개발자도구는 네트워크 자원보다 로컬, 바뀐 파일을 제공한다
제한사항
로컬 재정의는 몇가지 예외를 제외하고 네트워크 응답 헤더와 XHR과 fetch요청을 포함한 대부분의 파일 타입을 위해 작동한다.
Local overrides가 허용되었을 때, 캐시가 불허용된다.
개발자도구는 Element창의 DOM트리의 변경은 저장하지 않는다.
Styles창에서 CSS를 편집하고 CSS의 소스가 HTML파일이라면, 개발자도구는 변경점을 저장하지 않는다.
대신, Sources창에서 HTML파일을 편집할 수 있다.
local overrides 셋업하기
Network패널에서 웹 콘텐츠나 응답 헤더를 재정의할 수 있다.
1. 개발자도구에서 Network패널에서 재정의를 원하는 요청을 우클릭하고, override headers또는 override content를 선택한다.
performance녹화 한 timeline을 볼 때 모르는 단어가 있다면 위 참고를 보자.
6. Memory
메모리 창은 javascript object의 메모리 분포를 볼 수 있고, 메모리 누수를 찾고 고립시키고, 함수에 의한 메모리 할당의 명세 등등이 가능한 진단 툴을 제공한다.
개요
메모리 창은 세 개요 타입의 캡처를 허락한다. 이 개요 타입은 다른 관점에서의 스냅샷을 보여주고 다양한 유틸리티를 제공한다:
Heap snapshot. heap snapshot은 페이지의 javascript object와 관련된 DOM 노드 사이의 메모리 분포를 보여준다.
Allocation Instrumentation on timeline. 할당 타임라인은 시간이 지남에 따라 계측된 javascript 메모리 할당을 보여준다. 프로파일이 기록되면 해당 프로파일 내에 할당된 개체를 볼 수 있는 시간 간격을 선택하여 기록이 끝날 때까지 계속 실행할 수 있습니다.메모리 누수의 분리는 이 프로파일을 사용해라.
Allocation sampling. 샘플링 메소드를 사용해 메모리 할당을 기록한다. 이 프로파일 타입은 적은 오버헤드 성능을 가지고 오랜 시간 작동 가능하다. 이것은 js 실행 스택에 의해 고장난 할당의 좋은 근사치를 제공한다.
메모리 전문용어
shallow size - 개체 자체가 들고있는 메모리 크기
retained size - 개체 자체와 그것에 의존적인 개체들이 free되었을 때, GC roots로부터 떨어지는 메모리의 크기다.
objects retaining tree - node와 edge로 이루어진 tree다. distance는 GC roots로부터 떨어져있는 거리이다.
dominators - 도미네이터 개체는 트리 구조로 이루어져있기 때문에, 각 개체는 정확히 하나의 도미네티어를 가진다.
V8 관련
primitive types - Numbers, Booleans, Strings 이것들은 다른 값들을 참조할 수 없고 항상 잎사귀거나 종료 노드다.
Native objects는 js heap에 없는 모든것을 말한다.
Arrays - array는 숫자를 key로 하는 개체이다.
메모리 문제 고치기
페이지 성능에 영향을 미치는 메모리 이슈를 찾는것과 메모리 누수, 메모리 부품, 잦은 가비지콜렉션 위해 크롬과 개발자도구를 사용하는 방법을 배운다.
요약
크롬 작업 매니저에서 현재 너의 페이지가 사용하는 메모리는 얼만큼인지 찾는다.
타임라인 레코딩으로 시간마다 메모리 사용을 시각화한다.
heap snapshots으로 떨어진 DOM trees(메모리 누수의 주 요인)를 확인한다.
할당 타임라인 레토딩으로 JS heap안에 새로운 메모리가 언제 할당되는지 찾는다.
RAIL 성능 모델에서의 영혼 안에서 성능 노력은 유저에 초점을 맞추어야 한다.
메모리 이슈가 중요한 이유는 유저가 종종 지각할 수 있기 때문이다. 유저는 다음 방법으로 메모리 이슈를 감지할 수 있다.
페이지 성능이 시간이 지남에 따라 지속적으로 나빠진다.
페이지의 성능이 일관하여 나쁘다.
페이지 성능이 딜레이되거나 자주 멈춤이 나타난다.
크롬 작업관리자로 실시간 메모리 사용 관찰하기
크롬 메뉴를 열어 도구 더보기 - 작업 관리자로 들어간다.
작업관리자의 헤더를 우클릭해 자바스크립트 메모리를 체크한다.
Memory 열은 순수 메모리를 표현한다. DOM 노드가 여기에 저장된다. 이 값이 증가한다면 DOM노드가 생긴것이다.
Javascript Memory 열은 JS heap을 표현한다.
performance녹화로 메모리 누수 시각화하기
performance창에서 memory를 체크하고 녹화하면 JS heap, Documents, Nodes, Listeners, GPU memory를 시간에 따라 볼 수 있다.
Nodes가 계산식으로 늘어나고, JS Heap가 못처럼 중간중간 변화량이 매우 크다면, 메모리 누수의 가능성이 있다.
Heap snapshot으로 떨어진 DOM 트리 메모리 누수 찾기
DOM 노드는 페이지의 dom 트리와 js코드 상에서 참조가 없어야만 garbage collect된다. 떨어진 DOM트리는 페이지의 dom트리에서는 떨어졌지만 js코드상에서 참조가 된 상태를 뜻한다. 이 떨어진 dom트리는 메모리 누수의 주요 원인이다.
memory창에서 heap snapshot을 선택후 Take snapshot을 하면 된다. class filter에 detached를 입력하면 어떤 dom들이 detach되었는지 확인할 수 있다.
allocation instrumentation on timeline으로 JS heap 메모리 누수 확인하기
memory창의 allocation instrumentation on timeline을 선택하고 녹화를 시작한다. 녹화 시작 후 메모리 누수가 의심되는 행동을 한 후에 녹화를 종료한다. 종료후 timeline을 보면 파란색 바가 있는데, 이 바는 새로운 메모리 할당을 의미한다. 이 새로운 메모리 할당들은 메모리 누수의 원인일 수 있다.
함수로 메모리 누수 조사하기
memory창에서 allocation sampling을 사용해 js 함수에 의한 메모리 할당을 본다. allocation sampling을 체크한 후 Start를 한다. 조사하고싶은 행동을 한 후 Stop을 누른다.
빈번한 garbage collection 찾기
페이지가 빈번하게 일시정지 된다면, garbage collection 이슈일 수 있다. 크롬 작업관리자나 timeline memory 녹화로도 빈번한 garbage collection을 찾을 수 있다. 작업관리자에서 메모리나 js메모리가 빈번하게 상승 또는 하강한다면 빈번한 garbage collection을 나타낸다. timeline 녹화에서, js heap 또는 node의 빈번한 상승 또는 하강은 빈번한 garbage collection을 나타낸다.
문제를 확인했다면, allocation timeline녹화로 어디에서 메모리가 할당되었고 어떤 함수가 할당을 야기했는지 찾을 수 있다.
7. Application
보고 삭제하기
Application창의 Storage를 보면 Local storage와 Session storage를 보고 삭제할 수 있다.
Local storage는 컴퓨터 내부에 저장되어 브라우저 창을 닫아도 값이 저장되어있다. 사이트를 재방문해도 값이 그대로이다.
console 명령
설명
localStorage.key(num)
num번째에 해당하는 localStorage의 Key를 반환
localStorage.getItem(key)
key에 해당하는 localStorage의 value 반환
localStorage.setItem(key, value)
key에 해당하는 localStorage에 value 저장
Session storage는 창을 열었을 때만 임시로 저장되는 값으로 창을 닫으면 값이 사라진다.
console 명령
설명
sessionStorage.key(num)
num번째에 해당하는 sessionStorage의 Key를 반환
sessionStorage.getItem(key)
key에 해당하는 sessionStorage의 value 반환
sessionStorage.setItem(key, value)
key에 해당하는 sessionStorage에 value 저장
IndexedDB도 보고 삭제할 수 있다. Storage는 최대 10MB, string형태만 저장할 수 있지만 IndexedDB는 js가 이해하는 어떠한 값도 저장할 수 있고 용량 제한도 없다.
Application창의 Storage - Cookies에서 쿠키들을 보고, 추가하고, 편집하고 삭제할 수 있다.
Application > Storage > Cache storage를 보면 캐시 데이터를 볼 수 있다.