이 시리즈는 주소창에 문자열을 입력하는 순간부터 화면에 픽셀이 찍히기까지의 긴 여정을, 이름 조회와 연결, 문서와 스타일의 해석, 배치와 색칠, 스크립트의 실행, 캐시와 저장과 보안에 이르기까지 한 단계씩 열어 왔다. 마지막 편은 이 모든 단계를 실제로 눈으로 확인하고 진단하는 도구를 다룬다. 앞선 여러 편에서 이 단계는 눈으로 확인해야 한다고 미뤄 두었던 약속을, 이제 그 도구의 활용으로 갚는다.


브라우저에 내장된 이 도구는 지금까지 배운 원리를 실전에 잇는 다리다. 각 단계의 이름과 의미를 아는 사람에게 이 도구는 원인을 짚는 지도가 되지만, 그 배경을 모르는 사람에게는 숫자와 막대의 나열일 뿐이다. 그래서 이 도구를 잘 쓰는 능력은 이 시리즈가 다룬 원리를 얼마나 손에 쥐고 있느냐에 달려 있다. 이번 편은 그 원리를 도구의 각 화면에 대응시켜 읽는 법을 짚는다.

구조를 들여다보는 창

가장 기본이 되는 화면은 브라우저가 세운 문서의 나무를 그대로 펼쳐 보여 주는 창이다. 앞서 문서 파싱 편에서 다룬 대로, 브라우저는 받아온 텍스트를 나무 구조로 바꾸고 그 위에서 모든 것을 그린다. 이 창은 지금 브라우저가 쥐고 있는 나무의 실제 모습을 보여 주므로, 작성한 문서가 의도대로 해석되었는지를 확인할 수 있다.


이 창의 쓸모는 특히 스크립트가 구조를 바꾸는 화면에서 드러난다. 처음 받은 문서는 멀쩡했어도 스크립트가 마디를 붙이고 떼는 과정에서 구조가 달라질 수 있는데, 이 창은 그 변형이 반영된 현재의 나무를 보여 준다. 원래 문서만 들여다볼 때는 보이지 않던, 자동으로 닫힌 태그나 옮겨진 요소가 이 창에서 드러난다.


같은 화면에서 각 요소에 적용된 스타일도 확인할 수 있다. 스타일 편에서 다룬 대로, 한 요소에는 여러 규칙이 다투어 최종 값이 정해지는데, 이 창은 어떤 규칙들이 그 요소에 걸렸고 그중 무엇이 이겼는지를 보여 준다. 스타일이 예상과 어긋날 때, 어느 규칙이 우선순위에서 이겨 그 값을 밀어냈는지를 여기서 차분히 추적할 수 있다.


물려받은 값과 직접 정해진 값도 이 창에서 구분된다. 어떤 값이 부모에게서 물려받은 것인지, 이 요소에 직접 걸린 규칙에서 온 것인지를 나누어 보여 주므로, 값이 이상하게 나올 때 그것이 물려받음을 잘못 예상한 탓인지 규칙의 다툼 탓인지를 가릴 수 있다. 구조와 스타일을 함께 들여다보는 이 창이 화면 문제 진단의 출발점이다.

통신을 시간 축에 펼치기

다음으로 중요한 화면은 자원이 오가는 통신을 시간 순서로 펼쳐 보여 주는 창이다. 이 창은 각 요청이 언제 시작해 언제 끝났는지, 그 안에서 이름 조회와 연결과 전송이 각각 얼마를 썼는지를 막대로 나누어 보여 준다. 앞서 다룬 여정의 앞부분, 곧 화면이 뜨기 전의 준비 구간이 이 창에 고스란히 담긴다.


이 창으로 첫 화면이 늦는 원인을 어느 단계로 좁힐 수 있다. 막대에서 이름 조회 구간이 유독 길면 조회가 병목이고, 연결 구간이 길면 연결 협상이, 전송 구간이 길면 자원 자체가 무겁거나 서버가 느린 것이다. 막연히 느리다는 인상 대신 어느 구간이 시간을 잡아먹었는지를 이 막대에서 짚으면, 개선의 초점이 분명해진다.


캐시가 잘 동작하는지도 이 창에서 확인한다. 캐시 편에서 다룬 대로, 재사용되는 자원은 통신을 거치지 않거나 가벼운 재검증만 거친다. 이 창은 각 자원이 통신망에서 새로 왔는지, 저장된 것에서 왔는지, 재검증만 했는지를 표시한다. 재사용될 것으로 기대한 자원이 매번 새로 오고 있다면, 유효기간이나 이름 표식의 설정이 잘못된 것이다.


자원들이 도착하는 순서와 서로의 의존도 이 창에서 드러난다. 여정 편에서 다룬 대로, 무거운 자원 하나가 앞을 막으면 중요한 자원이 뒤로 밀린다. 이 창의 시간 축을 보면 어떤 자원이 다른 자원을 기다리느라 늦어졌는지, 우선순위가 잘못 매겨져 정작 중요한 것이 뒤에 왔는지를 알 수 있다. 크기뿐 아니라 순서의 문제를 이 창이 보여 준다.

