IE11을 이용한 JavaScript 디버깅 10, F12 개발자 도구 네트워크 창 Part 1

등록일시: 2019-03-19 08:00,  수정일시: 2019-09-25 21:38
조회수: 1,167

브라우저를 기반으로 한 웹 응용 프로그램 개발 생태계에서 클라이언트 측 개발의 난이도와 복잡성은 이미 서버 측에 못지 않습니다. 이런 어려움에 대한 대표적인 방안 중 하나로 대부분의 최신 브라우저들은 수 년 전부터 F12 개발자 도구를 제공하고 있습니다. F12 개발자 도구를 활용하면 직면한 문제점을 해결할 수 있는 실마리를 손쉽게 발견할 수 있는 경우가 많습니다. 그러나 초보자나 갑자기 웹 환경에서 작업하게 된 다른 언어의 전문가가 F12 개발자 도구에 부담 없이 접근할 수 있게 실질적인 도움을 제공하는 자료는 아직 많이 부족합니다.

이 시리즈에서는 가장 단순한 F12 개발자 도구를 갖고 있는 IE11을 사용해서 JavaScript를 디버깅하는 초보적인 수준의 방법을 소개합니다. F12 개발자 도구에서 어떤 기능의 도구가 제공되며 그 도구를 어떤 경우에 어떤 방식으로 활용할 수 있을지 간단히 경험해보고, 자신이 선호하는 다른 최신 브라우저에서 그에 대응하는 기능을 찾아서 사용할 수 있는 시작점이 되는 것이 본 시리즈의 목표입니다.

목차: IE11을 이용한 JavaScript 디버깅

들어가기 전에

본문에서는 F12 개발자 도구의 네트워크 창이 제공하는 기능들을 살펴봅니다.

네트워크 창은 브라우저와 서버 간에 이루어지는 통신을 모니터링 하기 위한 도구입니다. 통신 과정 중 특이 사항이 발생하지는 않았는지, 어떤 상태의 어떤 정보를 전송하고 수신했는지, 그리고 특정 정보를 수신하는데 얼마만큼의 시간이 걸렸는지 같은 정보들을 확인하고 분석할 수 있습니다.

방금 작업을 마친 페이지가 기대한 대로 동작하지 않을 경우, 가장 먼저 확인해봐야 할 곳 중 한 군데가 바로 네트워크 창입니다. 가령 URL을 잘못 지정해서 404 Not Found 오류가 발생했을 수도 있고, 서버 측 코드에 오류가 존재해서 500 Internal Server Error가 발생했을 수도 있습니다. 또는 수정한 코드에는 아무런 문제가 없지만 304 Not Modified 응답에 의해서 여전히 브라우저의 캐시에 저장된 기존 코드가 사용되고 있을 수도 있습니다. 네트워크 창을 살펴보면 이런 정보들을 한눈에 파악할 수 있습니다.

그뿐만 아니라 Ajax 통신 과정 중 문제가 발생한 경우에도 디버거 창과 네트워크 창의 기능을 적절히 활용하면 Fiddler 같은 외부 도구의 도움 없이도 손쉽게 문제의 원인을 파악하고 해결할 수 있습니다.

안타깝게도 본문의 주제인 IE11에서는 다소 빛바랜 얘기지만, 다른 최신 브라우저에서는 CORS (Cross-Origin Resource Sharing) 또는 CSP (Content Security Policy) 관련 이슈가 발생하는 경우에도 네트워크 창을 확인해보면 문제 해결에 유용한 정보를 얻을 수 있습니다.

노트

다만 IE11은 CORS와 CSP를 온전하게 지원하지 않습니다. 예를 들어 IE11은 도메인 원본을 비교할 때 포트를 감안하지 않으며, CSP는 극히 제한적으로만 지원된다고 보시면 무방합니다. 결과적으로는 이런 점들이 모여서 사용자의 보안을 위협하는 원인이 된다고 말할 수 있을 것입니다.

기본적인 모니터링

프로파일링 세션 시작 및 중지

