네비게이션 타이밍을 이용한 페이지 로딩 속도 측정하기

HTML5 Rocks

Navigation Timing으로 페이지 로딩 속도 측정하기

사람들은 빨리 뜨는 웹페이지를 좋아한다. 구글은 실험을 통해 백 밀리 초 정도의 작은 지연도 부정적인 영향을 끼칠 수 있다는 점을 보여주었다. 하지만 웹페이지의 로딩 속도는 어떻게 측정해야 하는가? 그리고 여기서 얘기하는 "페이지 로딩"의 의미는 정확히 무엇인가?

Navigation Timing은 웹의 성능을 정확하게 측정하는 자바스크립트 API이다. Navigation Timing API는 페이지 탐색과 로드 이벤트와 관련한 정확한 타이밍을 자세하게 얻을 방법을 제공한다. 현재 이 API는 Internet Explorer 9, Google Chrome, Firefox에서 사용할 수 있다.

이 글에서는 이 API를 사용해서 타이밍 데이터를 사용하는 방법을 설명한다.

어떻게 사용하는가?

Navigation Timing API는 window.performance 객체의 프로퍼티로 접근한다.

  • navigation: 사용자가 어떻게 페이지를 탐색했는가
  • timing: 탐색과 페이지 로드 이벤트에 관한 데이터.

크롬은 자바스크립트 메모리 사용에 대한 데이터를 볼 수 있는 perfomance.memory 프로퍼티도 제공한다.

이 API를 사용해보는 가장 쉬운 방법은 브라우저의 자바스크립트 콘솔에서 window.performance를 살펴보는 것이다.

구글 크롬에서 아무 페이지나 열고

  1. 크롬창에서 오른쪽 위의 "크롬 맞춤설정 및 제어" 메뉴에서 도구 > 자바스크립트 콘솔을 선택한다.(아니면 윈도우나 리눅스에서는 Ctrl-Shift-J로 맥에서는 Command-Option-J로 접근할 수 있다.)
  2. 창 하단의 > 프롬프트에 performance라고 입력하고 엔터를 누른다.
  3. 객체의 프로퍼티(memory, navigation, timing)를 보려면 Performance를 클릭한다.
  4. 세부 속성을 보려면 timing 왼쪽의 화살표를 클릭한다.

다음과 같은 내용을 볼 수 있을 것이다. 이 부분은 이 페이지에서 동적으로 생성한 것이다.

이 부분은 현재 브라우저에서는 지원하지 않는다.

Internet Explorer에서 이 API를 사용해보려면 먼저 브라우저가 올바른 모드로 동작하는지 확인해 봐라.

  • 웹페이지의 문서가 표준 모드로 보이도록 <!doctype html> 디렉티브를 사용해라.
  • 개발자 도구 콘솔에서 브라우저나 문서 모드를 조정해야 할 수도 있다.

자바스크립트 Date보다 더 좋은 방법

예전에는 웹 개발자가 타이밍 매트릭스를 구하려고 자바스크립트 Date 객체를 사용했다. 다음과 같은 코드를 웹페이지 최상단에 두고 간단한 속도 측정을 했을 것이다.

var start = Date.now();

그리고 페이지 하단에는 다음과 같은 코드를 둔다.

console.log("Page load took " + (Date.now() - start) + "milliseconds");

이런 식으로 인라인 자바스크립트를 사용해서 측정한 성능은 다음과 같은 이유로 한계가 있고 신뢰할만하지도 않다.

  • 타이밍관련 코드가 페이지에 있으므로 이 코드가 페이지 로딩에 영향을 주고 시간을 잡아먹는다. (Navigation Timing API는 페이지 로딩 과정에는 영향을 전혀 주지 않고 페이지 로딩이 완료된 후에 타이밍 데이터를 사용할 수 있다.)
  • JavaScript time is not accurate.
  • 자바스크립트의 시간은 정확하지 않다.
  • 페이지에 타이밍을 측정하는 코드를 두어도 좋은 상황이 아니라면 사용자가 경험하는 페이지 로딩 속도를 측정할 수 없다.
  • 가장 최악인 것은 Date 객체로는 페이지 로딩을 시작하기 전의 네트워크 지연을 측정할 수 없다는 부분이다.

즉, 페이지에 인라인 코드를 사용하는 방법은 사용자가 "페이지를 열었을 때"(링크를 클릭하거나 브라우저의 주소창에 URL을 입력하던가) 경험하는 전체 지연시간을 측정할 수 없다. 왜냐하면, 페이지 콘텐츠(자바스크립트 타이밍 코드가 포함된)를 로드하기 전에 일어나는 DNS 처리 과정이나 리다이렉트, 서버 응답 같은 과정이 지연시간에 포함되기 때문이다. 하나의 페이지가 언로드되고 다음 페이지가 로드되는 사이의 시간을 측정하려고 쿠키를 사용할 수도 있지만 쿠키는 두 페이지가 같은 호스트일 때만 사용할 수 있다. 쿠키를 이용한 방법은 사용자가 웹사이트에서 가장 먼저 접속하는 페이지(아마 가장 중요하게 성능을 측정해야 할)에서는 동작하지 않고 네트워크 지연에 대한 전체 수치만 알 수 있고 다양한 종류의 지연에 대한 정보를 얻으려면 데이터를 깨뜨릴 수밖에 없다.