화면 그리기를 해부하기

렌더링 성능을 다룰 때 가장 요긴한 화면은 화면을 그리는 과정을 시간 축에 해부해 보여 주는 창이다. 성능 편에서 다룬 대로, 한 프레임의 예산 안에 스크립트 실행과 자리 잡기와 색칠과 합치기가 모두 들어가야 하는데, 이 창은 각 프레임에서 이 작업들이 각각 얼마를 썼는지를 펼쳐 보여 준다.


이 창으로 어느 프레임이 예산을 넘겼는지, 그 프레임에서 무엇이 시간을 잡아먹었는지를 짚을 수 있다. 유독 긴 프레임을 골라 그 안을 들여다보면, 무거운 스크립트가 흐름을 붙들었는지, 자리 잡기가 과도하게 반복되었는지, 넓은 영역의 색칠이 부담이 되었는지가 드러난다. 리플로우와 리페인트 편에서 다룬 갱신의 깊이를 이 창에서 실제로 확인하는 것이다.


특히 이 창은 어떤 변화가 자리를 다시 잡게 만들었는지를 보여 주어, 강제로 앞당겨진 리플로우를 잡아내는 데 유용하다. 배치 편에서 다룬, 읽기와 쓰기를 뒤섞어 리플로우를 반복시키는 함정이 이 창에서 촘촘히 반복되는 자리 잡기 막대로 나타난다. 이 막대를 발견하면 그 부근의 코드에서 읽기와 쓰기가 교차하고 있음을 의심할 수 있다.


이벤트 루프 편에서 다룬 긴 작업도 이 창에서 드러난다. 하나의 일감이 흐름을 오래 붙들면, 그 구간이 유난히 긴 막대로 나타나고 그동안 화면 그리기가 끊긴 흔적이 보인다. 이 긴 막대를 골라내면, 어떤 작업이 순환을 붙들어 화면을 멈추게 했는지를 특정할 수 있다. 짐작이 아니라 이 막대를 근거로 삼아야 최적화의 방향이 어긋나지 않는다.

저장과 상태를 확인하기

브라우저에 담긴 데이터와 상태를 확인하는 화면도 있다. 쿠키와 스토리지 편에서 다룬 여러 저장 수단에 지금 무엇이 담겨 있는지를 이 창에서 들여다볼 수 있다. 요청에 실려 오가는 작은 데이터, 서버로 오가지 않는 저장, 구조적인 데이터 저장에 각각 어떤 값이 들어 있는지가 나뉘어 표시된다.


이 창은 저장 수단을 올바로 골랐는지를 점검하는 데 쓰인다. 서버가 볼 필요 없는 데이터가 요청에 실려 오가는 수단에 담겨 있다면, 매 요청을 무겁게 하는 낭비가 진행 중인 것이다. 민감한 데이터가 스크립트로 읽히는 자리에 무방비로 담겨 있다면, 유출의 위험이 있는 것이다. 무엇이 어디에 담겨 있는지를 눈으로 확인해야 이런 문제가 보인다.


서비스 워커 편에서 다룬 중개자의 상태도 이 화면에서 확인한다. 지금 어떤 중개자가 등록되어 있고 어느 단계에 있는지, 새 판이 통제권을 넘겨받기를 기다리고 있는지가 표시된다. 갱신이 제때 반영되지 않는 것처럼 보일 때, 이 화면에서 옛 중개자가 아직 통제하고 있음을 확인하면 원인이 분명해진다.


중개자가 저장해 둔 자원의 목록도 여기서 볼 수 있다. 옛 저장본이 남아 사용자를 낡은 화면에 가두는 사고가 의심될 때, 이 목록에서 어떤 자원이 언제 저장된 채 남아 있는지를 확인할 수 있다. 필요하면 이 저장을 비워, 중개자가 새 자원을 다시 받게 만들어 문제를 풀 수 있다. 저장과 상태를 들여다보는 이 창이 캐시와 오프라인 관련 사고의 진단을 돕는다.

기록을 남기고 코드를 멈춰 세우기

지금까지의 창들이 브라우저의 상태를 들여다보는 것이라면, 스크립트의 동작을 직접 살피는 화면도 있다. 가장 단순한 것은 스크립트가 남긴 기록을 보여 주는 창이다. 코드가 실행되며 남긴 메시지와 오류가 이곳에 시간 순서로 쌓여, 무엇이 언제 실행되었고 어디서 문제가 생겼는지를 알려 준다.


이 창은 스크립트에서 발생한 오류를 가장 먼저 마주하는 자리다. 코드가 어긋나 멈추면 그 원인과 위치가 이곳에 나타나므로, 화면이 갑자기 동작하지 않을 때 가장 먼저 열어 볼 창이다. 오류 메시지는 어느 코드의 몇 번째 자리에서 무슨 문제가 생겼는지를 알려 주어, 헤매지 않고 원인의 지점으로 곧장 갈 수 있게 한다.