브라우저와 서버 간의 트래픽을 모니터링 하기 위해서는 먼저 프로파일링 세션을 시작해야 합니다. 프로파일링 세션이 중지된 상태에서는 어떠한 관련 정보도 수집되지 않습니다. 프로파일링 세션이 시작된 상태인지 확인할 수 있는 가장 간단한 방법은 네트워크 창의 탭 우측에 다음과 같은 아이콘이 나타나 있는지를 확인하는 것입니다. 만약 이 아이콘이 나타나 있다면 프로파일링 세션이 실행 중인 것입니다.

F12 개발자 도구 - 네트워크 창 - 프로파일링 세션 활성 상태

반면 이 아이콘이 나타나 있지 않다면 현재 프로파일링 세션은 중지된 것입니다.

F12 개발자 도구 - 네트워크 창 - 프로파일링 세션 비활성 상태

프로파일링 세션은 네트워크 창의 툴 바에서 프로파일링 세션 시작 버튼과 프로파일링 세션 중지 버튼을 클릭해서 시작하거나 중지할 수 있고, 단축키인 Ctrl+E 키를 이용해서 상태를 토글할 수도 있습니다.

Microsoft (R) 진단 허브 표준 수집기 서비스

네트워크 창의 기능 중 대다수는 Microsoft (R) 진단 허브 표준 수집기 서비스를 기반으로 하고 있습니다. 따라서 이 서비스에 문제가 있거나 중지되어 있으면 관련 기능들이 정상적으로 동작하지 않습니다. 이는 비단 IE11뿐만 아니라 Edge에도 해당되는 얘기입니다. 만약 문제가 생겨서 이 서비스를 재시작했다면 브라우저를 껏다가 다시 실행해야만 정상적으로 동작할 것입니다.

서비스 - Microsoft (R) 진단 허브 표준 수집기 서비스

인터넷을 검색하다 보면 윈도우 최적화 팁이라면서 이 서비스를 '사용 안 함'으로 설정하도록 권유하는 블로그 글을 간혹 볼 수 있으므로 주의하시기 바랍니다.

대상 페이지 탐색

프로파일링 세션을 시작했다면 이제 통신 내용을 살펴보고자 하는 웹 페이지를 탐색하면 됩니다. 그러면 다음과 같이 해당 웹 페이지를 탐색하기 위해서 서버에 요청하고 응답받은 모든 전송 내역 목록이 타임라인 순으로 정렬되어 출력됩니다.

F12 개발자 도구 - 네트워크 창 - 모니터링 목록

간단하게 하단 상태 바에 출력된 요약 정보를 살펴보면, 총 30건의 요청이 아무런 오류 없이 2.61초만에 수행되어 정상적으로 응답 받았음을 확인할 수 있습니다. 전송 내역 목록에 대한 보다 자세한 사항들은 잠시 후에 다시 살펴보도록 하겠습니다.

만약 전송 내역 목록만 중점적으로 넓게 살펴보고 싶다면 머리글 탭 좌측의 화살표 버튼을 클릭해서 우측의 탭들을 잠시 숨길 수 있습니다. 물론 언제라도 버튼을 다시 클릭하면 탭들을 보이게 할 수 있습니다.

F12 개발자 도구 - 네트워크 창 - 목록 넓게 보기

HAR 파일 내보내기

필요한 경우, 툴 바의 HAR로 내보내기 버튼을 클릭해서 현재 네트워크 프로파일링 세션의 정보를 HAR (HTTP Archive) 형식의 파일로 내보낼 수 있습니다. 그런 다음, FiddlerHttpWatch 같은 도구를 이용해서 디버깅이나 성능 분석 등의 작업에 활용할 수 있습니다. 참고로 IE11에는 내보낸 HAR 파일을 다시 읽어들이는 기능은 없습니다.

F12 개발자 도구 - 네트워크 창 - HAR로 내보내기

그런데 HAR 파일을 활용할 때는 한 가지 주의해야 할 점이 있습니다. HAR 파일에는 자세한 성능 데이터가 담긴 HTTP 전송 내역이 JSON 형태로 저장되며, 그 대상에는 페이지의 내용이 함께 포함됩니다. 그런데 문제는 단지 기록 중 다운로드 된 웹 페이지의 내용만 저장되는 것이 아니라 쿠키를 비롯한 제출된 모든 정보가 함께 저장된다는 점입니다. 따라서 어떤 페이지의 프로파일링 세션을 저장하는지에 따라서 사용자가 입력한 비밀번호를 비롯한 각종 개인정보가 함께 저장될 가능성이 있으므로 활용에 각별히 주의를 기울여야만 합니다.

