첫 바이트까지의 시간 최적화

Time to First Byte(첫 바이트까지의 시간) 측정항목을 최적화하는 방법을 알아봅니다.

첫 바이트까지의 시간 (TTFB)콘텐츠가 포함된 첫 페인트 (FCP)최대 콘텐츠 페인트 (LCP)와 같은 다른 모든 의미 있는 사용자 환경 측정항목보다 앞서는 기본 웹 성능 측정항목입니다. 즉, TTFB 값이 높으면 다음에 오는 측정항목에 시간이 추가됩니다.

사용자의 75번째 백분위수'양호' 기준점 이내에서 FCP를 경험할 수 있도록 서버가 탐색 요청에 충분히 빠르게 응답하는 것이 좋습니다. 대략적으로 대부분의 사이트는 TTFB가 0.8초 이하가 되도록 노력해야 합니다.

양호한 TTFB 값은 0.8초 이하이고, 낮은 값은 1.8초보다 크며, 그 사이의 모든 값은 개선이 필요합니다.

TTFB 측정 방법

TTFB를 최적화하려면 먼저 TTFB가 웹사이트 사용자에게 미치는 영향을 관찰해야 합니다. 리디렉션의 영향을 받는 TTFB를 관찰하는 기본 소스로 필드 데이터를 활용해야 하지만, 실험실 기반 도구는 종종 최종 URL을 사용하여 측정되므로 이러한 추가 지연이 누락됩니다.

PageSpeed InsightsChrome 사용자 환경 보고서에서 제공되는 공개 웹사이트에 대한 필드 및 실험실 정보를 모두 얻는 한 가지 방법입니다.

실제 사용자의 TTFB는 상단의 실제 사용자가 경험하는 문제 알아보기 섹션에 표시됩니다.

TTFB 측정항목의 필드 데이터를 포함한 PageSpeed Insights 실제 사용자 데이터

TTFB의 하위 집합은 서버 응답 시간 감사에 표시됩니다.

서버 응답 시간 감사

현장과 실험실에서 TTFB를 측정하는 더 많은 방법을 알아보려면 TTFB 측정항목 페이지를 참고하세요.

Server-Timing를 사용하여 필드에서 높은 TTFB 디버그

Server-Timing 응답 헤더는 애플리케이션 백엔드에서 긴 지연 시간에 영향을 미칠 수 있는 고유한 백엔드 프로세스를 측정하는 데 사용할 수 있습니다. 헤더 값의 구조는 유연하며, 최소한 개발자가 정의한 핸들을 허용합니다. 선택적 값에는 기간 값 (dur를 통해)과 인간이 읽을 수 있는 설명 (desc를 통해)이 선택적으로 포함됩니다.

Serving-Timing는 여러 애플리케이션 백엔드 프로세스를 측정하는 데 사용할 수 있지만 다음과 같은 몇 가지 사항에 특히 주의해야 합니다.

  • 데이터베이스 쿼리
  • 서버 측 렌더링 시간(해당하는 경우)
  • 디스크 탐색
  • 에지 서버 캐시 적중/누락 (CDN을 사용하는 경우)

Server-Timing 항목의 모든 부분은 콜론으로 구분되며 여러 항목은 쉼표로 구분할 수 있습니다.

// Two metrics with descriptions and values
Server-Timing: db;desc="Database";dur=121.3, ssr;desc="Server-side Rendering";dur=212.2

헤더는 애플리케이션 백엔드에서 선택한 언어를 사용하여 설정할 수 있습니다. 예를 들어 PHP에서는 다음과 같이 헤더를 설정할 수 있습니다.

<?php
// Get a high-resolution timestamp before
// the database query is performed:
$dbReadStartTime = hrtime(true);

// Perform a database query and get results...
// ...

// Get a high-resolution timestamp after
// the database query is performed:
$dbReadEndTime = hrtime(true);