기록을 남기는 것만으로 부족할 때는 실행을 특정 지점에서 멈춰 세워 들여다보는 방법이 있다. 코드의 어느 자리에 멈춤 지점을 걸어 두면, 실행이 그 자리에 이르렀을 때 멈추어 그 순간의 값들이 어떤 상태인지를 살필 수 있다. 앞서 다룬 한 줄기 흐름이 그 지점에서 잠시 멈춘 것이므로, 그때의 값과 흐름을 차분히 확인할 수 있다.


멈춰 세운 뒤에는 한 걸음씩 실행을 이어가며 값이 어떻게 변하는지를 따라갈 수 있다. 한 문장을 실행하고 값의 변화를 보고, 다시 다음 문장으로 넘어가는 식이다. 이렇게 코드를 한 걸음씩 밟으면, 어느 지점에서 값이 예상과 달라지는지를 정확히 짚을 수 있다. 기록만으로는 보이지 않던 미묘한 어긋남이 이 한 걸음씩의 추적에서 드러난다.


이벤트 루프 편에서 다룬 실행 순서의 문제도 이 방식으로 확인할 수 있다. 여러 일감이 어떤 순서로 처리되는지가 헷갈릴 때, 각 지점에 멈춤을 걸어 무엇이 먼저 멈추는지를 보면 순서가 눈에 들어온다. 짐작으로 순서를 그리는 대신, 실제로 멈춰 세워 확인하면 그 순서가 규칙대로 흐르고 있음을 확인할 수 있다.


이 창들은 서로 떨어져 있지 않고 함께 쓰일 때 힘을 발한다. 통신을 펼치는 창에서 어떤 자원이 늦게 왔음을 확인하고, 그리기를 해부하는 창에서 그 지연이 화면을 어떻게 붙잡았는지를 보고, 기록을 남기는 창에서 그때 스크립트가 무슨 오류를 냈는지를 잇는 식이다. 하나의 창이 가리킨 단서를 다른 창에서 이어 확인하면, 흩어진 증상이 하나의 원인으로 모인다.


그래서 진단에 능숙해진다는 것은 어느 증상에 어느 창을 열어야 하는지를 몸에 익히는 일이기도 하다. 첫 화면이 늦으면 통신을 펼치는 창을, 움직임이 끊기면 그리기를 해부하는 창을, 동작이 멈추면 기록을 남기는 창을, 낡은 화면에 갇히면 저장과 상태를 보는 창을 먼저 연다. 증상과 창을 짝지어 아는 것이, 원리를 도구로 잇는 마지막 연결 고리다.

도구를 넘어 원리로

지금까지 살펴본 여러 창은 각각 이 시리즈의 한 편씩에 대응한다. 구조를 보는 창은 문서와 스타일의 해석에, 통신을 펼치는 창은 조회와 연결과 캐시에, 그리기를 해부하는 창은 배치와 색칠과 성능에, 상태를 보는 창은 저장과 보안과 오프라인에 대응한다. 도구의 각 화면은 원리의 각 단계를 비추는 거울인 셈이다.


그래서 이 도구를 잘 쓰는 능력은 도구의 사용법을 외우는 데서 오지 않는다. 각 화면이 어느 단계를 비추는지, 그 단계에서 무슨 일이 벌어지는지를 알아야 화면에 나타난 숫자와 막대가 의미를 갖는다. 원리를 모르면 같은 화면도 그저 어지러운 정보의 나열이지만, 원리를 아는 사람에게는 원인을 가리키는 이정표가 된다. 이것이 이 시리즈가 도구가 아니라 원리를 먼저 다룬 이유다.


진단의 태도에도 원칙이 있다. 문제가 느껴질 때 짐작으로 손을 대는 대신, 먼저 알맞은 창을 열어 어느 단계에서 벌어지는 일인지를 특정하는 것이다. 그다음 그 단계의 원리에 비추어 원인을 좁히고, 고친 뒤에는 다시 같은 창으로 개선을 확인한다. 재고 고치고 다시 재는 이 순환이, 근거 없는 손댐이 오히려 문제를 키우는 것을 막는다.


이 시리즈는 주소를 해석하는 일에서 출발해, 이름 조회와 연결, 문서와 스타일, 배치와 색칠, 스크립트와 순환, 갱신과 성능, 캐시와 저장, 보안과 오프라인, 그리고 이 모든 것을 확인하는 도구까지 한 바퀴를 돌았다. 브라우저 안에서 벌어지는 일의 원리를 손에 쥐고 있으면, 새로운 도구와 프레임워크가 아무리 바뀌어도 그 아래에서 무슨 일이 벌어지는지를 스스로 읽어 낼 수 있다. 겉의 도구는 낡아도 그 아래를 흐르는 원리는 낡지 않는다. 이 시리즈가 그 단단한 밑바탕을 세우는 데 보탬이 되었기를 바란다.