개발자 도구
고친 사람 github-actions[bot]
개발자 도구는 브라우저가 페이지를 여는 동안 속에서 한 일을 보여 줍니다. 서버와 주고받은 요청을 한 건씩 펼쳐 볼 수 있습니다. 개발에 쓰는 프로그램 전반을 넓게 이렇게 부르기도 합니다. 이 문서는 브라우저에 들어 있는 도구를 다룹니다.
쉽고 빠른 이해
개발자 도구는 브라우저 속을 들여다보는 창입니다. 로그인 버튼을 눌러도 아무 일이 없을 때 열어 봅니다. 어떤 요청이 나갔는지, 서버가 무슨 상태 코드로 답했는지가 보입니다.
이게 없으면 화면만 보고 짐작해야 합니다. 페이지에는 브라우저에서 도는 자바스크립트 코드, 곧 페이지 코드가 실려 옵니다. 목록이 비어 있어도 서버가 실패했는지 페이지 코드가 멈췄는지 가릴 수 없습니다.
어떻게 도나:
- 브라우저에서 키 하나를 눌러 엽니다
- 요청 · 화면 구조 · 오류 메시지를 맡은 패널 가운데 하나를 고릅니다
- 페이지를 새로 고치거나 버튼을 누르면 그동안 일어난 일이 패널에 쌓입니다
대가도 있습니다. 보이는 것은 내 컴퓨터의 브라우저 한 대에서 일어난 일뿐입니다. 서버 안에서 시간이 어디에 들었는지는 서버가 알려 주지 않으면 안 보입니다.
상세
정비소에서 차를 리프트로 들어 올리면 운전석에서는 안 보이던 차 밑이 드러납니다. 운전하는 사람은 차가 덜컹거린다는 것만 압니다. 리프트 아래에 선 정비사는 어느 부품이 헐거운지 봅니다.
개발자 도구는 브라우저를 그 리프트 위에 올립니다. 브라우저는 페이지 하나를 열 때 많은 일을 합니다. 서버에 요청을 여러 번 보냅니다. 받은 문서를 해석해 화면을 그립니다. 페이지에 실려 온 자바스크립트 코드, 곧 페이지 코드도 실행합니다.
평소에는 이 일이 전부 가려져 있습니다. 개발자 도구는 이 일을 한 건씩 펼쳐 보여 줍니다. 페이지를 띄운 채로 값을 바꿔 다시 해 보게도 해 줍니다.
따로 설치하지 않습니다. 데스크톱 브라우저에는 처음부터 들어 있습니다. 대개 키보드 맨 윗줄의 기능 키 F12 로 엽니다. 페이지의 한 곳을 오른쪽 클릭해 「검사」를 고르면 그 부분을 가리킨 채로 열립니다.
패널로 나뉜 도구
개발자 도구는 여러 패널로 나뉩니다. 패널은 개발자 도구 창 위쪽에 늘어선 탭 하나입니다. 패널마다 브라우저가 하는 일 가운데 한 가지를 맡아 보여 줍니다.
아래 표를 읽으려면 낱말 다섯을 알아야 합니다. HTML(HyperText Markup Language)은 웹 페이지의 구조를 적는 언어입니다. 서버가 페이지를 내줄 때 보내는 문서가 이 언어로 쓰여 있습니다.
DOM(Document Object Model, 문서 객체 모델)은 브라우저가 HTML 을 읽어 메모리에 펼쳐 놓은 나무 모양의 구조입니다. 페이지 코드가 이 구조를 고치면 화면도 바뀝니다. 그래서 지금 화면에 무엇이 있는지는 처음 받은 HTML 이 아니라 DOM 이 말해 줍니다.
CSS(Cascading Style Sheets)는 그 구조에 색과 크기와 위치를 입히는 언어입니다. 글자를 빨갛게 하거나 상자를 오른쪽에 붙이는 일이 CSS 로 정해집니다.
중단점은 코드의 한 줄에 걸어 두는 표시입니다. 실행이 그 줄에 닿으면 멈춥니다. 멈춘 동안 변수에 든 값을 들여다볼 수 있습니다.
쿠키는 서버가 브라우저에 맡겨 두는 작은 값입니다. 브라우저는 같은 서버에 요청할 때마다 이 값을 실어 보냅니다. 로그인 상태를 기억하는 세션 값이 흔히 여기 들어 있습니다.
| 패널 | 보여 주는 것 | 백엔드 개발자가 여는 때 |
|---|---|---|
| 요소 (Elements) | 지금의 DOM 과 요소마다 걸린 CSS | 서버가 보낸 HTML 이 화면에서 어떻게 바뀌었나 볼 때 |
| 콘솔 (Console) | 페이지 코드가 남긴 메시지와 오류 | 응답은 왔어도 화면이 멈췄을 때 |
| 소스 (Sources) | 페이지에 실린 코드 파일. 중단점을 건다 | 받은 응답을 페이지 코드가 어떻게 쓰는지 따라갈 때 |
| 네트워크 (Network) | 페이지가 보낸 요청과 받은 응답 전부 | 서버를 부르는 요청이 나갔나, 무엇을 받았나 볼 때 |
| 성능 (Performance) | 녹화한 동안 브라우저가 한 일의 시간표 | 서버 응답은 일찍 왔어도 화면이 늦게 그려질 때 |
| 애플리케이션 (Application) | 쿠키와 브라우저에 저장된 값 | 로그인 쿠키가 남았나, 지워졌나 볼 때 |
패널 이름은 크롬 계열 브라우저를 따랐습니다. 다른 브라우저도 같은 일을 하는 패널을 둡니다. 이름만 조금 다릅니다.
콘솔 패널은 서버의 로그 파일처럼 읽으면 됩니다. 페이지 코드가 남긴 메시지와 오류가 시간 순으로 찍힙니다. 명령을 한 줄 넣어 바로 실행해 볼 수도 있습니다.
화면만 보고는 못 가리는 문제
목록이 비어 있다는 제보가 왔다고 합시다. 개발자 도구가 없으면 무엇이 곤란한지 이 제보 하나로 봅니다.
화면만 봐서는 문제가 어디서 났는지 모릅니다. 요청이 아예 안 나갔을 수 있습니다. 서버가 오류나 빈 목록을 돌려줬을 수 있습니다.
서버는 값을 다 줬을 수도 있습니다. 그 값을 페이지 코드가 쓰다 멈춘 경우입니다.
세 경우는 화면에서 똑같이 빈 목록으로 보입니다. 개발자 도구를 열면 셋이 갈립니다.
응답이 정상인지는 상태 코드로 먼저 봅니다. 상태 코드는 HTTP(HyperText Transfer Protocol) 응답의 첫 줄에 붙는 세 자리 숫자입니다. 200 이면 성공입니다. 500 대면 서버 오류입니다.
아래는 네트워크 패널과 콘솔 패널로 셋을 가리는 순서입니다.
flowchart TD
A["목록이 비어 있다"] --> B["네트워크 패널에 요청이 있나"]
B -->|없다| F["페이지 코드가 요청을 안 보냈다"]
B -->|있다| C["응답이 정상인가"]
C -->|오류 상태 코드 · 빈 목록| S["서버 쪽을 본다"]
C -->|값이 다 왔다| D["콘솔 패널에 오류가 있나"]
D -->|있다| G["페이지 코드가 값을 쓰다 멈췄다"]
D -->|없다| H["값을 받고도 안 그렸다<br/>소스 패널에서 따라간다"]
콘솔에 오류가 없어도 페이지 코드 탓일 수 있습니다. 값을 받고도 목록에 안 그린 경우입니다. 그때는 소스 패널에서 중단점을 걸어 값이 어디로 가는지 따라갑니다.
서버 탓인지 아닌지는 「네트워크 패널에 요청이 있나」와 「응답이 정상인가」 두 칸에서 갈립니다. 그래서 페이지 코드를 안 짜는 백엔드 개발자에게도 이 도구가 쓸모 있습니다.
요청 한 건을 펼치는 네트워크 패널
백엔드 개발자가 가장 오래 보는 패널입니다. 요청 한 건을 열어 무엇이 보이는지, 시간이 어디에 쓰였는지를 봅니다.
네트워크 패널은 페이지가 보낸 요청을 한 줄에 하나씩 쌓습니다. 줄마다 주소와 메서드, 상태 코드, 크기, 걸린 시간이 적힙니다. 개발자 도구를 연 뒤의 요청만 쌓입니다. 그래서 열어 두고 페이지를 새로 고치는 것이 보통입니다.
한 줄을 누르면 그 요청이 펼쳐집니다. 요청 헤더와 응답 헤더, 응답 본문이 따로 나옵니다. 서버가 보낸 JSON(JavaScript Object Notation) 응답도 여기서 바로 읽습니다.
펼친 요청에는 시간을 쪼갠 표도 있습니다. 요청 한 건의 지연을 단계별로 나눠 보여 주는 표입니다.
첫 단계는 DNS(Domain Name System) 조회입니다. 도메인 이름을 컴퓨터가 쓰는 숫자 주소로 바꾸는 일입니다.
다음은 TCP(Transmission Control Protocol) 연결입니다. 데이터를 주고받기 전에 브라우저와 서버가 통로를 맺는 일입니다.
https 로 시작하는 주소라면 TLS(Transport Layer Security) 핸드셰이크가 뒤따릅니다. 맺은 통로를 암호화하려고 양쪽이 열쇠를 맞추는 인사입니다.
그다음에 요청을 보내고 응답의 첫 바이트를 기다립니다. 요청을 보낸 뒤 첫 바이트가 올 때까지의 구간이 TTFB(Time To First Byte, 첫 바이트까지의 시간)입니다. 첫 바이트가 오면 나머지를 내려받습니다.
아래 그림에서 색을 입힌 구간이 TTFB 입니다.
sequenceDiagram
participant 브라우저
participant DNS as DNS 서버
participant 서버 as 웹 서버
브라우저->>DNS: 도메인 이름의 숫자 주소를 묻는다
DNS-->>브라우저: 숫자 주소
브라우저->>서버: TCP 연결을 맺는다
서버-->>브라우저: 연결됨
브라우저->>서버: TLS 핸드셰이크
서버-->>브라우저: 암호화 준비 끝
rect rgba(78, 201, 176, 0.2)
Note over 브라우저,서버: TTFB 구간
브라우저->>서버: HTTP 요청
Note over 서버: 요청을 처리한다
서버-->>브라우저: 응답의 첫 바이트
end
서버-->>브라우저: 응답의 나머지를 내려받는다
백엔드 개발자가 눈여겨볼 구간이 이 TTFB 입니다. 서버가 요청을 처리한 시간과 오가는 길의 시간이 이 구간에 함께 들어갑니다.
이 구간이 길면 서버 쪽을 봅니다. 내려받기가 길면 응답이 크거나 네트워크 대역폭이 모자란 것입니다. 같은 서버에 다시 요청하면 앞서 맺은 연결을 이어 쓰기도 합니다. 그때는 DNS 와 연결 단계가 비어 있습니다.
서버 안의 시간을 보태는 Server-Timing
TTFB 안은 더 쪼개 볼 수 있습니다. 네트워크 패널은 서버 안에서 시간이 어디에 들었는지 모릅니다. 서버가 알려 줘야 보입니다.
서버가 Server-Timing 응답 헤더를 붙이면 그 값이 시간 표에 함께 나옵니다. 아래는 데이터베이스 구간과 나머지 처리 구간에 걸린 시간을 알리는 헤더입니다.
Server-Timing: db;dur=53, app;dur=47.2
db 와 app 은 서버가 붙인 구간 이름입니다. dur 는 그 구간에 걸린 시간을 밀리초로 적습니다. 서버 로그를 열지 않아도 브라우저 쪽에서 시간을 많이 쓴 구간이 드러납니다.
요청을 터미널에서 다시 보내기
브라우저에서 본 요청은 서버 개발자의 터미널로 옮길 수 있습니다.
curl 은 명령줄에서 HTTP 요청을 보내는 프로그램입니다. 네트워크 패널의 요청 줄을 오른쪽 클릭하면 그 요청을 curl 명령으로 복사하는 메뉴가 있습니다. 헤더와 쿠키까지 같이 담깁니다.
curl 'https://shop.example.com/api/cart' \
-H 'accept: application/json' \
-H 'cookie: session=abc123'
복사한 명령을 터미널에 붙이면 브라우저가 보낸 것과 같은 요청이 한 번 더 나갑니다. 브라우저에서만 나는 오류를 서버 개발자가 자기 터미널에서 되풀이해 볼 수 있습니다.
콘솔에만 찍히는 CORS 오류
서버 로그만 봐서는 문제가 안 보이는 경우가 있습니다. CORS 오류가 그 하나입니다.
CORS(Cross-Origin Resource Sharing, 교차 출처 리소스 공유)는 다른 주소의 서버가 준 응답을 페이지 코드가 읽어도 되는지 서버가 허락하는 규칙입니다. 허락은 응답 헤더에 적습니다.
페이지를 내주는 서버와 데이터를 내주는 서버의 주소가 다를 때 흔히 부딪힙니다. 데이터를 내주는 쪽은 대개 API(Application Programming Interface) 서버입니다. 페이지 코드가 데이터를 받으려고 부르는 서버의 창구가 API 입니다.
서버가 허락하는 헤더를 안 붙이면 브라우저는 응답을 페이지 코드에 넘기지 않습니다. 서버가 요청을 처리해 응답을 보냈어도 그렇습니다. 서버 쪽에서는 문제가 없어 보입니다. 막힌 까닭은 브라우저의 콘솔 패널에 오류로 찍힙니다.
화면 그리는 시간을 재는 성능 패널
서버 응답은 일찍 왔어도 화면이 늦게 그려질 때 보는 곳입니다. 브라우저는 화면을 세 단계로 그립니다.
성능 패널은 녹화 단추를 누른 동안 브라우저가 한 일을 시간 순으로 적습니다. 페이지 코드 실행 · 스타일 계산 · 레이아웃 · 페인트가 저마다 막대로 나옵니다. 어느 막대가 긴지 보면 시간을 잡아먹은 단계가 드러납니다.
이미 칠한 화면 일부를 다시 칠하는 일이 리페인트입니다. 개발자 도구에는 다시 칠한 영역을 초록색으로 덧칠해 보여 주는 설정도 있습니다. 켜 두면 쉬지 않고 다시 칠해지는 영역이 눈에 보입니다.
브라우저에서 바꾼 값
개발자 도구로는 페이지를 고칠 수도 있습니다. 서버를 짜는 사람은 이 점을 알아 둬야 합니다.
요소 패널에서는 DOM 을 손으로 고칠 수 있습니다. 비활성으로 막아 둔 버튼을 살릴 수 있습니다. 숨겨 둔 입력 칸의 값도 바꿀 수 있습니다. 고친 것은 내 브라우저에만 남습니다. 새로 고치면 사라집니다.
고친 페이지에서 보낸 요청은 서버에 평소처럼 닿습니다. 콘솔 패널에서 코드 한 줄로 서버에 요청을 직접 보낼 수도 있습니다. 그래서 브라우저 쪽에 넣어 둔 검사는 서버에 닿는 요청을 막지 못합니다. 서버가 받은 값을 다시 검사하는 입력 검증이 따로 있는 까닭입니다.
개발자 도구가 못 보는 것
개발자 도구로 본 값에도 한계가 있습니다. 그 한계 밖에서는 다른 수단으로 넘어갑니다.
개발자 도구가 보여 주는 것은 내 컴퓨터의 브라우저 한 대에서 한 번 일어난 일입니다. 개발자의 컴퓨터는 대개 빠릅니다. 네트워크도 대개 좋습니다. 사용자의 휴대폰에서 같은 페이지가 얼마나 걸리는지는 여기서 안 나옵니다.
많은 사용자의 경험을 모으려면 실사용자 모니터링을 씁니다. 사용자 브라우저가 잰 값을 서버로 보내 모으는 방식입니다.
이렇게 모으는 값으로 코어 웹 바이탈이 흔히 쓰입니다. 페이지가 뜨는 속도, 누른 것에 반응하는 속도, 화면이 덜 흔들리는 정도를 재는 구글의 지표 몇 개입니다.
서버 안도 보이지 않습니다. 서버가 어느 함수에서 시간을 썼는지는 서버 쪽의 로그와 프로파일러가 봅니다. Server-Timing 헤더로는 그 결과 가운데 일부만 브라우저까지 가져올 수 있습니다.
같은 점검을 매번 되풀이할 때도 손으로 여는 개발자 도구는 맞지 않습니다. 그때는 헤드리스 브라우저를 코드로 부립니다. 헤드리스 브라우저는 창을 띄우지 않고 도는 브라우저입니다. 사람이 누르던 것을 코드가 대신 누릅니다.
크롬 계열 브라우저는 Chrome DevTools Protocol 을 밖에 열어 둡니다. 바깥 프로그램이 개발자 도구와 같은 명령을 브라우저에 보낼 수 있게 정한 프로토콜입니다. Puppeteer 같은 자동화 라이브러리가 이 프로토콜로 명령을 보내 같은 일을 코드로 합니다.
관련 항목
개발자 도구가 들어 있는 브라우저
브라우저 · Chromium · Google Chrome · Firefox · Safari · Microsoft Edge
개발자 도구 안에 든 도구
콘솔 · 디버거 · 중단점 · 소스 맵 · Lighthouse
개발자 도구로 들여다보는 페이지의 구성 요소
DOM · HTML · CSS · JavaScript · 쿠키 · 웹 스토리지 · 서비스 워커
네트워크 패널이 쪼개 보이는 요청과 그 시간
HTTP · 요청 메서드 · 헤더 · 상태 코드 · JSON · 지연 · DNS · TCP · TLS · TTFB · Server-Timing · PerformanceServerTiming
성능 패널이 보여 주는 렌더링 단계
렌더링 엔진 · 레이아웃 · 리플로 · 페인트 · 리페인트 · 합성
콘솔에 찍히는 브라우저 보안 오류
CORS · 동일 출처 정책 · 콘텐츠 보안 정책 · 혼합 콘텐츠
개발자 도구를 코드로 부르는 자동화
헤드리스 브라우저 · Chrome DevTools Protocol · 프로토콜 · 브라우저 자동화 · Puppeteer · Playwright · WebDriver
브라우저 밖에서 요청을 보고 다시 보내는 도구
curl · HTTP 클라이언트 · 명령줄 HTTP 클라이언트 · Postman · 프록시
개발자 도구 밖에서 걸린 시간을 재는 수단
실사용자 모니터링 · 코어 웹 바이탈 · 프로파일러 · 로그 · 애플리케이션 성능 모니터링 · 분산 추적
브라우저에서 바꾼 값을 서버에서 막는 방어
입력 검증 · 클라이언트 측 검증 · 웹 애플리케이션 보안 · 파라미터 변조
넓은 뜻의 개발자 도구가 가리키는 프로그램
다른 이름: DevTools · developer tools · 브라우저 개발자 도구 · 데브툴즈