// Get the total time, converting nanoseconds to
// milliseconds (or whatever granularity you need):
$dbReadTotalTime = ($dbReadEndTime - $dbReadStarTime) / 1e+6;

// Set the Server-Timing header:
header('Server-Timing: db;desc="Database";dur=' . $dbReadTotalTime);
?>

이 헤더가 설정되면 실습필드에서 모두 사용할 수 있는 정보가 표시됩니다.

필드에서 Server-Timing 응답 헤더가 설정된 페이지는 Navigation Timing APIserverTiming 속성을 채웁니다.

// Get the serverTiming entry for the first navigation request:
performance.getEntries('navigation')[0].serverTiming.forEach(entry => {
  // Log the server timing data:
  console.log(entry.name, entry.description, entry.duration);
});

실습에서 Server-Timing 응답 헤더의 데이터는 Chrome DevTools의 Network 탭에 있는 타이밍 패널에 시각화됩니다.

Chrome DevTools의 네트워크 탭에 있는 Server-Timing 헤더 값을 시각화한 그림입니다. 이 이미지에서 Server-Timing 헤더 값은 CDN 에지 서버에서 캐시 적중 또는 부적중이 발생했는지 여부와 에지 및 원본 서버에서 리소스를 검색하는 데 걸리는 시간을 측정합니다.

Chrome DevTools의 네트워크 탭에 시각화된 Server-Timing 응답 헤더 여기서 Server-Timing는 리소스 요청이 CDN 캐시에 도달했는지, 요청이 CDN의 에지 서버에 도달한 후 원본에 도달하는 데 걸리는 시간을 측정하는 데 사용됩니다.

사용 가능한 데이터를 분석하여 TTFB에 문제가 있음을 확인했으면 문제 해결 단계로 넘어갈 수 있습니다.

TTFB 최적화 방법

TTFB 최적화에서 가장 어려운 점은 웹의 프런트엔드 스택은 항상 HTML, CSS, JavaScript이지만 백엔드 스택은 크게 다를 수 있다는 점입니다. 수많은 백엔드 스택과 데이터베이스 제품이 있으며, 각 제품에는 고유한 최적화 기법이 있습니다. 따라서 이 가이드에서는 스택 관련 지침만 중점적으로 살펴보기보다는 대부분의 아키텍처에 적용되는 사항을 중점적으로 다룹니다.

플랫폼별 안내

웹사이트에서 사용하는 플랫폼에 따라 TTFB가 크게 달라질 수 있습니다. 예를 들어 WordPress 성능은 플러그인의 수와 품질 또는 사용되는 테마의 영향을 받습니다. 플랫폼이 맞춤설정될 때 다른 플랫폼도 마찬가지로 영향을 받습니다. 이 게시물의 보다 일반적인 성능 조언을 보완할 수 있는 공급업체별 조언은 플랫폼 문서를 참조하세요. 서버 응답 시간을 줄이기 위한 Lighthouse 감사에는 제한된 스택별 지침도 포함되어 있습니다.

호스팅, 호스팅, 호스팅

다른 최적화 방법을 고려하기 전에 먼저 호스팅을 먼저 고려해야 합니다. 여기에서 제공할 수 있는 구체적인 지침이 많지는 않지만 일반적으로 웹사이트의 호스트가 웹사이트에 전송하는 트래픽을 처리할 수 있는지 확인하는 것이 좋습니다.

공유 호스팅은 일반적으로 속도가 느립니다. 주로 정적 파일을 제공하는 소규모 개인 웹사이트를 운영하는 경우 이 방법이 괜찮을 수 있으며, 이어지는 최적화 기법은 TTFB를 최대한 줄이는 데 도움이 될 것입니다.

그러나 맞춤설정, 데이터베이스 쿼리 및 기타 집중적인 서버 측 작업과 관련된 사용자가 많은 대규모 애플리케이션을 실행하는 경우 호스팅 선택은 현장에서 TTFB를 낮추는 데 매우 중요합니다.

