본문으로 건너뛰기

02 페이지 속도의 원리

여기서는 다음의 항목을 최적화하는 데 집중할 것이다.

  • 페이지에서 로딩하는 자원의 수(이미지나 글꼴, HTML, CSS 등)
  • 로딩한 자원 파일의 크기
  • 사용자가 느끼는 사이트의 체감 성능

프론트엔드의 페이지 로딩 시간을 개선하는 데 집중할 것이다.

브라우저가 콘텐츠를 렌더링하는 방법

먼저 브라우저가 데이터를 얻기 위해 서버에 요청을 보낸다. 이렇게 브라우저가 새로운 도메인에 요청을 보내려면 콘텐츠가 있는 서버를 먼저 찾아야 하는데 이 과정을 DNS 조회라 한다. DNS 조회를 통해 웹 호스팅이 인터넷의 어디에서 이루어지는지 검색한 후 검색된 서버로 사용자가 보낸 콘텐츠 요청이 도달한다. 브라우저는 일정 기간동안 이 위치를 기억하므로 매 요청마다 DNS 조회를 하는 시간 낭비가 생기지는 않는다.

서버가 사용자의 브라우저로부터 첫 요청을 받으면 서버는 이 요청을 확인한 후 페이지를 렌더링하기 위해 브라우저가 찾는 콘텐츠의 위치를 확인한다. 그 다음 서버는 이미지나 CSS, HTML 혹은 또 다른 종류의 콘텐츠를 브라우저의 요청에 대한 결과로 반환한다. 브라우저는 서버가 반환한 자원을 다운받은 후 사용자를 위해 화면에 렌더링한다.

브라우저가 서버로부터 받은 콘텐츠의 첫 번째 바이트 도착 시간을 TTFB(Time to First Byte)라 한다. 프론트엔드에서 페이지의 콘텐츠를 모두 다운받은 후 렌더링을 해야 하는데 여기서 시간이 추가로 걸린다. 게다가 어떤 파일들은 브라우저가 쉽게 처리한 후 렌더링까지 할 수도 있지만, 블로킹-자바스크립트처럼 사용자의 브라우저가 추가적인 콘텐츠를 렌더링하기 전까지는 처리할 수 없는 것도 있다.

브라우저는 보통 웹 페이지를 렌더링하는 시간을 줄이기 위해 서버에 보내는 콘텐츠 요청을 병렬로 처리하려고 한다.

요청

웹 페이지 구성에 필요한 콘텐츠를 요청할 때 크기와 횟수를 최적화하면 사이트의 페이지 로딩 시간이 엄청나게 달라질 것이다.

요청하는 콘텐츠 조각의 크기가 커지면 다운받는 시간과 브라우저에서 처리하는 시간, 그리고 페이지에서 보여주는 시간도 당연히 길어진다. 또한 페이지를 렌더링하는 데 필요한 콘텐츠 중 독립적인 조각이 많다면 페이지를 완전히 로딩하는 데 더 많은 시간이 걸린다. 그러므로 사이트를 로딩하는 시간을 줄이려면 화면을 그리는 데 필요한 이미지, CSS, 자바스크립트 파일 등의 개수뿐 아니라 크기까지 줄여야 한다.

이미지 작업을 예로 들어보자. 각각의 이미지 요청을 하나의 스프라이트(쉽게 말해 이미지의 집합)로 만들면 브라우저가 보내는 요청 횟수를 줄일 수 있다. 또한 이미지의 품질을 손상시키지 않고 파일의 크기만 줄이는 압축 도구를 사용할 수도 있다. 체감 성능을 향상시키기 위해 CSS 파일 및 자바스크립트의 파일 수를 줄이고 최적의 순서로 로딩하는 방법도 고려할 수 있다.

연결

페이지를 로딩하는 데 필요한 요청의 수와 브라우저가 콘텐츠를 가져오기 위해 만드는 연결의 수는 서로 다를 수 있다. 브라우저가 서버와의 연결을 유지하고 다른 자원 요청을 위해 연결을 재사용하는 것을 지속 연결이라고 부른다. 서버로부터 더 많은 콘텐츠를 가져오기 위해 새로운 연결이 필요하다고 판단되기 전까지 브라우저가 자바스크립트를 요청하기 위해 만든 연결을 이용해 추가적으로 글꼴이나 이미지를 가져오고 있다.

브라우저는 콘텐츠를 동시에 가져오기 위해 연결을 여러 개 만들기도 한다. 동시에 만들 수 있는 지속 연결의 수는 브라우저마다 다른데, 최근 브라우저들을 살펴보면 최대 6개(크롬, 파이어폭스, 오페라12)에서 8개(IE 10, 11)의 동시 연결을 허용한다.

또 페이지를 로딩하는 데 얼마나 많은 연결이 사용 중인지 확인하는 것도 중요하다. 연결이 많다면 페이지에 필요한 콘텐츠를 여러 개의 다른 도메인을 통해 받아오는 것일 수 있으며, 이는 브라우저가 연결을 최적화하는 데 방해가 된다. 일반적으로 서드파티의 스크립트를 많이 쓰는 경우 이런 증상이 생긴다.

