본문 바로가기
MAKESITE
무료 스캔 문의하기 로그인

점검 항목 · 성능

첫 응답이 느림(TTFB)

이미지를 아무리 줄여도 이 구간은 줄지 않습니다. 그림을 그리기 전에 종이가 도착하기를 기다리는 시간이기 때문입니다.

심각도 보통 성능 무료 스캔 판정 항목 /check/ttfb

01DEFINITION

한 줄로 말하면

TTFB 는 브라우저가 요청을 보내고 첫 바이트를 받기까지의 시간입니다. 이 구간이 길면 이미지를 아무리 줄여도 체감 속도가 좋아지지 않습니다. 화면이 그려지기 시작하는 시점 자체가 뒤로 밀리기 때문입니다. 원인은 대개 느린 쿼리, 외부 API 응답 대기, 캐시 없음 셋 중 하나이고 프런트엔드 최적화로는 손댈 수 없는 자리입니다.

02RISK

없으면 무슨 일이 생기나

브라우저는 첫 바이트를 받아야 화면을 그리기 시작합니다. 그전까지는 아무것도 할 수 없고, 방문자가 보는 것은 흰 화면입니다. 이 구간이 1초를 넘어가면 사람들은 페이지가 열리지 않았다고 판단하기 시작합니다. 이미지를 최적화하고 스크립트를 미뤄도 이 시간 뒤에 일어나는 일이라 체감이 바뀌지 않습니다.

원인은 대개 서버 안쪽에 있습니다. 목록 하나 그리는 데 쿼리가 수백 번 나가거나, 페이지 안에서 외부 API 응답을 기다리거나, 매번 같은 결과를 처음부터 다시 계산하는 경우입니다. 이 셋은 방문자가 늘어날수록 급격히 나빠지는 성질이 있어서, 평소에는 괜찮다가 이벤트 날에 무너집니다.

검색 쪽 영향도 있습니다. 크롤러는 사이트마다 할당된 시간 안에서 페이지를 읽는데, 한 페이지에 오래 걸리면 그만큼 적은 페이지를 읽고 돌아갑니다. 페이지가 수천 개인 사이트에서 새 글이 늦게 색인되는 원인 중 하나입니다.

03CHECK IT YOURSELF

직접 확인하는 방법

아래는 저희를 거치지 않고 지금 해 보실 수 있는 방법입니다. 결과를 저희에게 보내실 필요도 없습니다.

  1. 01
    첫 바이트까지의 시간만 재 본다

    전체 소요와 헷갈리지 않아야 합니다. 아래 값 중 앞의 것이 TTFB 이고 뒤가 전체입니다. 두 값의 차이가 크면 그것은 다른 항목의 문제입니다.

    $ curl -s -o /dev/null -w "ttfb=%{time_starttransfer} total=%{time_total}\n" \
        https://example.com/
    ttfb=0.184 total=0.312
  2. 02
    연결 단계를 쪼개서 본다

    어느 구간이 오래 걸리는지 나눠 보면 원인이 좁혀집니다. 이름 조회가 느린 것인지, 연결이 느린 것인지, 서버가 생각하는 시간이 긴 것인지가 갈립니다.

    $ curl -s -o /dev/null -w \
    "dns=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer}\n" \
        https://example.com/
  3. 03
    정적 파일과 비교한다

    이미지 하나를 요청해 TTFB 를 재 봅니다. 정적 파일은 빠른데 HTML 만 느리면 원인은 애플리케이션 안쪽입니다. 정적 파일도 느리면 네트워크나 서버 자원 문제입니다.

    $ curl -s -o /dev/null -w "%{time_starttransfer}\n" https://example.com/favicon.ico
  4. 04
    여러 번 재서 편차를 본다

    한 번 재고 판단하면 안 됩니다. 열 번쯤 반복해 값이 들쭉날쭉하면 캐시가 없는 것이고, 일정하게 느리면 처리 자체가 무거운 것입니다.

    $ for i in $(seq 10); do curl -s -o /dev/null -w "%{time_starttransfer}\n" https://example.com/; done

04HOW TO FIX

고치는 방법

서버 환경에 따라 적을 자리가 다릅니다. 아래는 가장 흔한 구성 기준이고, 적용 전에 현재 설정을 백업하십시오.

느린 쿼리부터 찾는다

대부분의 원인이 여기 있습니다. 데이터베이스의 느린 쿼리 로그를 켜고 하루만 모아 보면 대개 범인이 한둘로 좁혀집니다. 목록을 그리면서 행마다 쿼리를 한 번씩 더 던지는 구조가 가장 흔합니다.