이 값은 모두 무엇을 의미하는가?

각 performance.timing 속성은 탐색(navigation) 이벤트(페이지를 요청한 경우 등)의 시간이나 페이지 로드 이벤트(DOM 로딩이 시작된 경우 등)의 시간을 UTC로 1970년 1월 1일 자정부터 측정한 밀리 초 단위로 보여준다. 값이 0이면 해당 이벤트(secureConnectionStartredirectStart같은)가 발생하지 않았다는 것을 의미한다.

각 이벤트는 Microsoft의 performance.timing 문서나 좀 더 공식적인 W3C 권고안에 의미가 설명되어 있다. Internet Explorer 9는 secureConnectionStart를 제외하고 API 드래프트 문서에 나온 모든 속성을 지원하고 추가로 loadEventEnd 이후 문서가 표시되기 시작할 때 발생하는 msFirstPaint 이벤트를 제공한다.

performance.timing 이벤트의 순서는 Navigation Timing 권고안에서 가져온 아래 그림에 나와 있다.

현재 페이지를 탐색하고 콘텐츠를 로딩할 때 발생한 모든 performance.timing 이벤트의 시간을 0부터 시작하게 조정해서 동적으로 만든 타임라인이 아래에 나와 있다.

정확한 이벤트 시간을 보려면 각 아이템에 커서를 올리면 된다.

이 부분은 현재 브라우저에서는 지원하지 않는다.

이 경우 타임라인을 렌더링 할 때 페이지가 계속 로딩중이므로 loadEventEnd 이벤트는 발생하지 않았다.

loadEventEnd를 보고 싶다면 다음 예제처럼 load 이벤트가 종료된 뒤에 값을 가져오면 된다.

window.onload = function(){
  setTimeout(function(){
    var t = performance.timing;
    console.log(t.loadEventEnd - t.responseEnd);
  }, 0);
}

활용 방법

이 API의 데이터는 여러 이벤트를 조합해서 사용해야 실제적인 의미를 가진다.

  • 네트워크 지연시간 (): responseEnd-fetchStart
  • 서버에서 페이지를 받고 페이지를 로드하는데 걸린 시간: loadEventEnd-responseEnd
  • 탐색과 페이지 로드의 전체 과정: loadEventEnd-navigationStart.

특정 문제를 정확히 짚어내기 위해 이러한 방법으로 데이터를 조합할 수도 있다. 예를 들어 redirectEnd-redirectStart로 리다이렉트에 걸린 시간을 측정할 수 있다.

물론 "페이지를 여는" 여러 가지 방법이 있는데 여기서 performance.navigation가 쓸모 있는데 이 API는 딱 두 개의 속성을 가진다.

  • redirectCount: 문서 요청이 리다이렉트된 횟수
  • type: 페이지를 로딩한 탐색의 종류

위에서 type은 다음 세 값 중 하나다.

  • 0: 링크를 클릭하거나 브라우저 주소창에 URL을 입력하는 등 사용자가 액션을 수행한 경우
  • 1: 페이지를 리로딩한 경우
  • 2: 히스토리 뒤로 가기나 앞으로 가기로 탐색한 경우

아래는 당신이 이 페이지에 접근한 방법이다.

이 부분은 현재 브라우저에서는 지원하지 않는다.

현실에서

Date 객체를 사용해서 타이밍을 측정하는 방법과는 달리 Navigation Timing API는 페이지 로딩에 전혀 영향을 주지 않고 사용할 수 있다. 그러므로 사내 네트워크에서 개발용 컴퓨터를 사용해서 개발자가 직접 테스트하는 대신 실제 사용자가 겪는 "현실"의 페이지 로딩 지연시간을 측정하는 데 유용하게 사용할 수 있다.

예를 들면 페이지를 로딩(언로딩도 마찬가지)할 때마다 XHR로 호스트 서버에 performance.timing 데이터를 보낼 수 있다. 이 방법으로 실시간 통계를 구할 수는 있지만, 효율적인 방법은 아니므로 페이지별, 사용자별로 로컬 스토리지에 타이밍 데이터를 기록해두고 정기적으로 서버에 보낼 수도 있다. Navigation Timing API는 페이지 성능에 대해 시간에 따른 데이터를 구성할 수 있는 간단한 방법을 제공한다.

Navigation Timing의 미래

Navigation Timing은 개발자가 성능을 이해하고 최적화하도록 유용한 도구를 제공하지만 가장 유용한 경우는 웹 통계에서 사용하는 것이며 풍부하고 정확한 데이터로 비침투적인 정보를 제공할 수 있다.

더 나은 정보는 페이지 로드 지연을 이해하는 데 유용하고 이로써 더 효율적인 웹사이트와 인프라, 더 빠른 웹 애플리케이션과 웹을 만들 수 있고 좋은 사용자 경험을 제공할 수 있다.

API를 사용하는 방법을 잘 이해하고 싶다면 구글 크롬의 Page Speed Test 확장을 사용해 봐라.(이 글의 작성자가 개발했다.) Page Speed Test의 차트는 어떤 페이지에서든 방문했을 때의 탐색과 페이지 로딩의 성능을 보여준다.


부록

2012.03.01: Kasia는 데이터를 화려하게 볼 수 있는 북마클릿을 작성했다.

Comments

0