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

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

첫 바이트까지의 시간 (TTFB)콘텐츠가 포함된 첫 페인트 (FCP)콘텐츠가 포함된 최대 페인트 (LCP)와 같은 다른 모든 의미 있는 사용자 환경 측정항목보다 먼저 발생하는 기본적인 웹 성능 측정항목입니다. 즉, TTFB 값이 높을수록 후속 측정항목에 시간이 추가됩니다.

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

적절한 TTFB 값은 0.8초 이하이고, 좋지 않은 값은 1.8초보다 크며, 그 사이의 값은 개선이 필요합니다.

TTFB 측정 방법

TTFB를 최적화하려면 먼저 웹사이트 사용자에게 TTFB가 미치는 영향을 관찰해야 합니다. TTFB가 리디렉션의 영향을 받기 때문에 필드 데이터를 기본 소스로 사용해야 하는 반면, 실험실 기반 도구는 최종 URL을 사용하여 측정하는 경우가 많으므로 이러한 추가 지연을 놓칠 수 있습니다.

PageSpeed Insights를 사용하면 Chrome 사용자 환경 보고서에서 제공되는 공개 웹사이트의 필드 및 실습 정보를 간편하게 확인할 수 있습니다.

실제 사용자를 위한 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의 Network 탭에 있는 Server-Timing 헤더 값의 시각화 이 이미지에서 Server-Timing 헤더 값은 CDN 에지 서버에 캐시 적중 또는 누락이 발생했는지와 에지 및 원본 서버에서 리소스를 검색하는 데 걸린 시간을 측정합니다.

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

사용 가능한 데이터를 분석하여 문제가 있는 TTFB가 있다고 판단되면 문제 해결 단계로 넘어갈 수 있습니다.

TTFB 최적화 방법

TTFB를 최적화할 때 가장 어려운 측면은 웹의 프런트엔드 스택이 항상 HTML, CSS 및 자바스크립트이지만 백엔드 스택은 크게 다를 수 있다는 점입니다. 각각 고유한 최적화 기술이 있는 수많은 백엔드 스택과 데이터베이스 제품이 있습니다. 따라서 이 가이드에서는 스택별 가이드에만 집중하기보다는 대부분의 아키텍처에 적용되는 사항에 중점을 둡니다.

플랫폼별 안내

웹사이트에 사용하는 플랫폼은 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가 의존하는 TCP)에 존재하는 대기 행렬 막힘 문제를 해결합니다.
  • 또한 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로 리디렉션할 수 있습니다. 이 문제를 해결할 수 있는 한 가지 방법은 Strict-Transport-Security 헤더 (HSTS)를 사용하는 것입니다. HSTS는 출처에 처음 방문할 때 HTTPS를 적용한 다음 브라우저가 향후 방문 시 HTTPS 스키마를 통해 출처에 즉시 액세스하도록 지시합니다.

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

브라우저에 마크업 스트림

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

브라우저는 스트리밍 마크업을 잘 처리하지만, 초기 마크업이 최대한 빨리 전달될 수 있도록 스트림의 흐름을 유지하는 데 필요한 모든 조치를 취하는 것이 중요합니다. 백엔드에서 지연되고 있다면 문제가 됩니다. 백엔드 스택은 많기 때문에 이 가이드에서는 모든 단일 스택과 특정 스택에서 발생할 수 있는 문제를 다루지 않습니다.

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

마크업이 브라우저로 빠르게 스트리밍되도록 하는 또 다른 방법은 빌드 시간 동안 HTML 파일을 생성하는 정적 렌더링을 사용하는 것입니다. 전체 파일을 즉시 사용할 수 있으므로 웹 서버에서 즉시 파일 전송을 시작할 수 있으며 HTTP의 고유한 특성으로 인해 스트리밍 마크업이 발생합니다. 이 방법은 모든 웹사이트의 모든 페이지(예: 사용자 경험의 일부로 동적 응답이 필요한 페이지)에 적합하지는 않지만, 특정 사용자에게 맞춤 마크업할 필요가 없는 페이지에 유용할 수 있습니다.

서비스 워커 사용

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

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

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

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

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

결론

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

모든 측정항목을 최적화하는 것과 마찬가지로 접근 방식은 대체로 비슷합니다. 즉, 현장에서 TTFB를 측정하고 실험실 도구를 사용해 원인을 자세히 분석한 후 가능한 경우 최적화를 적용합니다. 여기에 나와 있는 모든 기법이 사용자의 상황에 적합한 것은 아니지만, 일부 기법은 사용 가능합니다. 항상 그렇듯이 필드 데이터를 주의 깊게 살펴보고 필요에 따라 조정하여 가능한 한 빠른 사용자 환경을 보장해야 합니다.

테일러 빅의 히어로 이미지(Unsplash 제공)