호스팅 제공업체를 선택할 때 다음 사항을 고려하세요.

  • 애플리케이션 인스턴스에 할당된 메모리 양은 얼마나 되나요? 애플리케이션의 메모리가 부족하면 애플리케이션이 최대한 빠르게 페이지를 제공하기 어렵게 됩니다.
  • 호스팅 업체에서 백엔드 스택을 최신 상태로 유지하나요? 새로운 버전의 애플리케이션 백엔드 언어, HTTP 구현, 데이터베이스 소프트웨어가 출시됨에 따라 시간이 지남에 따라 해당 소프트웨어의 성능이 개선될 것입니다. 이러한 유형의 중요 유지관리를 우선시하는 호스팅 업체와 협력하는 것이 중요합니다.
  • 매우 구체적인 애플리케이션 요구사항이 있고 서버 구성 파일에 최저 수준의 액세스를 원하는 경우, 자체 애플리케이션 인스턴스의 백엔드를 맞춤설정하는 것이 적절한지 문의하세요.

이러한 사항을 처리해 주는 호스팅 업체가 많지만 전용 호스팅 제공업체에서도 긴 TTFB 값이 관찰되기 시작하면 최상의 사용자 환경을 제공하기 위해 현재 호스팅 업체의 기능을 재평가해야 할 수도 있습니다.

콘텐츠 전송 네트워크 (CDN) 사용

CDN 사용이라는 주제는 타당한 주제이지만 타당한 이유가 있습니다. 매우 잘 최적화된 애플리케이션 백엔드를 사용할 수 있지만 원본 서버에서 멀리 떨어진 사용자는 필드에서 여전히 높은 TTFB를 경험할 수 있습니다.

CDN은 물리적으로 사용자에게 가까운 서버에서 리소스를 캐시하는 분산 서버 네트워크를 사용하여 원본 서버에서 사용자 근접성 문제를 해결합니다. 이러한 서버를 에지 서버라고 합니다.

CDN 제공업체는 에지 서버 외의 이점도 제공할 수 있습니다.

  • CDN 제공업체는 일반적으로 매우 빠른 DNS 확인 시간을 제공합니다.
  • CDN은 HTTP/2 또는 HTTP/3와 같은 최신 프로토콜을 사용하여 에지 서버에서 콘텐츠를 제공할 가능성이 높습니다.
  • 특히 HTTP/3는 UDP 프로토콜을 사용하여 TCP (HTTP/2에서 사용하는)에 있는 H라인 차단 문제를 해결합니다.
  • CDN은 또한 최신 버전의 TLS를 제공하여 TLS 협상 시간과 관련된 지연 시간을 단축합니다. 특히 TLS 1.3은 TLS 협상을 가능한 한 짧게 유지하도록 설계되었습니다.
  • 일부 CDN 제공업체는 Service Worker API와 유사한 API를 사용하여 요청을 가로채거나 에지 캐시에서 프로그래매틱 방식으로 응답을 관리하거나 응답을 모두 재작성하는 '에지 작업자'라고 하는 기능을 제공합니다.
  • CDN 제공업체는 압축 최적화에 매우 능숙합니다. 압축은 자체적으로 올바르게 하기 어려우며, 동적으로 생성된 마크업을 사용하는 경우 즉석에서 압축해야 하는 특정한 경우에는 응답 시간이 느려질 수 있습니다.
  • 또한 CDN 제공업체는 정적 리소스의 압축된 응답을 자동으로 캐시하여 압축 비율과 응답 시간의 조합을 최적화합니다.

CDN을 채택하는 데는 사소한 것에서 중대한 것까지 다양한 노력이 필요하지만, 웹사이트에서 아직 TTFB를 사용하지 않는 경우에는 TTFB를 최적화하는 것을 우선시해야 합니다.

가능한 경우 캐시된 콘텐츠 사용