다음은 실제로 제 개인 홈페이지의 로그인 트래픽을 HAR 파일로 내보내서 그 내용을 살펴본 모습입니다. 방금 언급한 것처럼 비밀번호가 함께 저장되어 있는 것을 확인할 수 있습니다.

F12 개발자 도구 - 네트워크 창 - HAR로 내보내기

항상 서버에서 새로 고침

캐시(Cache)는 웹 개발에 있어서 뿐만 아니라 컴퓨터 공학 전반에 걸쳐서 매우 광범위하게 사용되는 개념입니다. 그중에서도 브라우저의 캐시는 한 번 로딩했던 페이지의 리소스를 자체적인 저장소에 보관해두었다가, 해당 리소스를 다시 사용해야 할 때 매번 서버로부터 리소스를 새로 받아오는 대신 캐시에 보관해두었던 리소스를 다시 사용함으로써 페이지의 로딩 속도를 높이고 트래픽의 총량을 줄여주는 유용한 기능입니다.

그런데 문제는 개발자가 캐시에 저장된 리소스를 재사용하고자 할 때와 서버로부터 새로 받아온 리소스를 사용하고자 할 때의 차이를 브라우저의 캐시 메커니즘이 지능적으로 완벽하게 구분하는 것이 거의 불가능하다는 점입니다.

가령 버그가 존재하는 클라이언트 측 코드를 수정해서 이미 배포했지만, 특정 사용자의 브라우저 환경에서는 여전히 캐시에 저장된 과거의 코드가 사용되고 있을 수도 있습니다. 또는 반대로 수정된 내용이 없음에도 불구하고 잘못된 서버 구성으로 인해 캐시를 무시하고 매번 서버로부터 새로운 데이터를 받아올 수도 있습니다. 아마도 대부분의 웹 개발자들이 코드를 잘못 작성한 것으로 오해하고 몇 시간 동안 고민했지만, 나중에 알고 보니 캐시 때문이었던 경험을 한 두 번쯤은 갖고 있을 것입니다. 그래서 결국은 인터넷 옵션 메뉴에서 몇 번씩 캐시를 모두 지우고 다시 테스트를 수행해서 문제가 해결되었음을 확인하거나, 사용자에게 캐시를 지우고 다시 테스트해 볼 것을 유선상으로 안내하기도 합니다.

그러나 적어도 개발자 자신의 클라이언트 환경에서는 네트워크 창이 제공하는 항상 서버에서 새로 고침 기능을 활용하면 매번 번거롭게 인터넷 옵션 메뉴를 열고 닫으며 캐시를 지워가면서 테스트를 수행할 필요가 없습니다. 항상 서버에서 새로 고침 기능을 활성화시키면 캐시에 저장된 기존 리소스를 무시하고 항상 서버로부터 리소스를 새로 받아옵니다.

네트워크 창의 툴 바에서 항상 서버에서 새로 고침 버튼을 클릭하면 이 기능을 토글할 수 있습니다. 다음 이미지는 항상 서버에서 새로 고침 기능을 비활성시키고 제 개인 홈페이지의 메인 페이지를 새로 고침한 후의 전송 내역 목록을 보여줍니다. 달리 말하자면 아마도 일반 사용자들은 캐시 기능이 적용된 이런 형태의 응답을 받게 될 것입니다.

F12 개발자 도구 - 네트워크 창 - 항상 서버에서 새로 고침 비활성 상태

이 전송 내역 목록에서 주목해야 할 부분은 304 Not Modified 응답이 반환된 내역들입니다. 이렇게 응답 코드 304가 반환된 내역들은 캐시에 저장되어 있던 리소스가 재사용되었음을 의미합니다. 브라우저가 서버에 해당 리소스를 요청했으나 서버는 '변경된 내용이 없으니 그냥 캐시에 저장된 데이터를 사용하라'고 응답한 것입니다. 그러면 브라우저는 이를 인식해서 자체적으로 캐시에 보관해두었던 리소스를 다시 재사용합니다.