페이지 크기

페이지 로딩에 필요한 HTML이나 이미지, 그 밖에 다른 콘텐츠 모두 총 페이지 로딩 시간에 영향을 준다. HTML, 자바스크립트 및 CSS 파일에 gzip을 적용하면 크기가 줄어드는 것을 볼 수 있다.

체감 성능

사이트의 속도는 실제 로딩 시간보다 사용자가 어떻게 느끼느냐가 더 중요하다. 사용자들은 페이지가 얼마나 빨리 보이는지, 페이지가 얼마나 빨리 반응하는지, 사이트가 얼마나 부드럽게 스크롤되는지를 통해 사이트의 속도를 인식하기 때문이다.

중요 렌더링 경로

페이지를 불러 올 때 브라우저는 문서 객체 모델이라 불리는 DOM을 만드는 것부터 시작한다. 사용자의 브라우저는 웹 서버에서 HTML을 받아 파싱한다. 이 과정은 바이트를 문자로, 문자열을 <body>와 같은 토큰으로, 토큰을 프로퍼티와 규칙을 가진 객체로 만들고 최종적으로 이 객체들을 서로 연겨라면서 데이터 구조를 만드는 순서로 진행된다. 이를 통해 DOM 트리가 만들어진다.

브라우저가 HTML을 파싱하는 과정에서 스타일시트를 만나면 브라우저는 모든 작업을 일시 중지하고 서버에 파일을 요청한다. 브라우저가 파일을 받으면 앞에서 한 작업과 유사한 작업을 반복한다. 이를통해 CSS의 객체 모델인 CSSOM이 생성된다.

다음으로 브라우저는 DOM과 CSSOM을 결합해 화면에 보이는 모든 요소의 위치와 크기를 계산하는 데 필요한 렌더링 트리를 만든다. 렌더링 트리는 페이지를 표시하는 데 필요한 정보만 가지고 있다.(그러므로 display

으로 선언된 것은 렌더링 트리에 포함되지 않는다.) 마지막으로 브라우저가 최종적으로 만든 렌더링 트리를 이용해 화면을 표시한다.

지금까지 설명한 전체 과정은 브라우저가 사용자에게 콘텐츠를 표시하기 위해 거치는 중요 렌더링 경로를 보여준다.

다음의 중요 렌더링 경로 최적화 기법들은 상호작용 시간 개선에도 효과가 있다.

  • 비동기 방식으로 콘텐츠 가져오기
  • 화면에 보이는 부분의 콘텐츠를 먼저 표시하도록 우선순위 높이기
  • CSS와 자바스크립트 로딩 모범 사례 따르기
  • 재방문 사용자를 고려하며 자원 캐싱하기
  • 사용자가 페이지의 주요 기능을 최대한 빨리 사용할 수 있도록 보장하기

쟁크

웹 페이지를 스크롤할 때 화면이 버벅거리거나 건너 뛰는 형상을 쟁크(Jank)라 부르는데, 브라우저가 초당 60프레임 이하로 렌더링할 때 발생한다. 이 버벅거림은 사용자 경험에도 좋지 않고 사이트 성능에 대한 사용자의 인식에도 부정적인 영향을 미친다.

보통 버벅거리는 현상은 브라우저가 페이지의 변경사항을 화면에 표현하는 과정에서 발생한다. 브라우저가 페이지의 변경사항을 화면에 표현하는 과정에서 발생한다. 브라우저는 배경이나 색상, 테두리 굴림, 그림자 같은 요소의 시각적 속성이 변경되면 이를 화면에 새로 그린다. 또한 사용자가 페이지에 포함된 요소의 시각적 속성에 영향을 미치는 행동을 할 때에도 브라우저는 화면을 새로 그린다.

페이지 속도에 영향을 미치는 다른 요소

페이지 속도에 영향을 미치는 요소에는 우리가 제어할 수 있는 성능적인 요인 외에 사용자의 지리적 위치나 네트워크, 브라우저 같은 환경적 요인들도 있다.

지리

사용자의 지리적 위치는 사이트의 로딩 시간에 크게 영향을 줄 수 있다. 이런 이유로 전세계 사용자를 고객으로 삼는 사이트들이 CDN(Content Delivery Networks)을 사용한다. CDN은 전세계에 데이터를 미리 복사한 서버를 준비하여 사용자가 거리상 가장 가까운 서버에 접근하도록 하는 방식으로 시간을 절악한다.

네트워크

사용자의 거주 지역에 따라 대역폭 자체의 제한이나 주어진 기간에 소비할 수 있는 대역폭의 약에 제한이 있을 수 있다.

브라우저

각 브라우저마다 콘텐츠 요청과 렌더링을 약간씩 다르게 처리하기 때문에 사용자가 사용하는 브라우저 또한 사이트의 체감 성능에 영향을 줄 수 있다. 동시 연결 수를 적게 지원하는 브라우저는 더 많이 지원하는 브라우저보다 요청과 렌더링을 처리하는 데 시간이 더 걸릴 것이다.