CDN을 사용하면 방문자가 물리적으로 가까운 곳에 위치한 에지 서버에 콘텐츠를 캐시할 수 있습니다. 단, 콘텐츠가 적절한 Cache-Control HTTP 헤더로 구성되어야 합니다. 이는 맞춤형 콘텐츠에는 적합하지 않지만, 원본까지 거슬러 올라가야 한다면 CDN의 많은 가치를 무효화할 수 있습니다.

콘텐츠를 자주 업데이트하는 사이트의 경우 캐싱 시간이 짧아도 사용량이 많은 사이트의 성능이 눈에 띄게 향상될 수 있습니다. 첫 번째 방문자만 원본 서버로의 전체 지연 시간을 경험하고 다른 모든 방문자는 에지 서버에서 캐시된 리소스를 재사용할 수 있기 때문입니다. 일부 CDN에서는 사이트 릴리스에서 캐시 무효화를 허용하여 캐시 시간이 길지만 필요한 경우 즉시 업데이트를 제공합니다.

캐싱이 올바르게 구성된 경우에도 애널리틱스 측정에 고유한 쿼리 문자열 매개변수를 사용하면 이를 무시할 수 있습니다. 이러한 항목은 동일하더라도 CDN과 다른 콘텐츠로 보일 수 있으므로 캐시된 버전이 사용되지 않습니다.

또한 오래되거나 방문 횟수가 적은 콘텐츠는 캐시되지 않을 수 있으며, 이로 인해 일부 페이지의 TTFB 값이 다른 페이지보다 높아질 수 있습니다. 캐싱 시간을 늘리면 이에 따른 영향을 줄일 수 있지만 캐싱 시간이 길어지면 오래된 콘텐츠를 제공할 가능성이 커집니다.

캐시된 콘텐츠의 영향은 CDN을 사용하는 콘텐츠에만 영향을 미치는 것이 아닙니다. 캐시된 콘텐츠를 재사용할 수 없는 경우 서버 인프라에서 비용이 많이 드는 데이터베이스 조회를 통해 콘텐츠를 생성해야 할 수 있습니다. 자주 액세스되는 데이터 또는 사전 캐시된 페이지의 성능이 더 좋은 경우가 많습니다.

페이지를 여러 번 리디렉션하지 않기

높은 TTFB의 일반적인 원인 중 하나는 리디렉션입니다. 리디렉션은 문서에 대한 탐색 요청이 다른 위치에 리소스가 있음을 브라우저에 알리는 응답을 수신하면 발생합니다. 하나의 리디렉션으로 인해 탐색 요청에 원치 않는 지연 시간이 추가될 수는 있지만, 리디렉션이 다른 리디렉션을 발생시키는 다른 리소스를 가리킬 경우에는 확실히 더 나빠질 수 있습니다. 측정 목적으로 분석 서비스를 통해 리디렉션하는 경우가 많으므로 광고나 뉴스레터를 통해 유입되는 방문자 수가 많은 사이트에 특히 영향을 줍니다. 직접 제어할 수 있는 리디렉션을 없애면 좋은 TTFB를 달성하는 데 도움이 될 수 있습니다.

리디렉션에는 두 가지 유형이 있습니다.

  • 동일 출처 리디렉션: 리디렉션이 전적으로 웹사이트에서 발생합니다.
  • 교차 출처 리디렉션: 웹사이트에 도착하기 전에 리디렉션이 소셜 미디어 URL 단축 서비스 등 다른 출처에서 처음으로 발생합니다.

동일 출처 리디렉션을 제거하는 데 집중하는 것이 좋습니다. 이 작업은 개발자가 직접 제어할 수 있기 때문입니다. 이때 웹사이트의 링크를 확인하여 302 또는 301 응답 코드로 연결되는 링크가 있는지 확인해야 합니다. 이 문제는 보통 https:// 스키마를 포함하지 않은 경우 (브라우저가 http://로 기본 설정되고 이후 리디렉션됨) URL에 후행 슬래시가 적절하게 포함되거나 제외되지 않았기 때문일 수 있습니다.