노트

전송 내역 목록의 '받은 날짜'라는 컬럼명과 '(시작 캐시)'라는 용어는 각각 'Received''(from cache)'의 오역입니다. 실제로는 '수신'이나 '받음', 그리고 '(캐시로부터 가져옴)' 정도가 적절한 번역일 것입니다. 잘못된 번역이 오히려 사용자를 혼란스럽게 만드는 대표적인 사례로 볼 수 있을 것입니다.

반면 다음은 항상 서버에서 새로 고침 기능을 활성화시키고 메인 페이지를 새로 고침한 후의 전송 내역 목록을 보여줍니다. 이번에는 304 Not Modified 응답을 받은 내역이 한 건도 없음을 확인할 수 있습니다. 즉 모든 리소스를 서버로부터 다시 받아온 것입니다.

F12 개발자 도구 - 네트워크 창 - 항상 서버에서 새로 고침 활성 상태

단순 비교이기는 하지만 위의 두 이미지에서 하단 상태 바에 출력된 요약 정보를 서로 비교해보면, 당연히 캐시에서 리소스를 가져오는 경우의 페이지 로딩 속도가 훨씬 빠르고 전송되는 데이터의 총량도 더 적습니다.

클라이언트로부터 프록시 서버 등을 거쳐서 웹 서버에 이르기까지 다양한 캐시를 적절히 제어하는 일은 생각보다 쉬운 작업이 아닙니다. 감안해야 할 사항도 많고 발생할 수 있는 시나리오도 다양하기 때문입니다. 때로는 개발자가 직접 처리할 수 있는 작업 영역을 넘어서기도 합니다.

범위를 일부 좁혀서 클라이언트 개발자의 입장에서만 생각해본다면 고민해야 할 부분이 조금은 줄어듭니다. 당연한 얘기지만 가장 이상적인 것은 JavaScript 파일이나 CSS 파일, 또는 이미지 등이 변경된 경우에만 서버로부터 새로 리소스를 받아오고, 변경되지 않은 경우에는 브라우저의 캐시를 재사용하는 방식일 것입니다.

만약 ASP.NET Core를 사용하고 있다면 프레임워크가 자체적으로 제공해주는 다음과 같은 몇 가지 태그 도우미(Tag Helper)를 사용하여 아주 간단하게 이 문제를 해결할 수 있습니다.

가령 이번 예제에서 공통 스타일시트 정보를 담고 있는 common.min.css 파일의 내역 경로를 자세히 살펴보면 다음과 같습니다. 키 이름이 v인 쿼리 문자열을 주의해서 살펴보시기 바랍니다.