# MariaDB / MySQL
slow_query_log = 1
long_query_time = 0.5
slow_query_log_file = /var/log/mysql/slow.log
요청 처리 중에 외부를 기다리지 않는다

메일 발송, 알림톡, 외부 API 호출을 페이지 그리는 중에 하면 그쪽이 느린 날 우리 페이지가 같이 느려집니다. 큐에 넣고 백그라운드에서 처리하는 구조로 바꾸십시오. 저희도 메일은 전부 큐를 거칩니다.

같은 결과를 다시 계산하지 않는다

메인 화면의 인기 상품 목록처럼 모든 방문자에게 같은 결과가 나가는 것은 계산해 두고 재사용합니다. 몇 분짜리 캐시만 넣어도 이벤트 날의 부하가 크게 달라집니다.

PHP 라면 바이트코드 캐시가 켜져 있는지 확인한다

꺼져 있으면 요청마다 모든 소스를 다시 해석합니다. 대부분의 환경에서 기본으로 켜져 있지만, 공유 호스팅이나 손으로 올린 서버에서 빠져 있는 경우가 있습니다.

$ php -i | grep -i "opcache.enable"
opcache.enable => On => On
가능하면 완성된 HTML 을 캐시한다

로그인이 없는 소개 페이지나 상품 목록은 결과 HTML 자체를 캐시할 수 있습니다. 이 경우 TTFB 가 한 자릿수 밀리초까지 떨어집니다. 다만 가격이나 재고가 바뀔 때 캐시를 지우는 규칙을 함께 만들어야 합니다.

주의. 무료 스캔의 성능 판정은 간이 측정입니다. 저희가 있는 곳에서 한 번 요청해 잰 값이라 방문자가 실제로 겪는 시간과 다를 수 있고, 정밀한 사용자 체감 지표 측정은 포함되지 않습니다.

05FAQ

자주 묻는 질문

TTFB 와 페이지 로딩 시간은 다른 것인가요

다릅니다. TTFB 는 첫 바이트가 도착하기까지이고, 로딩 시간은 화면이 다 그려지기까지입니다. TTFB 가 짧아도 이미지가 무거우면 로딩은 느리고, TTFB 가 길면 그 뒤가 아무리 빨라도 전체가 밀립니다. 두 지표는 원인이 다르고 고치는 방법도 다릅니다.

얼마나 나오면 괜찮은 건가요

일반적으로 0.8초 아래를 권장선으로 봅니다. 다만 절대적인 기준보다 우리 사이트의 다른 페이지와 비교하는 편이 유용합니다. 홈은 빠른데 상품 목록만 느리다면 그 페이지의 쿼리를 보면 되고, 전 페이지가 고르게 느리면 서버나 호스팅 환경의 문제입니다.

이미지를 줄였는데 왜 그대로인가요

이미지는 첫 바이트가 도착한 뒤에 받는 것이기 때문입니다. TTFB 는 서버가 HTML 을 만들어 내보내기 시작할 때까지의 시간이라 이미지와 무관합니다. 이 둘을 구분하지 못하면 몇 달 동안 효과 없는 최적화를 반복하게 됩니다.

CDN 을 붙이면 해결되나요

정적 파일에는 효과가 크지만 HTML 은 다릅니다. 로그인 상태에 따라 내용이 달라지는 페이지는 CDN 이 캐시할 수 없어 매번 원 서버까지 다녀와야 합니다. 오히려 경유지가 하나 늘어 조금 느려질 수도 있습니다. 서버 안쪽의 처리 시간을 먼저 보십시오.
여기까지는 항목 일반론입니다. 무엇이고 왜 문제이며 어떻게 고치는지는 감출 이유가 없어 그대로 적었습니다. 리포트에 들어가는 것은 귀사 사이트에서 실제로 어떤 값이 나왔는지 — 어느 주소의 어느 응답인지, 그 환경에서 어떤 순서로 적용해야 하는지, 예상 공수가 얼마인지입니다. 이 페이지만 보고 직접 고치셔도 되고, 실제로 그러시라고 적어 두었습니다.

GET STARTED

내 사이트는
이 항목을 통과할까요

주소만 넣으시면 이 항목을 포함해 25가지를 판정해 점수와 실패 개수를 보여 드립니다. 로그인도, 소유 확인도 필요 없습니다 — 전부 밖에서 관찰만 하는 항목이기 때문입니다.