교차 출처 리디렉션은 제어할 수 없는 경우가 많으므로 더 까다롭지만, 가능하면 여러 번 리디렉션(예: 링크를 공유할 때 여러 링크 축약기 사용)을 사용하는 것은 피해야 합니다. 광고주 또는 뉴스레터에 제공된 URL이 올바른 최종 URL인지 확인하여 이러한 서비스에서 사용하는 URL로 다른 리디렉션을 추가하지 않도록 합니다.

리디렉션 시간의 또 다른 중요한 소스는 HTTP-HTTPS 간 리디렉션에서 올 수 있습니다. 이 문제를 해결할 수 있는 한 가지 방법은 HSTS (Strict-Transport-Security 헤더)를 사용하는 것입니다. HSTS는 출처에 처음 방문할 때 HTTPS를 적용한 다음 향후 방문 시 HTTPS 스키마를 통해 출처에 즉시 액세스하도록 브라우저에 지시합니다.

적절한 HSTS 정책을 마련하면 사이트를 HSTS 미리 로드 목록에 추가하여 출처를 처음 방문할 때 작업 속도를 높일 수 있습니다.

브라우저로 마크업 스트리밍

브라우저는 마크업이 스트리밍될 때 마크업을 효율적으로 처리하도록 최적화되어 있습니다. 즉, 마크업은 서버에서 도착할 때 청크로 처리됩니다. 이는 대규모 마크업 페이로드와 관련된 경우에 중요합니다. 왜냐하면 파싱이 시작되기 전에 전체 응답이 도착할 때까지 기다리는 대신 브라우저가 해당 마크업 청크를 점진적으로 파싱할 수 있기 때문입니다.

브라우저는 스트리밍 마크업을 처리하는 데 탁월하지만, 초기 마크업이 가능한 한 빨리 전달될 수 있도록 스트림이 계속 흐르도록 할 수 있는 모든 작업을 수행하는 것이 중요합니다. 백엔드가 작업을 보류하고 있다면 문제가 됩니다. 백엔드 스택은 많기 때문에 모든 단일 스택과 각각의 특정 스택에서 발생할 수 있는 문제를 다루는 것은 이 가이드의 범위를 벗어납니다.

예를 들어 React 및 서버에서 요청 시 마크업을 렌더링할 수 있는 다른 프레임워크는 서버 측 렌더링에 동기식 접근 방식을 사용했습니다. 그러나 최신 버전의 React에서는 렌더링이 진행될 때 스트리밍 마크업을 위한 서버 메서드를 구현했습니다. 즉, React 서버 API 메서드가 전체 응답을 렌더링할 때까지 기다렸다가 전송할 필요가 없습니다.

마크업이 브라우저로 빠르게 스트리밍되도록 하는 또 다른 방법은 빌드 시 HTML 파일을 생성하는 정적 렌더링을 사용하는 것입니다. 전체 파일을 즉시 사용할 수 있게 되면 웹 서버에서 즉시 파일을 보내기 시작할 수 있으며 HTTP의 특성상 스트리밍 마크업이 발생합니다. 이 방법은 사용자 환경의 일부로 동적 응답을 필요로 하는 페이지와 같은 모든 웹사이트의 모든 페이지에 적합하지는 않지만, 마크업을 특정 사용자에게 맞춤설정할 필요가 없는 페이지에는 유용할 수 있습니다.

서비스 워커 사용

