이 글의 목차
이 파트의 핵심
- 기술적 SEO는 검색엔진과 AI 크롤러가 페이지를 크롤링·렌더링·색인할 수 있게 만드는 기반 작업입니다. 콘텐츠가 좋아도 이 단계에서 막히면 검색과 AI 답변 어디에도 나오지 않습니다.
- robots.txt는 2022년 RFC 9309로 표준화되었고 크롤링만 제어합니다. 색인 제외는
noindex로 하되,noindex는 크롤 버짓을 아껴 주지 않습니다. - 2026년 9월 기준 Core Web Vitals 기준은 LCP 2.5초, INP 200ms, CLS 0.1 이하(75백분위)입니다.
- 주요 AI 크롤러는 자바스크립트를 실행하지 않고, 구글봇은 HTML 파일의 처음 2MB만 처리합니다. 핵심 콘텐츠는 서버 렌더링(SSR)·정적 생성(SSG)으로 초기 HTML에 넣으세요.
- 서버 설정 관행도 바뀌었습니다. Nginx는
http2 on;, Let's Encrypt는 OCSP를 종료했고, Cloudflare Auto Minify는 폐지되었습니다.
기술적 SEO는 “콘텐츠가 아무리 좋아도 검색엔진이 제대로 읽지 못하면 의미가 없다”는 전제에서 시작합니다. 크롤링, 인덱싱, 렌더링, 사이트 속도, 보안, 서버 설정이 모두 검색 노출에 영향을 줍니다. 2026년에는 여기에 ChatGPT·
5-A. 크롤링 & 인덱싱
크롤링·인덱싱 단계의 목표는 중요한 URL은 빠짐없이 발견·수집되게 하고, 불필요한 URL은 크롤러의 시간을 낭비하지 않게 하는 것입니다.
5.1 robots.txt 작성 가이드
robots.txt는 사이트 루트에 두는 텍스트 파일로, 크롤러에게 어떤 URL을 크롤링해도 되는지 알려 줍니다. 2022년 9월 IETF 표준 RFC 9309(Robots Exclusion Protocol)로 정리되었습니다 (IETF, 2022). 구글이 지원하는 필드는 user-agent, allow, disallow, sitemap 네 가지이고 crawl-delay는 지원하지 않습니다. 파일은 500KiB까지만 읽고, 보통 최대 24시간 캐시합니다 (Google, 2026).
기본 문법
User-agent: * # 모든 크롤러에 적용
Disallow: /admin/ # /admin/ 경로 크롤링 차단
Disallow: /private/ # /private/ 경로 크롤링 차단
Allow: / # 그 외 모든 경로 허용
Sitemap: https://example.com/sitemap.xml # 사이트맵 위치 안내
자주 차단하는 경로
User-agent: *
Disallow: /admin/
Disallow: /wp-admin/ # WordPress 관리자
Disallow: /cart/ # 장바구니
Disallow: /checkout/ # 결제
Disallow: /my-account/ # 회원 마이페이지
Disallow: /search/ # 내부 검색 결과
Disallow: /?s= # WordPress 검색 파라미터
RFC 9309는 robots.txt가 접근 권한 제어 수단이 아니며, 파일에 적은 경로는 누구나 볼 수 있다고 명시합니다 (IETF, 2022). 관리자 경로는 robots.txt가 아니라 인증으로 보호하세요.
robots.txt의 치명적인 실수
가장 흔하고 치명적인 실수는 중요한 페이지를 실수로 차단하는 것입니다. 스테이징 서버의 Disallow: /가 프로덕션에 그대로 배포되면 사이트 전체가 검색에서 사라질 수 있습니다. 응답 코드도 중요합니다. 구글은 robots.txt가 4xx(429 제외)이면 제한이 없는 것으로 보지만, 5xx이면 처음 12시간 동안 사이트 크롤링을 멈추고 이후 30일간 마지막 정상 버전을 씁니다 (Google, 2026). robots.txt가 서버 오류를 내지 않는지 모니터링하세요.
robots.txt는 색인 차단 도구가 아닙니다
robots.txt로 막은 페이지도 다른 사이트에서 링크되면 설명 없이 색인될 수 있습니다. 검색에서 빼려면 noindex 메타 태그나 X-Robots-Tag 헤더를 쓰고, 이때는 크롤러가 태그를 읽을 수 있도록 robots.txt로 막지 않아야 합니다 (Google Search Central, 2025).
5.2 AI 크롤러 접근 관리
AI 답변에 인용되려면 각 AI 서비스의 검색용 크롤러를 허용하고, 모델 학습용 크롤러는 회사 정책에 따라 따로 정합니다. 2026년 9월 기준 각 사 공식 문서의 주요 토큰은 다음과 같습니다 (OpenAI, 2026; Anthropic, 2026; Perplexity, 2026; Google, 2026).
| 회사 | 검색·답변용 | 사용자 요청 방문 | 모델 학습용 |
|---|---|---|---|
| Googlebot (AI 개요·AI 모드 포함) | Google-Agent | Google-Extended (제품 토큰) | |
| OpenAI | OAI-SearchBot | ChatGPT-User | GPTBot |
| Anthropic | Claude-SearchBot | Claude-User | ClaudeBot |
| Perplexity | PerplexityBot | Perplexity-User | — |
| Microsoft·네이버 | Bingbot· | — | — |
예전 예제에 흔한 anthropic-ai는 현재 Anthropic 문서에 없는 토큰이고, Google-Extended는 구글 AI 개요(AI Overviews) 노출과 무관합니다. Google-Extended는 Gemini 모델 학습과 Gemini 앱·Vertex AI의 그라운딩에 콘텐츠를 쓸지 여부만 제어하며, 구글 검색 포함 여부나 순위에는 영향을 주지 않습니다 (Google, 2026). AI 개요에서 빠지고 싶다면 서치 콘솔의 ‘검색 생성형 AI 제어’나 nosnippet 계열 지시어를 써야 합니다(PART 4 참고).
# 기본 그룹: 검색엔진·AI 검색용 크롤러는 여기를 따릅니다
User-agent: *
Disallow: /admin/
# (선택) 모델 학습용 크롤러만 차단
User-agent: GPTBot
Disallow: /
User-agent: ClaudeBot
Disallow: /
User-agent: Google-Extended
Disallow: /
크롤러는 자기 이름과 가장 구체적으로 일치하는 그룹 하나만 따르고, 이때 User-agent: * 그룹 규칙은 합쳐지지 않습니다 (Google, 2026). 위 예에서 GPTBot 그룹에는 /admin/ 규칙이 적용되지 않는다는 뜻입니다. 특정 크롤러 그룹을 만들 때는 필요한 규칙을 그 그룹에도 모두 적으세요. 사용자 요청으로 방문하는 ChatGPT-User에는 robots.txt가 적용되지 않을 수 있고, Perplexity-User는 대체로 따르지 않습니다.
CDN 설정도 확인해야 합니다. Cloudflare는 2025년 7월 AI 크롤러를 기본 차단하는 쪽으로 기본값을 바꿨고 (Cloudflare, 2025), 관리형 robots.txt를 켜면 GPTBot·openai.com/searchbot.json)으로 진짜 봇인지 검증하세요. 엔진별 인용 구조는 PART 4의 AI 크롤러 접근과 llms.txt, 봇별 설정 사례는 AI 크롤러 robots.txt 설정 가이드에서 다룹니다.
2026년 9월 업데이트
구글은 2026년 2월 구글봇이 지원 파일 형식의 처음 2MB(PDF는 64MB)만 크롤링한다고 문서를 명확히 했습니다. 크롤러 공통 기본값인 15MB와 다릅니다 (Google, 2026). 크롤링 관련 문서는 2025년 11월부터 developers.google.com/crawling으로 옮겨졌고, robots.txt 해석 문서는 2026년 8월에 갱신되었습니다. HTML 앞부분에 거대한 인라인 스크립트·JSON·
5.3 XML Sitemap 생성 및 제출
XML 사이트맵은 색인되기를 원하는 중요 URL 목록을 검색엔진에 알려 주는 파일입니다. 사이트가 크거나 새 페이지가 많을수록, 내부 링크가 부족할수록 중요해집니다. 사이트맵 하나에는 URL 5만 개 또는 비압축 50MB까지 넣을 수 있습니다 (Google Search Central, 2026).
기본 사이트맵 구조
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/seo-guide/</loc>
<lastmod>2026-09-28</lastmod>
</url>
</urlset>
구글은 <changefreq>와 <priority>를 쓰지 않고, <lastmod>는 일관되게 정확할 때만 사용합니다 (Google Search Central, 2026). 내용을 실제로 고친 날짜만 넣고, 빌드할 때마다 모든 URL의 날짜를 오늘로 바꾸지 마세요.
사이트맵 유형
- 사이트맵 인덱스: 여러 사이트맵을 묶는 파일. URL이 5만 개를 넘거나 유형별로 나눌 때 씁니다.
- 페이지·글 사이트맵: 일반 페이지와 블로그 글을 나눠 관리하면 오류 추적이 쉽습니다.
- 이미지·동영상 사이트맵: 이미지·동영상 검색 노출용
- 뉴스 사이트맵: 뉴스 사이트 전용 (최근 2일 이내 기사)
사이트맵에 넣지 말아야 할 URL
- noindex가 설정된 페이지, 리다이렉트(301/302)되는 URL, 404 페이지
- canonical이 다른 URL을 가리키는 중복 페이지
- 로그인이 필요한 페이지
제출 방법
서치 콘솔 → Sitemaps에서 사이트맵 URL을 제출하거나, robots.txt에 Sitemap: 줄을 넣습니다. 예전에 쓰던 구글의 사이트맵 ‘핑(ping)’ 엔드포인트는 2023년에 폐지되어 요청해도 아무 효과가 없습니다 (Google Search Central Blog, 2023). 제출 후 상태가 “성공”인지, 발견된 URL 수가 예상과 맞는지 정기적으로 확인하세요.
5.4 IndexNow로 변경 사항 즉시 알리기
IndexNow는 URL을 추가·수정·삭제했을 때 참여 검색엔진에 바로 알리는 프로토콜입니다. 2026년 9월 기준 참여 엔진은 빙, 얀덱스, 세즈남, 네이버, Yep, 인터넷 아카이브, 아마존봇이며, 한 곳에 보내면 모든 참여 엔진에 공유됩니다. 구글은 참여하지 않습니다 (IndexNow.org, 2026). 사이트 루트에 키 파일({키}.txt)을 두고, POST 요청 한 번에 URL을 최대 1만 개까지 보낼 수 있습니다. 빙은 AI 답변이 최신 버전을 참조하도록 IndexNow 사용을 권장합니다 (Bing, 2026).
curl -X POST "https://api.indexnow.org/indexnow" \
-H "Content-Type: application/json; charset=utf-8" \
-d '{
"host": "www.example.com",
"key": "your-indexnow-key",
"keyLocation": "https://www.example.com/your-indexnow-key.txt",
"urlList": ["https://www.example.com/guide/part-05"]
}'
첫 요청에는 키를 검증하는 동안 HTTP 202가, 이후에는 200이 돌아오는 것이 정상입니다 (IndexNow.org, 2026).
5.5 크롤 버짓(Crawl Budget) 관리
크롤 버짓은 구글이 사이트에서 크롤링할 수 있고 크롤링하려는 URL의 양으로, 서버가 감당할 수 있는 크롤링 용량과 구글의 크롤링 수요로 정해집니다. 구글은 이 관리가 주로 고유 페이지 100만 개 이상이면서 주 단위로 바뀌는 사이트, 1만 개 이상이면서 매일 바뀌는 사이트, ‘발견됨 - 현재 색인이 생성되지 않음’ URL이 많은 사이트에 필요하다고 설명합니다 (Google, 2026). 작은 사이트라면 대부분 신경 쓸 필요가 없습니다.
크롤 버짓이 낭비되는 원인
- 파라미터 URL 과다: 필터·정렬·추적 파라미터로 수천 개의 중복 URL 생성
- 무한 페이지·캘린더: 끝없이 이어지는 목록이나 날짜 URL
- 소프트 404: 없는 페이지인데 200을 반환하는 URL
- 긴 리다이렉트 체인과 느린 서버 응답
크롤 버짓 최적화 방법
- 필터·정렬 같은 패싯 내비게이션 URL은 robots.txt로 크롤링을 막습니다. canonical이나 nofollow는 장기적으로 효과가 떨어집니다 (Google, 2025).
- 완전히 삭제한 페이지는 404나 410을 반환하고, 소프트 404를 없앱니다.
- 크롤 버짓 절약용으로
noindex를 쓰지 않습니다. 구글은 페이지를 요청한 뒤에야 noindex를 보고 버리므로 크롤링 시간이 그대로 낭비됩니다 (Google, 2026). - 다른 페이지에 버짓을 몰아주려고 robots.txt를 임시로 바꾸는 것도 효과가 없습니다.
- 사이트맵을 최신으로 유지하고, 리다이렉트 체인을 줄이고, 서버 응답 속도를 개선합니다.
5.6 404 & 301 리다이렉트 전략
404 오류 관리
서치 콘솔 → 페이지 색인 생성 보고서에서 ‘찾을 수 없음(404)’ URL을 확인합니다. 404 자체는 벌점이 아니지만, 백링크가 걸린 URL이 404라면 그 링크의 가치를 잃습니다. 구글 크롤러는 429를 제외한 모든 4xx를 “콘텐츠 없음”으로 똑같이 처리합니다 (Google, 2026).
- 콘텐츠가 이동했다면 → 새 URL로 301 리다이렉트
- 대체할 만한 유사 콘텐츠가 있다면 → 가장 관련 높은 페이지로 301 리다이렉트
- 콘텐츠가 완전히 사라졌다면 → 404 또는 410 반환. 관련 없는 홈페이지로 일괄 리다이렉트하면 사용자가 원하는 정보를 찾지 못하므로 피합니다.
301 vs 302 리다이렉트
- 301·
308 (영구 이동): 구글은 리다이렉트 대상 URL을 대표(canonical) URL로 삼는 신호로 씁니다. 주소를 영구적으로 바꿀 때 사용합니다. - 302·
303· 구글은 대상 URL을 대표 URL로 삼는 신호로 쓰지 않습니다. A/B 테스트, 일시적인 점검 페이지에만 사용합니다 (Google Search Central, 2026).307 (임시 이동):
리다이렉트는 서버 측 방식이 가장 확실하며, 자바스크립트 리다이렉트는 서버 측이나 meta refresh를 쓸 수 없을 때만 씁니다. 사이트 이전 절차는 사이트 이전 SEO 가이드에서 자세히 다룹니다.
Nginx 301 리다이렉트 설정 예시:
# 특정 URL 영구 이동
location = /old-page/ {
return 301 https://example.com/new-page/;
}
# 디렉터리 전체 이동 (하위 경로 유지)
location ^~ /old-category/ {
rewrite ^/old-category/(.*)$ /new-category/$1 permanent;
}
# http → https, www → non-www를 한 번에 최종 주소로
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
return 301 https://example.com$request_uri;
}
5.7 Pagination & Infinite Scroll 처리
페이지네이션의 원칙은 페이지마다 고유 URL을 주고 서로 링크로 연결하는 것입니다. 구글은 ?page=2처럼 페이지별 고유 URL을 쓰고, <a href>로 다음 페이지를 연결하며, 1페이지를 모든 페이지의 canonical로 지정하지 말고 각 페이지가 자기 자신을 canonical로 갖게 하라고 안내합니다. rel="next"·rel="prev"는 구글이 더 이상 쓰지 않고(다른 검색엔진은 쓸 수 있음), # 뒤의 프래그먼트는 무시하므로 페이지 구분에 쓰면 안 됩니다 (Google Search Central, 2025).
- 2페이지 이후를 noindex하거나 1페이지로 canonical하면 뒤쪽의 글·상품이 발견되지 않을 수 있습니다.
- 무한 스크롤·더 보기: 자바스크립트로 구현되므로, 스크롤로 불러오는 목록에도 페이지별 URL과 링크를 함께 제공하고 사이트맵으로 개별 항목을 알립니다.
5.8 JavaScript 렌더링과 크롤러
구글은 자바스크립트를 렌더링하지만, 모든 크롤러가 그렇지는 않습니다. 구글은 크롤링 → 렌더링 → 색인의 3단계로 페이지를 처리하며 최신 크로미움으로 자바스크립트를 실행합니다. 다만 200이 아닌 상태 코드의 페이지는 렌더링을 건너뛸 수 있고, 초기 HTML에 noindex가 있으면 렌더링 자체를 생략할 수 있어 자바스크립트로 noindex를 지우는 방식은 통하지 않을 수 있습니다. 구글도 서버 렌더링이나 프리렌더링이 “여전히 좋은 생각”이라며, 모든 봇이 자바스크립트를 실행하지는 못한다고 밝힙니다 (Google Search Central, 2026).
- AI 크롤러: Vercel의 분석에서 OpenAI·
Anthropic· Meta· ByteDance· Perplexity의 크롤러는 자바스크립트를 렌더링하지 않았습니다 (Vercel, 2024). 클라이언트 렌더링(CSR)만으로 만든 페이지는 이런 크롤러가 본문을 읽지 못합니다. - canonical: 자바스크립트로 초기 HTML과 다른 canonical을 넣지 않습니다.
- 라우팅: SPA는
#프래그먼트 대신 History API로 URL을 바꿉니다. - 동적 렌더링: 봇에게만 미리 렌더링한 HTML을 주는 방식은 구글이 “장기적 해법이 아닌 임시방편”이라고 규정했습니다. SSR, 정적 렌더링, 하이드레이션을 권장합니다 (Google Search Central, 2025).
5-B. 사이트 속도 최적화 (Core Web Vitals)
Core Web Vitals는 실제 사용자의 로딩(LCP)·반응성(INP)·시각적 안정성(CLS)을 재는 세 지표이며, 구글 순위 시스템이 사용하는 신호입니다. 다만 구글은 단일한 ‘페이지 경험 신호’는 없고, 경험이 다소 부족해도 가장 관련성 높은 콘텐츠를 보여 준다고 설명합니다 (Google Search Central, 2026). 속도는 관련성을 대신하지 못하지만, 비슷한 콘텐츠끼리의 경쟁에서는 차이를 만듭니다.
5.9 Core Web Vitals 완전 이해 — LCP, INP, CLS
2024년 3월 12일 INP(Interaction to Next Paint)가 FID(First Input Delay)를 대체하면서 Core Web Vitals는 지금의 세 가지 지표로 구성됩니다 (web.dev, 2024). 기준은 방문의 75번째 백분위 값을 모바일과 데스크톱으로 나눠 판단하며, 2026년 9월 기준 아래 수치가 그대로 유지되고 있습니다 (web.dev, 2024).
LCP (Largest Contentful Paint) — 로딩 성능
화면에서 가장 큰 콘텐츠 요소(이미지, 텍스트 블록 등)가 렌더링되는 시간입니다.
| 점수 | 기준 |
|---|---|
| 좋음 (Good) | 2.5초 이하 |
| 개선 필요 (Needs Improvement) | 2.5초 초과 ~ 4.0초 |
| 나쁨 (Poor) | 4.0초 초과 |
LCP 개선 방법:
- LCP 이미지를 AVIF·
WebP로 제공하고 fetchpriority="high"를 붙입니다. 이 속성은 크롬 102, 파이어폭스 132, 사파리 17.2부터 지원됩니다 (web.dev, 2023). - 화면 첫 부분의 이미지(특히 LCP 이미지)에는
loading="lazy"를 쓰지 않습니다. 지연 로딩한 페이지의 LCP가 더 느렸다는 분석이 있습니다 (web.dev, 2022). <link rel="preload">로 늦게 발견되는 LCP 리소스를 미리 불러옵니다.- TTFB를 줄이고, 서버 사이드 렌더링이나 정적 생성을 활용합니다.
INP (Interaction to Next Paint) — 반응성
방문 중 발생한 클릭·탭·키보드 입력의 지연을 관찰해, 이상치를 제외한 가장 긴 상호작용 시간을 보고합니다 (web.dev, 2025).
| 점수 | 기준 |
|---|---|
| 좋음 (Good) | 200ms 이하 |
| 개선 필요 (Needs Improvement) | 200ms 초과 ~ 500ms |
| 나쁨 (Poor) | 500ms 초과 |
INP 개선 방법:
- 무거운 JavaScript 실행 최소화
- Long Task(메인 스레드를 50ms 넘게 점유하는 작업) 분할
- React 등 프레임워크에서 불필요한 재렌더링 최소화
- Web Worker로 무거운 계산을 메인 스레드 밖으로 이동
CLS (Cumulative Layout Shift) — 시각적 안정성
페이지 로딩 중 레이아웃이 얼마나 이동하는지를 수치화한 것입니다.
| 점수 | 기준 |
|---|---|
| 좋음 (Good) | 0.1 이하 |
| 개선 필요 (Needs Improvement) | 0.1 초과 ~ 0.25 |
| 나쁨 (Poor) | 0.25 초과 |
CLS 개선 방법:
- 모든 이미지와 동영상에
width·height속성 지정 - 광고·임베드 영역의 공간을 미리 확보
- 웹폰트 교체로 인한 이동 방지 (
font-display: optional또는swap과 폴백 폰트 크기 조정) - 동적으로 삽입되는 배너는 기존 콘텐츠를 밀어내지 않는 위치에 배치
5.10 PageSpeed Insights & GTmetrix 활용법
Google PageSpeed Insights (PSI)
pagespeed.web.dev에서 URL을 입력하면 현장 데이터와 실험실 데이터를 함께 보여 줍니다.
- 현장 데이터(Field Data): 크롬 사용자 경험 보고서(CrUX)의 직전 28일간 실제 사용자 데이터입니다. Core Web Vitals 통과 여부는 이 데이터의 75번째 백분위로 판정합니다 (Google for Developers, 2024).
- 실험실 데이터(Lab Data): Lighthouse로 한 기기·고정된 네트워크 조건에서 측정한 시뮬레이션입니다. 원인 분석에 유용하지만 실제 사용자 경험과 다를 수 있습니다.
현장 데이터가 “나쁨”이라면 그것이 최우선 개선 대상입니다. 서치 콘솔의 Core Web Vitals 보고서로 같은 문제를 가진 URL 그룹을 찾으세요. 서치 콘솔·PSI 사용법은 PART 7 측정 & 분석 도구에서 다룹니다.
GTmetrix
gtmetrix.com은 Lighthouse 기반 분석에 지역별 테스트, 워터폴 차트, 기록 추적 기능을 더한 도구입니다.
- 가장 긴 막대의 리소스가 병목 지점입니다.
- TTFB가 길면 서버·캐시 설정 문제입니다.
- CSS·
JS 파일이 렌더링을 막고 있는지 확인합니다.
5.11 WebPageTest & Lighthouse 심층 분석
WebPageTest
webpagetest.org는 가장 심층적인 성능 분석을 제공하는 도구입니다.
- Filmstrip View: 로딩 과정을 일정 간격의 스크린샷으로 보여 줘 콘텐츠가 나타나는 시점을 직관적으로 확인할 수 있습니다.
- Connection View: 리소스별 DNS, TCP, TLS, 응답 시간을 표시합니다.
- Repeat View: 재방문 시 캐시가 제대로 작동하는지 확인합니다.
Chrome DevTools Lighthouse
개발자 도구(F12)의 Lighthouse 탭이나 CLI로 로컬 환경에서 빠르게 측정할 수 있습니다.
# CLI로 Lighthouse 실행
npx lighthouse https://example.com --output html --output-path ./report.html
5.12 이미지 최적화 — CDN, 포맷, 압축
이미지는 여전히 웹페이지에서 가장 무거운 리소스입니다. HTTP Archive의 Web Almanac 2025(2025년 7월 데이터)에서 모바일 홈페이지 중앙값은 약 2.6MB였고, 그중 이미지가 911KB로 자바스크립트(632KB)보다 컸습니다 (HTTP Archive, 2026). 구글 검색은 AVIF 형식도 지원합니다 (Google Search Central, 2024).
이미지 압축 파이프라인
빌드 타임 변환 (권장):
// npm install sharp
import sharp from 'sharp';
await sharp('input.jpg').avif({ quality: 50 }).toFile('output.avif');
await sharp('input.jpg').webp({ quality: 80 }).toFile('output.webp');
이미지 CDN 실시간 변환: Cloudflare Images, Imgix, Cloudinary 같은 이미지 CDN은 URL 파라미터만으로 리사이징과 포맷 변환을 처리합니다.
# 브라우저가 지원하는 최적 포맷(AVIF·WebP)으로 자동 변환
https://example.com/cdn-cgi/image/width=800,format=auto/images/photo.jpg
Responsive Images (반응형 이미지)
<img
srcset="image-400.webp 400w, image-800.webp 800w, image-1200.webp 1200w"
sizes="(max-width: 600px) 400px, (max-width: 900px) 800px, 1200px"
src="image-800.webp"
width="800" height="533"
alt="제품 사용 장면"
loading="lazy"
/>
브라우저가 화면 크기에 맞는 이미지를 골라 모바일에서 불필요하게 큰 파일을 받지 않습니다. 이 예시처럼 loading="lazy"는 화면 아래쪽 이미지에만 쓰고, LCP 이미지에는 fetchpriority="high"를 씁니다.
5.13 JavaScript 최적화
JavaScript는 메인 스레드를 점유해 렌더링과 상호작용(INP)을 늦추는 주요 원인입니다.
렌더링 차단 JS 제거
<!-- 나쁜 예시: <head>의 렌더링 차단 스크립트 -->
<script src="heavy-script.js"></script>
<!-- 좋은 예시: defer로 HTML 파싱 후 실행 -->
<script src="script.js" defer></script>
<!-- async: 다운로드 즉시 실행 (순서 무관한 독립 스크립트) -->
<script src="analytics.js" async></script>
코드 스플리팅 (Code Splitting)
React, Next.js, Vite 같은 프레임워크에서는 필요한 코드만 불러오도록 나눕니다.
// Next.js 동적 임포트 예시
import dynamic from 'next/dynamic';
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
loading: () => <p>로딩 중...</p>,
});
단, 검색·AI 크롤러가 읽어야 할 본문은 동적 임포트 뒤에 숨기지 말고 서버에서 렌더링하세요(5.8 참고).
불필요한 서드파티 스크립트 정리
태그 관리자, 채팅 위젯, A/B 테스트 도구 같은 서드파티 스크립트는 성능에 큰 영향을 줍니다. 쓰지 않는 스크립트는 제거하고, 필요한 것은 async·defer로 불러옵니다.
5.14 CSS 최적화
Critical CSS (인라인 CSS)
첫 화면(Above-the-fold)에 필요한 CSS를 HTML에 인라인으로 넣으면 외부 CSS를 기다리지 않고 바로 화면을 그릴 수 있습니다.
<head>
<!-- 크리티컬 CSS 인라인 -->
<style>
body { margin: 0; font-family: sans-serif; }
header { background: #333; color: white; padding: 1rem; }
</style>
<!-- 나머지 CSS는 비동기 로드 -->
<link rel="preload" href="main.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="main.css"></noscript>
</head>
미사용 CSS 제거
PurgeCSS 같은 도구나 Tailwind의 빌드 단계 최적화로 쓰지 않는 CSS 규칙을 제거하면 파일 크기를 크게 줄일 수 있습니다.
5-C. 서버 & 인프라 최적화
서버·인프라 최적화의 목표는 첫 바이트를 빨리 보내고(TTFB), 같은 파일을 반복해 보내지 않고(캐시), 전송량을 줄이는(압축) 것입니다.
5.15 Nginx 설정 최적화
Nginx는 가장 널리 쓰이는 웹 서버 중 하나로, 설정만으로도 속도를 크게 개선할 수 있습니다.
Gzip / Brotli 압축
HTML·
# http 또는 server 블록
# Gzip 설정 (text/html은 기본 포함)
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/json
application/xml
image/svg+xml;
# Brotli 설정 (ngx_brotli 모듈 설치 필요)
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css text/javascript application/javascript application/json image/svg+xml;
Brotli는 보통 Gzip보다 압축률이 높지만 Nginx 기본 빌드에는 포함되어 있지 않습니다. 브라우저가 Accept-Encoding 헤더로 지원 방식을 알리면 Nginx가 알맞은 방식을 고릅니다.
Keep-Alive 설정
TCP 연결을 재사용해 리소스마다 새 연결을 맺는 비용을 줄입니다. Nginx 1.19.10부터 keepalive_requests 기본값이 100에서 1000으로 올라갔으므로 (nginx 공식 문서, 2026년 9월 확인), 예전 글처럼 100으로 낮추지 마세요. keepalive_timeout 기본값은 75초입니다.
# 기본값을 쓰는 것이 무난합니다 (명시할 경우)
keepalive_timeout 75s;
keepalive_requests 1000;
정적 파일 캐싱
# 파일명에 해시가 들어간 정적 리소스(app.3f9a1c.js 등): 1년 + immutable
location ~* \.(?:css|js|woff2|avif|webp|png|jpe?g|gif|svg|ico)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
access_log off;
}
# HTML: 캐시하되 매번 재검증 (배포 즉시 반영)
location ~* \.html$ {
add_header Cache-Control "no-cache";
}
immutable은 내용이 바뀌면 파일명도 바뀌는(해시가 붙는) 리소스에만 씁니다. 또 Nginx에서 location에 add_header를 쓰면 상위 블록의 add_header(보안 헤더 등)가 상속되지 않습니다. 보안 헤더 스니펫을 각 location에도 include하거나, Nginx 1.29.3 이상이라면 add_header_inherit merge;로 상속 방식을 바꿀 수 있습니다 (nginx 공식 문서, 2026년 9월 확인).
Worker 프로세스
# CPU 코어 수에 맞게 자동 설정
worker_processes auto;
events {
worker_connections 1024; # worker당 최대 동시 연결 수
multi_accept on;
# 리눅스에서는 epoll이 자동 선택됩니다
}
5.16 PHP OPcache 설정 및 최적화
Laravel·
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=256 ; MB, 기본 128
opcache.interned_strings_buffer=16 ; MB, 기본 8
opcache.max_accelerated_files=20000 ; 프로젝트 PHP 파일 수보다 크게
opcache.validate_timestamps=0 ; 프로덕션: 파일 변경 감지 끔 (배포 시 리셋 필수)
opcache.save_comments=1
; opcache.fast_shutdown은 PHP 7.2에서 제거되었으므로 넣지 않습니다
; JIT는 PHP 8.4부터 기본 비활성화(opcache.jit=disable). 필요하면 측정 후 켭니다
; opcache.jit=tracing
; opcache.jit_buffer_size=64M
배포 시 OPcache 리셋 주의
validate_timestamps=0이면 PHP 파일을 바꿔도 바로 반영되지 않습니다. 이때 php -r "opcache_reset();"처럼 CLI에서 리셋하면 PHP-FPM이 쓰는 캐시는 지워지지 않습니다. CLI와 FPM은 캐시 메모리를 공유하지 않기 때문입니다. PHP-FPM을 reload하세요.
# 배포 스크립트 마지막에 PHP-FPM 재적재 (버전에 맞게)
sudo systemctl reload php8.3-fpm
5.17 Redis / Memcached 캐싱 전략
데이터베이스 쿼리 결과, 세션, 계산이 복잡한 데이터를 메모리에 캐시하면 응답 속도가 크게 빨라집니다.
Redis 활용 전략
// 데이터베이스 쿼리 결과 캐싱 (1시간)
$posts = Cache::remember('popular_posts', 3600, function () {
return Post::orderBy('views', 'desc')->take(10)->get();
});
// 세션을 Redis로 처리 (config/session.php)
// 'driver' => 'redis'
// 큐 작업도 Redis로 처리 (config/queue.php)
// 'default' => 'redis'
WordPress + Redis Object Cache
WordPress에서는 Redis Object Cache 플러그인으로 반복되는 데이터베이스 쿼리를 크게 줄일 수 있습니다.
define('WP_REDIS_HOST', '127.0.0.1');
define('WP_REDIS_PORT', 6379);
define('WP_REDIS_TIMEOUT', 1);
define('WP_REDIS_READ_TIMEOUT', 1);
define('WP_REDIS_DATABASE', 0);
5.18 Cloudflare CDN 설정 완전 가이드
Cloudflare는 CDN을 넘어 DNS, DDoS 방어, WAF, 성능 최적화를 한곳에서 제공하는 플랫폼으로, 무료 플랜만으로도 상당한 개선이 가능합니다. 다만 몇몇 설정은 2024~2025년에 바뀌었으니 예전 체크리스트를 그대로 따르지 마세요.
기본 설정 체크리스트
SSL/TLS:
- SSL/TLS → 암호화 모드: Full (strict)
- Always Use HTTPS 활성화
- HSTS 활성화 (max-age 최소 6개월, preload 신청은 5.24의 주의사항 확인 후)
- Minimum TLS Version: TLS 1.2 이상
캐싱:
- Caching Level: Standard, 정적 리소스 Browser Cache TTL은 길게
- Tiered Cache로 오리진 요청 줄이기
성능:
- Auto Minify는 2024년 8월 5일 폐지되었습니다. HTML·
CSS· JS 압축(minify)은 빌드 단계에서 합니다. - Brotli 설정 토글도 2024년 8월 폐지되었고, 비엔터프라이즈 존에서는 별도 설정 없이 Brotli 압축을 쓸 수 있습니다 (Cloudflare 문서, 2024).
- Rocket Loader: 사이트별로 테스트 후 사용 (자바스크립트 동작이 깨질 수 있음)
- HTTP/2는 자동 적용, HTTP/3(QUIC)는 대시보드에서 활성화
Page Rules 대신 Cache Rules
Cloudflare는 새로 설정할 때 Page Rules 대신 Cache Rules·
# 규칙 1: API·관리자 경로는 캐시 제외
(starts_with(http.request.uri.path, "/api/") or starts_with(http.request.uri.path, "/admin/"))
→ Cache eligibility: Bypass cache
# 규칙 2: 정적 리소스는 엣지에 1년 캐시
(starts_with(http.request.uri.path, "/static/"))
→ Cache eligibility: Eligible for cache / Edge TTL: 1 year
Workers를 활용한 SEO 작업
Cloudflare Workers는 엣지에서 실행되는 서버리스 함수입니다. 예전의 addEventListener('fetch') 방식(Service Worker 문법)은 지원은 되지만 폐지 예정(deprecated)이며, ES 모듈 형식이 권장됩니다 (Cloudflare 문서, 2026). 아래는 이전 URL을 엣지에서 301로 보내고, 스테이징 도메인에 noindex 헤더를 붙이는 예시입니다.
const REDIRECTS = new Map([
['/old-page/', '/new-page/'],
['/blog/seo-2024/', '/guide/part-05'],
]);
export default {
async fetch(request) {
const url = new URL(request.url);
// 1) 이전 URL은 엣지에서 바로 301
const to = REDIRECTS.get(url.pathname);
if (to) return Response.redirect(new URL(to, url.origin).toString(), 301);
// 2) 스테이징 도메인은 색인되지 않게
const response = await fetch(request);
if (url.hostname.startsWith('staging.')) {
const res = new Response(response.body, response);
res.headers.set('X-Robots-Tag', 'noindex');
return res;
}
return response;
},
};
예전 가이드에 흔하던 “봇에게만 미리 렌더링한 HTML을 주는” 동적 렌더링은 구글이 임시방편으로 규정한 방식입니다 (Google Search Central, 2025). 새로 만든다면 SSR·
5.19 TTFB(Time To First Byte) 단축 전략
TTFB는 요청을 보낸 뒤 첫 바이트를 받기까지의 시간으로, LCP에 직접 영향을 줍니다. web.dev는 대략적인 기준으로 대부분의 사이트가 0.8초 이하를 목표로 삼으라고 권하며, TTFB 자체는 Core Web Vitals 지표가 아니라고 설명합니다 (web.dev, 2025). HTML까지 CDN에 캐시하면 이보다 훨씬 짧게 만들 수 있습니다.
TTFB가 긴 주요 원인과 해결책
| 원인 | 해결책 |
|---|---|
| 물리적 거리 (서버가 멀리 있음) | CDN 활용, 사용자와 가까운 리전에 배포 |
| 느린 데이터베이스 쿼리 | 쿼리 최적화, 인덱스 추가, Redis 캐싱 |
| PHP·애플리케이션 처리 시간 | OPcache 활성화, 코드 최적화, 페이지 캐시 |
| 여러 번의 리다이렉트 | 최종 URL로 바로 연결 (http→https→www 체인 제거) |
| 연결 설정 지연 (DNS· | 응답이 빠른 관리형 DNS, TLS 1.3, HTTP/2· |
5.20 HTTP/2, HTTP/3(QUIC) 적용
HTTP/2의 장점
- 멀티플렉싱: 하나의 연결로 여러 리소스를 동시에 전송
- 헤더 압축: HPACK으로 반복 헤더 압축
- 서버 푸시는 쓰지 않습니다: 크롬은 버전 106부터 HTTP/2 서버 푸시를 기본 비활성화했고 (Chrome for Developers, 2022), Nginx도 1.25.1에서 관련 기능을 없앴습니다. 대신
preload나 103 Early Hints를 씁니다.
구글 크롤러는 HTTP/1.1과 HTTP/2를 지원하며, 문서에 HTTP/3 크롤링은 언급되어 있지 않습니다 (Google, 2026). HTTP/3는 크롤링이 아니라 사용자, 특히 손실이 많은 모바일 네트워크의 체감 속도를 위한 선택입니다.
# Nginx 1.25.1+ : listen의 http2 파라미터는 폐지 예정, http2 지시어 사용
server {
listen 443 ssl;
http2 on;
# ...
}
HTTP/3 (QUIC) 적용
HTTP/3는 TCP 대신 UDP 기반의 QUIC을 씁니다. Nginx의 HTTP/3 모듈은 1.25.0부터 제공되지만 실험적 기능이고 기본 빌드에 포함되지 않아 --with-http_v3_module로 빌드해야 합니다 (nginx 공식 문서, 2026년 9월 확인). 방화벽에서 UDP 443 포트도 열어야 합니다.
server {
# HTTP/3와 HTTPS는 같은 포트를 쓰는 것이 권장됩니다
listen 443 quic reuseport;
listen 443 ssl;
http2 on;
# ssl_certificate 등 인증서 설정은 5.22 참고
ssl_protocols TLSv1.2 TLSv1.3; # QUIC은 TLS 1.3 사용
# 브라우저에 HTTP/3 사용 가능을 알림
add_header Alt-Svc 'h3=":443"; ma=86400' always;
}
HTTP/3를 켰다면 Nginx를 최신 버전으로 유지하세요. 2026년 9월 15일 배포된 Nginx 1.31.6(안정 버전은 1.30.5)은 OpenSSL 3.5.0 이하와 HTTP/3를 함께 쓰는 특정 설정에서 발생할 수 있는 힙 버퍼 오버플로 취약점(CVE-2026-90439)을 고쳤습니다 (nginx CHANGES, 2026). Cloudflare를 쓴다면 대시보드에서 HTTP/3를 켜는 것만으로 방문자 구간에 적용됩니다.
5.21 서버 사이드 렌더링(SSR) vs 정적 사이트(SSG) SEO 비교
React·
| 방식 | 검색·AI 크롤러 적합성 | 속도 | 적합한 사이트 유형 |
|---|---|---|---|
| SSR (Server Side Rendering) | 매우 좋음 | 중간 | 동적 콘텐츠, 로그인 사이트 |
| SSG (Static Site Generation) | 매우 좋음 | 매우 빠름 | 블로그, 문서, 랜딩 페이지 |
| ISR (Incremental Static Regeneration) | 좋음 | 빠름 | 자주 업데이트되는 대용량 사이트 |
| CSR (Client Side Rendering, SPA) | 구글은 가능, AI 크롤러는 취약 | 초기 느림 | 로그인 후 내부 앱 |
| 동적 렌더링(봇 전용 프리렌더) | 임시방편 (비권장) | 빠름 | 기존 CSR 사이트의 과도기 |
Next.js, Nuxt, SvelteKit, Astro처럼 SSR과 SSG를 섞어 쓸 수 있는 프레임워크를 쓰면 검색 친화성과 성능을 함께 챙길 수 있습니다.
5-D. 보안 & 신뢰성
보안 설정의 SEO 목표는 모든 페이지를 HTTPS로 안정적으로 제공하고, 인증서 만료나 잘못된 차단으로 크롤링이 끊기지 않게 하는 것입니다. 구글은 페이지 경험 자가 점검 항목에 HTTPS 제공 여부를 포함합니다 (Google Search Central, 2026).
5.22 SSL/TLS 설정 — SSL Labs A+ 등급 달성
SSL Labs 등급은 TLS 설정 품질을 점검하는 좋은 지표입니다. 다만 구글이 SSL Labs 등급 자체를 순위에 쓴다는 공식 언급은 없으므로, 보안과 호환성을 위한 기준으로 활용하세요.
Nginx SSL 권장 설정
아래는 Mozilla의 서버 TLS 가이드라인 6.0(2026년 4월)의 ‘Intermediate’ 구성을 따른 예시입니다 (Mozilla, 2026).
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Mozilla Intermediate (가이드라인 6.0)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
# 세션 재사용
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
# HSTS 2년 (preload는 5.24 주의사항 확인 후 추가)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
# OCSP 스테이플링: Let's Encrypt는 2025년 OCSP를 종료했으므로 넣지 않습니다
}
예전 설정에 흔한 ssl_stapling on;은 Let's Encrypt 인증서에서는 더 이상 의미가 없습니다. Let's Encrypt는 2025년 5월 7일부터 인증서에서 OCSP 주소를 빼고, 8월 6일 OCSP 응답 서버를 종료했습니다 (Let's Encrypt, 2024). OCSP를 지원하는 다른 CA의 인증서를 쓸 때만 켭니다.
인증서 자동 갱신
# 인증서 발급 (Nginx 플러그인)
sudo certbot --nginx -d example.com -d www.example.com
# 대부분의 설치 패키지는 자동 갱신 타이머를 함께 설치합니다
systemctl list-timers | grep certbot
# 갱신에 성공했을 때만 Nginx 재적재 (deploy 훅)
echo 'systemctl reload nginx' | sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
# 갱신 과정 점검
sudo certbot renew --dry-run
--post-hook은 갱신 시도 때마다 실행되고, deploy 훅은 갱신에 성공했을 때만 실행됩니다 (Certbot 문서, 2026년 9월 확인).
2026년 9월 업데이트: 인증서 수명이 짧아집니다
CA/브라우저 포럼은 2025년 4월 공인 TLS 인증서의 최대 유효기간을 2026년 3월부터 단계적으로 줄여 2029년 3월까지 47일로 낮추는 안(SC-081v3)을 채택했습니다 (CA/Browser Forum, 2025). Let's Encrypt도 2026년 5월 13일 선택형 45일 인증서를 시작했고, 기본 인증서를 2027년 2월 64일, 2028년 2월 45일로 줄일 예정입니다 (Let's Encrypt, 2025). 수동 갱신은 더 이상 현실적이지 않습니다. 자동 갱신과 실패 알림을 반드시 설정하세요.
5.23 HTTPS 마이그레이션 체크리스트
HTTP에서 HTTPS로 옮길 때 검색 노출 손실을 막기 위한 체크리스트입니다. 도메인 이전을 포함한 전체 절차는 사이트 이전 SEO 가이드와 PART 11의 마이그레이션 체크리스트를 참고하세요.
- SSL 인증서 발급·설치와 자동 갱신 설정
- HTTP → HTTPS 301 리다이렉트 (체인 없이 최종 URL로 한 번에)
- 내부 링크, 이미지, CSS, JS URL을 HTTPS로 변경
- canonical, hreflang, 구조화 데이터의 URL을 HTTPS로 변경
robots.txt,sitemap.xml의 URL을 HTTPS로 변경- 서치 콘솔은 도메인 속성으로 등록해 http·
https와 www 변형을 함께 확인 - GA4 데이터 스트림 URL, 광고·외부 서비스의 연결 URL 변경
- 혼합 콘텐츠(Mixed Content) 오류 해결
- 중요한 외부 백링크는 HTTPS URL로 수정 요청
5.24 보안 헤더 설정
보안 헤더는 브라우저가 특정 보안 정책을 따르도록 지시합니다. securityheaders.com에서 현재 설정을 확인할 수 있습니다.
# 구형 XSS 필터는 끕니다 (폐지된 헤더, CSP로 대체)
add_header X-XSS-Protection "0" always;
# MIME 타입 스니핑 방지
add_header X-Content-Type-Options "nosniff" always;
# 클릭재킹 방지 (CSP frame-ancestors와 함께 사용 가능)
add_header X-Frame-Options "SAMEORIGIN" always;
# 참조자 정책
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 권한 정책 (불필요한 기능 비활성화)
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# Content Security Policy (사이트에 맞게 조정 필요, 'unsafe-inline'은 가능하면 nonce로 대체)
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com; img-src 'self' data: https:; frame-ancestors 'self'" always;
MDN은 X-XSS-Protection을 폐지된 비표준 헤더로 분류하며, 오히려 XSS 취약점을 만들 수 있으니 CSP를 쓰라고 권장합니다 (MDN, 2026년 9월 확인). CSP는 처음부터 차단 모드로 걸면 분석·광고 스크립트가 멈출 수 있으니 Content-Security-Policy-Report-Only로 먼저 점검하세요.
HSTS preload는 신중하게
HSTS preload 목록에 등록하려면 max-age 1년 이상, includeSubDomains, preload가 모두 필요하고, 모든 하위 도메인이 HTTPS를 지원해야 합니다. 목록에서 빼는 데 몇 달이 걸리므로 모든 하위 도메인을 장기적으로 HTTPS로 운영할 수 있을 때만 신청하세요 (hstspreload.org, 2026년 9월 확인).
5.25 Cloudflare WAF & 봇 관리
Cloudflare WAF(웹 애플리케이션 방화벽)는 SQL 인젝션, XSS 같은 공격을 자동으로 차단합니다.
- Security → WAF → Managed rules에서 플랜에 따라 제공되는 관리형 규칙(Cloudflare Managed Ruleset, OWASP Core Ruleset) 활성화
- 로그인·검색·API처럼 남용되기 쉬운 경로에 Rate Limiting 규칙 설정
봇 관리와 검색 크롤러
악성 봇은 서버 자원을 낭비하지만, 봇 차단 설정이 검색·AI 크롤러까지 막으면 곧바로 노출 손실로 이어집니다. 무료 플랜의 Bot Fight Mode는 WAF 사용자 정의 규칙으로 예외를 둘 수 없으므로, 예외가 필요하면 Super Bot Fight Mode나 별도 규칙을 써야 합니다 (Cloudflare 문서, 2026). 봇 설정을 바꾼 뒤에는 보안 이벤트 로그에서 Googlebot, Bingbot, 네이버 Yeti, OAI-SearchBot, PerplexityBot 요청이 챌린지·차단되고 있지 않은지 확인하세요. AI 크롤러 관련 설정은 5.2를 참고하세요.
5-E. 모바일 & 구조
모바일 대응의 핵심은 구글이 모바일 버전을 기준으로 색인한다는 사실입니다. 모바일에서 빠진 콘텐츠는 검색에서도 없는 콘텐츠가 됩니다.
5.26 Mobile-First Indexing 대응
구글은 2023년 10월 모바일 우선 색인 전환이 사실상 완료되었다고 발표했습니다 (Google Search Central Blog, 2023). 현재 대부분의 사이트는 모바일 버전으로 색인되며, 구글봇 크롤링 요청도 스마트폰 크롤러가 더 많습니다 (Google Search Central, 2026).
Mobile-First Indexing 대응 체크리스트:
- 모바일에서도 데스크톱과 같은 본문·이미지·동영상이 표시되는지 확인
- 탭·아코디언에 넣은 모바일 콘텐츠도 HTML에 있으면 색인된다는 점을 인지
- 구조화 데이터, 메타 태그, canonical·
hreflang이 모바일 버전에도 동일하게 있는지 확인 - 모바일 Core Web Vitals(LCP, INP, CLS)가 기준을 충족하는지 확인
- 모바일 HTML이 2MB를 넘지 않는지 확인 (5.2 업데이트 참고)
5.27 반응형 디자인 SEO 체크리스트
반응형 디자인은 하나의 HTML로 모든 기기에 대응하는 방식으로, 운영과 색인 모두에서 가장 관리하기 쉬운 구성입니다.
<!-- 반응형 디자인 필수 메타 태그 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
모바일 SEO 체크포인트:
- 본문 글자 크기: 16px 안팎으로 확대 없이 읽을 수 있게
- 터치 대상(버튼·링크): WCAG 2.2 AA 기준 최소 24×24 CSS 픽셀, 주요 버튼은 44×44 픽셀 이상 권장 (W3C, 2023)
- 가로 스크롤 없음
- 본문을 가리는 전면 팝업(인터스티셜) 지양. 구글의 페이지 경험 점검 항목에 포함됩니다 (Google Search Central, 2026).
5.28 AMP — 현재 유효성 재검토
AMP(Accelerated Mobile Pages)는 순위 혜택을 주는 기술이 아닙니다. 구글은 AMP 페이지도 다른 웹페이지와 같은 기준으로 색인하며, 2026년 7월 1일부터는 AMP 캐시를 거치지 않고 사용자를 게시자의 AMP 페이지로 바로 보냅니다. 게시자는 AMP 캐시 갱신이나 Signed Exchange 설정을 더 이상 신경 쓰지 않아도 됩니다 (Google Search Central, 2026).
- AMP 자체는 순위에 영향을 주지 않습니다.
- Core Web Vitals를 충족하면 AMP 없이도 같은 효과를 얻을 수 있습니다.
- 기존 AMP 페이지는 유지해도 되지만, 신규 도입은 권장하지 않습니다.
PART 5 요약 및 독자별 체크리스트
핵심 정리
- robots.txt(RFC 9309)는 크롤링을,
noindex는 색인을 제어합니다. 크롤 버짓 절약에noindex를 쓰지 마세요. - 검색·AI 검색용 크롤러(Googlebot, Bingbot, OAI-SearchBot, Claude-SearchBot, PerplexityBot, Yeti)는 막지 말고, 학습용 크롤러는 정책에 따라 정합니다.
- Core Web Vitals 목표는 LCP 2.5초, INP 200ms, CLS 0.1 이하(75백분위)입니다.
- 핵심 콘텐츠는 SSR·
SSG로 초기 HTML에 넣고, HTML은 2MB 안에서 가볍게 유지합니다. - Nginx
http2 on;, OPcache 리셋은 FPM reload, OCSP 스테이플링 제거, 인증서 자동 갱신이 2026년 서버 설정의 기본입니다. - Cloudflare는 Auto Minify 폐지, Cache Rules 권장, AI 크롤러 기본 차단 여부를 확인합니다.
👶 입문자 체크리스트
- 사이트 전체가 HTTPS로 열리고, http 주소는 https로 301 이동하나요?
- 서치 콘솔의 페이지 색인 생성 보고서에서 오류를 확인해 보셨나요?
- PageSpeed Insights에서 현장 데이터(실제 사용자) 기준 Core Web Vitals를 확인해 보셨나요?
- 모바일에서 사이트가 제대로 표시되는지 확인했나요?
🧑💼 중급 마케터 체크리스트
- 서치 콘솔 Core Web Vitals 보고서에서 “나쁨” URL 그룹을 파악했나요?
- 사이트맵에 noindex·리다이렉트 URL이 섞여 있지 않고,
lastmod가 실제 수정일인가요? - 내부 링크가 하나도 없는 고아 페이지(Orphan Page)를 파악했나요?
- robots.txt와 Cloudflare 설정이 검색·AI 검색용 크롤러를 막고 있지 않은지 확인했나요?
👨💻 개발자 체크리스트
- Nginx에 Gzip/Brotli 압축과
http2 on;이 적용되어 있나요? - OPcache가 켜져 있고, 배포 때 CLI가 아닌 PHP-FPM reload로 캐시를 비우나요?
- TLS 설정이 Mozilla Intermediate 기준이고, Let's Encrypt 인증서에 불필요한 OCSP 스테이플링이 남아 있지 않나요?
- 보안 헤더에서
X-XSS-Protection을 “0”으로 바꾸고 CSP를 점검했나요? - LCP 이미지에
fetchpriority="high"가 있고loading="lazy"는 없나요? - 핵심 콘텐츠가 자바스크립트 실행 없이 초기 HTML에 있나요?
🏢 에이전시/전문가 체크리스트
- 클라이언트 사이트의 기술 SEO 감사 절차에 AI 크롤러 접근 점검이 포함되어 있나요?
- Core Web Vitals 현장 데이터 개선 로드맵이 클라이언트별로 있나요?
- 서버 환경(공유 호스팅, VPS, 클라우드, CDN)별 최적화 전략이 구분되어 있나요?
- 배포 파이프라인에 Lighthouse 자동 점검과 인증서 만료 알림이 포함되어 있나요?
진단부터 구축·수정까지 개발팀이 직접 맡기를 원한다면 테크니컬 SEO·웹 개발 서비스를 참고하세요.
자주 묻는 질문
robots.txt로 막으면 구글 검색에서 사라지나요?
아닙니다. robots.txt는 크롤링만 막기 때문에, 다른 사이트에서 링크된 URL은 설명 없이 색인될 수 있습니다. 검색에서 빼려면 noindex 메타 태그나 X-Robots-Tag 헤더를 쓰고, 크롤러가 그 태그를 읽을 수 있도록 해당 URL은 robots.txt로 막지 않아야 합니다.
2026년에도 INP 기준은 200ms인가요?
네. 2026년 9월 기준 INP는 200ms 이하가 좋음, 500ms 초과가 나쁨이며, 방문의 75번째 백분위로 판단합니다. INP는 2024년 3월 12일 FID를 대체해 Core Web Vitals가 되었습니다.
AI 크롤러는 막아야 하나요, 열어야 하나요?
AI 답변에 인용되고 싶다면 OAI-SearchBot, Claude-SearchBot, PerplexityBot 같은 검색용 크롤러는 열어 두고, GPTBot·
IndexNow를 쓰면 구글 색인도 빨라지나요?
아닙니다. 2026년 9월 기준 IndexNow에는 빙, 네이버, 얀덱스, 세즈남 등이 참여하지만 구글은 참여하지 않습니다. 구글에는 정확한 lastmod가 담긴 사이트맵과 서치 콘솔 URL 검사로 알리세요.
HTTP/3를 켜면 SEO에 도움이 되나요?
순위에 직접 도움이 된다는 근거는 없습니다. 구글 크롤러 문서는 HTTP/1.1과 HTTP/2만 명시하므로, HTTP/3는 모바일 사용자의 체감 속도를 높이는 선택으로 보는 것이 맞습니다. 켰다면 Nginx를 최신 보안 버전으로 유지하세요.
React로 만든 SPA도 구글에 색인되나요?
구글은 자바스크립트를 렌더링하므로 색인될 수 있지만, 200이 아닌 페이지는 렌더링을 건너뛸 수 있고 초기 HTML의 noindex는 자바스크립트로 지워지지 않을 수 있습니다. 주요 AI 크롤러는 자바스크립트를 실행하지 않으므로, 검색과 AI 노출이 중요한 페이지는 SSR이나 SSG로 만드는 것이 안전합니다.
참고 자료
- RFC 9309: Robots Exclusion Protocol — IETF, 2022-09
- How Google interprets the robots.txt specification — Google, 2026-08-31
- Introduction to robots.txt — Google Search Central, 2025-12-10
- Overview of Google crawlers and fetchers — Google, 2026-06-12
- Googlebot — Google Search Central, 2026-02-03
- Google's common crawlers (Google-Extended) — Google, 2026-07-14
- Google's user-triggered fetchers (Google-Agent) — Google, 2026-08-19
- Optimize your crawl budget — Google, 2026-07-22
- Managing crawling of faceted navigation URLs — Google, 2025-12-18
- How HTTP status codes affect Google's crawlers — Google, 2026-02-04
- Build and submit a sitemap — Google Search Central, 2026-07-08
- Sitemaps ping endpoint is going away — Google Search Central Blog, 2023-06
- Redirects and Google Search — Google Search Central, 2026-04-14
- Pagination, incremental page loading, and their impact on Google Search — Google Search Central, 2025-12-10
- Understand JavaScript SEO basics — Google Search Central, 2026-03-04
- Dynamic rendering as a workaround — Google Search Central, 2025-12-10
- Understanding page experience in Google Search results — Google Search Central, 2026-09-22
- Mobile-first indexing has landed — Google Search Central Blog, 2023-10
- About AMP on Google Search — Google Search Central, 2026-07-01
- Latest Google Search Documentation Updates (AVIF 지원 등) — Google Search Central, 2024-08~2026-09
- Web Vitals — web.dev, 2024-10-31
- Interaction to Next Paint becomes a Core Web Vital on March 12 — web.dev, 2024-01-31
- Interaction to Next Paint (INP) — web.dev, 2025-09-02
- Time to First Byte (TTFB) — web.dev, 2025-11-18
- Optimize resource loading with the Fetch Priority API — web.dev, 2023-11-14
- The performance effects of too much lazy loading — web.dev, 2022-03-31
- About PageSpeed Insights — Google for Developers, 2024-10-21
- Web Almanac 2025: Page Weight — HTTP Archive, 2026-01-15
- IndexNow FAQ · 참여 검색엔진 목록(searchengines.json) — IndexNow.org, 2026-09 확인
- Introducing AI Performance in Bing Webmaster Tools — Bing Webmaster Blog, 2026-02
- Overview of OpenAI Crawlers — OpenAI, 2026-09 확인
- Does Anthropic crawl data from the web…? — Anthropic, 2026-04-07
- Perplexity Crawlers — Perplexity, 2026-09 확인
- The rise of the AI crawler — Vercel, 2024-12-17
- Content Independence Day — Cloudflare, 2025-07-01
- Managed robots.txt — Cloudflare 문서, 2026-09 확인
- API deprecations (Auto Minify·
Brotli) — Cloudflare 문서, 2024-08 - Page Rules migration guide — Cloudflare 문서, 2026-09 확인
- Migrate from Service Workers to ES Modules — Cloudflare 문서, 2026-07-03
- Bot Fight Mode — Cloudflare 문서, 2026-09 확인
- Module ngx_http_v2_module · ngx_http_v3_module · core·
headers 모듈 — nginx 공식 문서, 2026-09 확인 - Changes with nginx 1.31.6 · nginx security advisories — nginx.org, 2026-09-15
- Remove HTTP/2 Server Push from Chrome — Chrome for Developers, 2022-08-18
- OPcache runtime configuration · opcache_reset — PHP 매뉴얼, 2026-09 확인
- Mozilla Server Side TLS guidelines 6.0 — Mozilla, 2026-04-06
- Ending OCSP Support in 2025 — Let's Encrypt, 2024-12-05
- Decreasing Certificate Lifetimes to 45 Days — Let's Encrypt, 2025-12-02
- Ballot SC-081v3: Introduce schedule of reducing validity and data reuse periods — CA/Browser Forum, 2025-04-11
- User Guide (Renewing certificates) — Certbot 문서, 2026-09 확인
- X-XSS-Protection — MDN, 2026-09 확인
- HSTS Preload List Submission — hstspreload.org, 2026-09 확인
- Understanding SC 2.5.8: Target Size (Minimum) — W3C, 2023