F12 개발자 도구 - 네트워크 창 - `common.min.css 파일 내역

그리고 다음 코드는 이 파일을 참조하는 ASP.NET Core의 레이아웃 뷰 페이지에 작성된 Link 태그 도우미입니다. asp-append-version 특성의 값이 true로 설정되어 있음을 확인할 수 있습니다.

<link rel="stylesheet" href="~/css/common.min.css" asp-append-version="true" />

ASP.NET Core의 Link 태그 도우미는 이렇게 asp-append-version 특성의 값이 true로 지정되어 있고 href 특정이 지정되어 있는 경우, 내부적으로 대상 리소스의 SHA512 해시값을 계산해서 다음과 같이 HTML의 link 태그를 렌더링해줍니다.

<link href="/css/common.min.css?v=[해시값]" rel="stylesheet" />

그리고 이렇게 쿼리 스트링으로 지정된 해시값은 common.min.css의 내용이 변경되는 경우에만 자동으로 재계산되어 적용됩니다.

따라서 스타일시트 파일의 내용이 변경되면 link 태그에 지정되는 쿼리 스트링의 값이 함께 변경되고, 이 값이 바뀌면 설령 캐시가 만료되지 않았다고 하더라도 기존 파일과는 다른 별개의 파일로 인식되기 때문에 캐시를 무시하고 서버로부터 새로운 리소스를 받아오게 됩니다. 결과적으로 이와 같은 방식으로 태그 도우미를 활용할 경우, 리소스가 변경되면 캐시 만료 여부와 관계 없이 항상 가장 최신의 데이터를 수신할 수 있습니다. 또한 개발자는 한 번 코드를 작성한 이후로는 이 과정 중에 어떠한 신경도 쓸 필요가 없습니다.

캐시 및 쿠키 지우기

경우에 따라서는 여전히 브라우저의 캐시나 쿠키를 지우고 싶은 경우도 물론 있을 수 있습니다. 네트워크 창의 툴 바에서 캐시 지우기 버튼이나 쿠키 지우기 버튼을 클릭하면 인터넷 옵션 메뉴를 열지 않고도 브라우저의 캐시나 쿠키를 지울 수 있습니다. 단 쿠키는 현재 도메인의 쿠키만 지워지므로 참고하시기 바랍니다.

F12 개발자 도구 - 네트워크 창 - 캐시 지우기

F12 개발자 도구 - 네트워크 창 - 쿠키 지우기

탐색 시 항목 지우기

기본적으로 네트워크 창의 전송 내역 목록은 다른 페이지를 탐색할 때마다 모두 지워진 다음 새로 기록됩니다. 그러나 때로는 여러 페이지에 걸친 내역을 검토하고자 하는 경우도 경우도 있습니다. 툴 바에서 탐색 시 항목 지우기 버튼을 클릭해서 이 기능을 토글할 수 있습니다. 이 기능이 비활성된 상태에서는 페이지를 이동하더라도 전송 내역 목록이 그대로 유지된 상태로 새로운 내역이 계속 추가됩니다.

F12 개발자 도구 - 네트워크 창 - 탐색 시 항목 지우기

세션 지우기

툴 바의 세션 지우기 버튼을 클릭하면 모든 전송 내역 목록을 지울 수 있습니다.

F12 개발자 도구 - 네트워크 창 - 세션 지우기

콘텐츠 형식 필터

툴 바의 콘텐츠 형식 필터에서 원하는 형식들을 선택하면 해당 콘텐츠 형식의 내역들만 필터링해서 살펴볼 수 있습니다. 다음은 스크립트 관련 내역들만 나타나도록 필터를 선택한 모습을 보여줍니다.

F12 개발자 도구 - 네트워크 창 - 콘텐츠 형식 필터 적용

전송 내역 목록 살펴보기

지금까지 간단하게 살펴본 것처럼 네트워크 창의 전송 내역 목록만 분석해봐도 다양한 정보들을 파악할 수 있습니다.

전송 내역 목록 중 대부분의 컬럼들은 각각 어떤 정보를 제공하는지 직관적으로 알 수 있지만 일부 컬럼은 조금 주의 깊게 살펴봐야 합니다. 이를테면 타임라인 컬럼이 그 대표적인 예입니다.

DOMContentLoaded 이벤트 및 Load 이벤트

다음은 제 개인 홈페이지 메인 페이지의 전송 내역 목록 중 타임라인 컬럼의 최상단을 보여줍니다. 타임라인 컬럼 위에 빨간색의 마름모가 두 개 찍혀있는 것을 볼 수 있습니다. 이 마름모들은 각각 DOMContentLoaded 이벤트와 Load 이벤트가 발생한 시점을 의미합니다. 이처럼 네트워크 창에서 이 두 가지 이벤트를 특별하게 다루는 이유는 페이지 로딩 시의 성능 조정과 밀접한 관련이 있기 때문입니다.

F12 개발자 도구 - 네트워크 창 - 타임라인 - DOMContentLoaded 이벤트

F12 개발자 도구 - 네트워크 창 - 타임라인 - Load 이벤트

DOMContentLoaded 이벤트는 HTML 페이지가 완전히 로드되고 파싱되어 DOM 트리가 만들어지면 그 즉시 발생합니다. 이때 페이지에서 사용되는 스타일시트나 이미지 등의 로딩이 완료되었는지 여부는 감안되지 않습니다. 따라서 네트워크 속도, 캐시 히트 여부, 개발자의 페이지 작성 패턴 등에 따라서 페이지에서 사용되는 특정 리소스가 이미 로딩되어 있을 수도 있고 아직 로딩되지 않았을 수도 있습니다. 그야말로 어느 정도는 운에 따라 좌우되는 셈입니다. 반면 Load 이벤트는 페이지에서 사용되는 모든 리소스들의 로딩이 완료된 이후에 발생합니다.

따라서 DOM 요소의 정보에만 의존해서 작업을 수행하는 코드는 DOMContentLoaded 이벤트 발생 직후까지 최대한 호출 시점을 끌어당겨 놓을 수 있습니다. 가령 페이지 내부에 존재하는 모든 앵커 태그의 갯수를 가져오는 코드 같은 경우가 이에 해당합니다. 그러나 이미지 같은 다른 리소스에 의해 영향을 받는 코드는 Load 이벤트 발생 시점 이후까지 호출을 미뤄두는 것이 안전합니다. 예를 들어 특정 요소의 너비와 높이를 구하는 코드의 경우, 그 대상이 동적으로 변경되는 이미지라면 Load 이벤트가 발생하기 전까지는 정확한 결과를 얻을 수 있을지 장담할 수 없습니다.

다음은 방금 언급한 사례를 직접 테스트해 볼 수 있는 간단한 예제입니다. 이전 절에서 설명했던 네트워크 창의 항상 서버에서 새로 고침 기능을 활성화시키고 캐시를 지운 상태로 한 번, 그리고 그 상태로 연이어서 페이지를 새로 고침하여 다시 한 번, 총 두 번을 테스트해 보시기 바랍니다. (새 창에서 보기)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>네트워크 - DOMContentLoaded 이벤트와 Load 이벤트</title>
    <style>
      body {
        font-size: 12px;
        font-family: Tahoma;
      }
    </style>
    <script>
      function fnDOMContentLoaded() {
        console.log("== DOMContentLoaded event fired");
        fnGetInfo();
      }

      function fnLoad() {
        console.log("== Load event fired");
        fnGetInfo();
      }

      function fnGetInfo() {
        var aCnt = document.getElementsByTagName("A").length;

        console.log("Number of 'A' tags: %d", aCnt);
        console.log("Image Size: %d, %d \n", image.offsetWidth, image.offsetHeight);
      }

      document.addEventListener("DOMContentLoaded", fnDOMContentLoaded);
      window.addEventListener("load", fnLoad);
    </script>
  </head>
  <body>
    <a href="http://www,egocube.pe.kr">Anchor 1</a><br />
    <a href="http://www,egocube.pe.kr">Anchor 2</a><br />
    <a href="http://www,egocube.pe.kr">Anchor 3</a><br /><br />

    <img id="image" src="http://www.egocube.pe.kr/images/sample/1024x576.jpg" />
  </body>
</html>

다음은 먼저 네트워크 창의 항상 서버에서 새로 고침 기능을 활성화시키고 캐시를 지운 다음 페이지를 로딩하고 살펴본 콘솔 창의 결과입니다. 아마도 이 페이지에 처음 접근하는 사용자들은 이런 결과를 얻게 될 것입니다. 원래 이미지의 크기는 1024 x 576 이지만 DOMContentLoaded 이벤트에서 출력한 값은 엉뚱한 값이 찍힌 것을 확인할 수 있습니다.

F12 개발자 도구 - 콘솔 창 - 최초 로딩 재현

그리고 다음은 페이지를 새로 고침하고 난 다음에 살펴본 콘솔 창의 결과입니다. 이번에는 두 이벤트 모두에서 올바른 이미지의 크기를 출력하고 수 있습니다.

F12 개발자 도구 - 콘솔 창 - 최초 로딩 이후 재로딩 재현

이 시점 정보들은 다음과 같이 전송 내역 목록 하단의 상태 바에서도 동일하게 확인할 수 있습니다. 가끔 타임라인 컬럼 상단에 시점 정보가 표시되지 않을 때가 있는데, 그런 경우에도 상태 바에서는 정상적으로 시점 정보가 제공됩니다.

F12 개발자 도구 - 네트워크 창 - 상태 바 정보

이번 예제의 경우 3.06 초는 프로파일링 세션이 시작된 이후 마지막 리소스가 다운로드 될 때까지 걸린 시간을 의미합니다. 그리고 1.1 초와 1.21 초는 각각 방금 살펴본 DOMContentLoaded 이벤트와 Load 이벤트가 발생한 시점입니다.

지금까지 살펴본 사항들 외에도 DOMContentLoaded 이벤트를 활용하기 위해서는 고려해야 할 점들이 많습니다. 보다 자세한 내용은 다음 문서들을 참고하시기 바랍니다.

번들링 및 축소

타임라인 컬럼의 그래프들을 살펴보다 보면 자연스럽게 한가지 특징을 발견하게 됩니다. 바로 어떤 내역의 그래프들은 페이지 요청과 거의 동시에 전송이 시작되는 반면, 다른 내역의 그래프들은 페이지를 요청한 지 얼마 지나서야 전송이 시작된다는 점입니다. 그리고 사용되는 리소스가 많으면 많을수록 이 패턴이 여러 번 반복됩니다.

F12 개발자 도구 - 네트워크 창 - 타임라인 컬럼의 그래프 흐름

간단히 상식적으로 생각해보면 그래프 자체의 길이는 해당 리소스의 크기나 순간적인 네트워크 상태에 따라서 얼마든지 길어지거나 짧아질 수 있겠지만, 이렇게 리소스마다 요청 시작 시점이 다른 이유는 브라우저 자체에 대한 이해가 부족하면 명확하게 설명하기가 어렵습니다. 결론부터 말해서 이런 형태로 전송이 처리되는 이유는 브라우저마다 동시에 열 수 있는 연결 갯수에 제한이 존재하기 때문입니다. 가령 IE11의 경우 호스트네임 당 13개까지만 연결을 열 수 있으며, 과거 버전에서는 이보다 더 적은 수의 연결만 가능했었습니다. 참고로 다른 최신 브라우저들은 대부분 6개까지만 연결을 열 수 있습니다.

그래프 자체를 분석하는 방법은 나중에 타이밍 탭을 살펴보면서 다시 자세하게 설명하겠지만, 이해를 돕기 위해서 먼저 일부만 살펴보도록 하겠습니다. 다음은 위의 이미지에서 빨간색으로 박스친 부분을 따로 발췌한 것입니다. 이 이미지에서 주의해서 살펴봐야 할 부분은 아래쪽 두 그래프의 회색 영역입니다.

F12 개발자 도구 - 네트워크 창 - 타임라인 컬럼의 그래프 흐름

이 회색 영역은 요청이 지연된, 정체된 시간을 의미합니다. 다시 말해서 사용 가능한 네트워크 연결이 생길때까지 기다린 시간입니다. 페이지의 로딩이 시작된 뒤 요청을 시작하기까지 대기한 시간이 아니라, 요청을 전송하려고 했으나 이미 다른 리소스들을 다운로드 받기 위해서 모든 연결이 사용 중이어서 사용 가능한 연결이 생길때까지 기다린 시간이라는 점에 주의하시기 바랍니다.

당연한 얘기지만 타임라인 컬럼의 그래프들에 이런 회색 영역이 많으면 많을수록 페이지의 로딩 속도는 느려지게 됩니다. 따라서 이런 상태가 발생하는 상황을 최대한 줄여야 하는데, 바로 이런 경우에 유용한 클라이언트 측의 기법이 바로 번들링(Bundling)과 축소(Minification)입니다. 번들링은 여러 개의 파일로 구성된 리소스들의 갯수를 줄임으로써 자연스럽게 페이지 로딩에 필요한 네트워크 연결의 갯수를 줄여줍니다. 그리고 축소는 리소스의 데이터 크기 자체를 줄여줌으로서 전체 전송량을 감소시켜줍니다.

ASP.NET 및 ASP.NET Core 환경 기반의 번들링 및 축소에 대한 보다 자세한 내용은 다음 문서들을 참고하시기 바랍니다. 참고로 이 문서에는 다른 언어 사용자분도 참고하면 좋을만한 내용도 많이 담겨 있습니다.

그리고 각각의 그래프 위에 마우스를 올리면 다음과 같이 보다 자세한 정보를 보여주는 팝업이 나타납니다. 이 팝업의 내용은 나중에 살펴볼 타이밍 탭의 정보와 동일한 내용을 담고 있으며, 이 이미지들은 대략적인 유형을 확인할 수 있도록 대조적인 두 가지 다른 사례를 캡처한 것입니다.

F12 개발자 도구 - 네트워크 창 - 타이밍 팝업 정보

F12 개발자 도구 - 네트워크 창 - 타이밍 팝업 정보

이미지의 데이터 URIs 얻기

네트워크 창의 본래 용도는 아니지만 이미지 전송 내역의 응답 페이로드를 복사하면 손쉽게 데이터 URIs를 얻을 수 있습니다. 일반적으로 img 태그를 이용해서 페이지에 이미지를 출력하려면 다음과 같이 태그를 작성하게 됩니다.

<img src="http://www.egocube.pe.kr/images/button/sbtnRSS.png" />

그러나 이런 방식 대신 다음과 같이 데이터 URIs 스킴을 사용할 수도 있습니다.

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwQAADsEBuJFr7QAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTFH80I3AAABgElEQVQ4T5WSaU8CQQyG/f8/hdMgBIJRITHGuMu5uIDKIShyiOgS2XbnsjMLYTF80Em/dPo+077NnARW7F9hgGoa6xmwU2jHo7WjoQEc3CkOkm24NwsmDraKaCeiomiEgK2iRzLhTaFbPtrQAK0CGzf4ciR8j+Q7jLPZI1RSUTVFaDpOj6EV8ytpaF/x5VgJvoVWY6ie/gbw6Vqs52zRw/6tX8sg8Z2S9D8No9i8BxFLBhhWwhodso6jGpn2G1mxWZk7gQPrEOiW+XquOJqyPuK9j3YSnbxiPqUSvqCW2QMUYMWhnoVhVQabkGFjh2aD57rJZDCqHgC6ZifINzazcvOhNRywmYNKWgKtTsnvZejEjGQn+UtLrhc4tDTZKSkpSBRMH/RzE1fzIqAJt0DgFmmB+pYD1M/IsfBmlElcAznplnSJ1tG72XVo5rbmSGG2zl7vQ4021swrwShjo9quAzHuBdlCpxCmgXsu3tpi4tKnpK8pJg6fdljncg/8NazYD3y2nPvxBdtcAAAAAElFTkSuQmCC" />

때에 따라서는 후자의 방식이 매우 유용한데, 가령 스타일시트 파일 자체에 이미지를 포함시켜서 배포하기 위한 용도로도 사용할 수도 있고, 데이터베이스 테이블의 CLOB, TEXT, 또는 VARCHAR(MAX) 형식의 컬럼에 이미지 데이터 자체를 저장해 놓는 용도로 사용할 수도 있기 때문입니다.

다만 개발자의 입장에서 한가지 번거로운 점은 별다른 유틸리티가 없을 경우, 프로그램을 작성한다던지 해서 직접 BASE64 형태의 데이터를 뽑아내야 한다는 것입니다. 그러나 네트워크 창의 기능을 이용하면 간단하게 데이터 URIs을 얻을 수 있습니다. 다음과 같이 이미지 전송 내역을 마우스 오른쪽 버튼으로 클릭한 다음, 응답 페이로드 복사를 선택합니다. 그러면 클립보드에 data:[<media type>][;base64],<data> 형태의 데이터 URIs 정보가 복사됩니다.

F12 개발자 도구 - 네트워크 창 - 응답 페이로드 복사

정리

본문에서는 F12 개발자 도구의 네트워크 창을 이용해서 브라우저와 서버 간에 전송되는 통신을 모니터링 하는 기본적인 방법과, 전송 내역 목록을 이해하기 위한 몇 가지 정보를 살펴봤습니다.

이어지는 글에서는 네트워크 창의 상세 탭들을 이용해서 전송 내역을 보다 상세하게 살펴보는 방법을 알아보도록 하겠습니다.