Service Worker API는 문서와 로드되는 리소스의 TTFB에 큰 영향을 미칠 수 있습니다. 그 이유는 서비스 워커가 브라우저와 서버 사이의 프록시 역할을 하지만 웹사이트의 TTFB에 영향을 미칠지 여부는 서비스 워커를 설정하는 방법과 해당 설정이 애플리케이션 요구사항에 부합하는지 여부에 따라 다르기 때문입니다.

  • 애셋에 대해 비활성 상태인 재검증 전략을 사용합니다. 애셋이 서비스 워커 캐시(문서 또는 문서에 필요한 리소스)에 있는 경우, 비활성 재검증 전략은 먼저 캐시에서 해당 리소스를 서비스한 다음, 백그라운드에서 애셋을 다운로드하고 향후 상호작용을 위해 캐시에서 제공합니다.
    • 자주 변경되지 않는 문서 리소스가 있는 경우 비활성 상태 재검증 전략을 사용하면 페이지의 TTFB를 거의 즉시 만들 수 있습니다. 그러나 웹사이트에서 동적으로 생성된 마크업(예: 사용자 인증 여부에 따라 변경되는 마크업)을 전송하는 경우에는 이 방식이 제대로 작동하지 않습니다. 이러한 경우 항상 먼저 네트워크에 접속하여 문서를 최신 상태로 유지하는 것이 좋습니다.
    • 문서가 일정 빈도로 변경되는 중요하지 않은 리소스를 로드하지만 오래된 리소스 가져오기가 사용자 환경에 큰 영향을 미치지 않는 경우(예: 선택 이미지 또는 중요하지 않은 기타 리소스) 이러한 리소스의 TTFB는 비활성 상태 재검증 전략을 사용하여 크게 줄일 수 있습니다.
  • 클라이언트 렌더링 애플리케이션에는 앱 셸 모델을 사용합니다. 이 모델은 페이지의 '셸'이 서비스 워커 캐시로부터 즉시 전달될 수 있고 페이지의 동적 콘텐츠가 나중에 페이지 수명 주기에서 채워지고 렌더링되는 SPA에 가장 적합합니다.

렌더링에 중요한 리소스에 103 Early Hints 사용

애플리케이션 백엔드가 얼마나 잘 최적화되었든, 탐색 응답이 최대한 빨리 도착하는 것을 지연시키는 값비싼 (아직 필요한) 데이터베이스 작업을 포함하여 응답을 준비하기 위해 서버에서 해야 할 상당한 작업이 여전히 있을 수 있습니다. 이로 인해 렌더링에 중요한 일부 리소스(예: CSS 또는 경우에 따라 클라이언트에서 마크업을 렌더링하는 JavaScript)와 같이 렌더링에 중요한 일부 리소스가 지연될 수 있습니다.

103 Early Hints 헤더는 백엔드가 마크업을 준비하는 동안 서버가 브라우저에 보낼 수 있는 조기 응답 코드입니다. 이 헤더는 마크업이 준비되는 동안 페이지에서 다운로드를 시작해야 하는 렌더링에 중요한 리소스가 있음을 브라우저에 알리는 데 사용할 수 있습니다. 지원되는 브라우저의 경우 문서 렌더링 (CSS) 속도가 빨라지고 핵심 페이지 기능 (JavaScript)의 가용성이 빨라질 수 있습니다.

결론

백엔드 애플리케이션 스택의 조합은 매우 많기 때문에 웹사이트의 TTFB를 낮추기 위해 할 수 있는 모든 것을 요약할 수 있는 하나의 문서는 없습니다. 하지만 서버 측에서 작업을 조금 더 빠르게 진행하기 위해 살펴볼 수 있는 몇 가지 옵션은 다음과 같습니다.

모든 측정항목을 최적화할 때와 마찬가지로 접근 방식은 대체로 유사합니다. 현장에서 TTFB를 측정하고 실험실 도구를 사용하여 원인을 조사한 다음 가능한 경우 최적화를 적용합니다. 여기에 제시된 모든 기법이 현재 상황에 적합한 것은 아니지만 일부 기술은 사용할 수 있습니다. 언제나 그렇듯이, 필드 데이터를 주의 깊게 관찰하고 필요에 따라 조정하여 최대한 빠른 사용자 환경을 제공해야 합니다.

히어로 이미지: 테일러 빅, 출처: Unsplash