웹 페이지 로딩 과정은 검색 최적화(SEO)의 핵심 요소입니다. 이 글은 DNS 조회부터 DOM 생성, 렌더링 트리를 거쳐 최종적으로 화면에 표시되는 웹페이지 로딩 단계, 각 단계에서 웹 성능을 최적화하기 위해 운영자가 적용할 수 있는 구체적인 방법(dns-prefetch, preconnect, CSS 및 JavaScript 최적화)을 제공합니다. 이는 Core Web Vitals(LCP, INP, CLS) 지표 개선에 필수적인 정보입니다.
검색 최적화 향상을 위한 웹 페이지 로딩 단계 분석 및 병목 현상
웹 페이지 로딩 과정은 검색 최적화에 중요한 요소 중 하나입니다. 웹 페이지 로딩은 DNS 조회로 IP 주소를 얻고, TCP를 통해 서버와 연결을 하게됩니다. HTTP 요청을 통해 서버에서 HTML과 CSS를 받아 DOM 및 렌더링 트리를 생성합니다. 생성된 트리에 CSS로 스타일을 적용하고 JavaScript를 실행하여 동적 콘텐츠를 추가합니다. 이후 레이아웃을 계산하고, 페인팅 및 컴포지팅을 통해 최종적으로 화면에 페이지를 표시하게 됩니다.
검색엔진 최적화 작업을 위해서는 웹 페이지가 어떤 방식으로 로딩이 되는지 웹페이지 로딩 단계의 기본적인 이해가 있으면 작업하기가 수월해집니다. 각 단계별로 운영자가 최적화 작업에서 진행할 수 있는 부분과 할 수 없는 부분을 알고 할 수 있는 부분에 대한 작업을 진행해야 하며 웹페이지 로딩 시 그 작업은 각 단계의 일부분에 한정될 수 있습니다.
검색엔진 최적화 후 다른 요소로 인해 발생하는 문제도 차후 점검 후 파악해야 하며 그 부분이 웹페이지의 어떤 과정에서 발생하는지는 대략적으로 파악할 필요성이 있어 아래는 웹페이지 로딩의 단계별 설명을 간단하게 요약 정리했습니다.
웹페이지 로딩 순서와 Core Web Vitals 최적화
1. DNS 조회 (DNS Lookup) 및 리소스 사전 연결 (TTFB 개선)
DNS 조회는 사용자가 웹사이트 주소를 입력하면 브라우저는 도메인 이름을 IP 주소로 변환하는 과정입니다. 일반적으로 사람들이 사용하기 편리한 사이트 이름을 컴퓨터가 이해할 수 있는 숫자로 변경해주는 작업입니다. DNS(Domain Name System)로 서버에 요청을 보내면 DNS 서버는 도메인 이름에 해당하는 IP 주소를 반환합니다. 이때 캐시를 이용해서 캐시 정보가 브라우저에 존재하면 DNS 조회 과정을 생략할 수 있습니다.
페이지에서 외부의 여러 개의 다른 사이트 정보를 가져올 때 이 과정에서 로딩 시 부하가 걸릴 수 있기 때문에 페이지에 많이 사용하는 정보를 가져오는 사이트에 대해서 미리 연결할 준비를 해주면 좀 더 빠르게 외부 리소스를 로딩시킬 수 있습니다.
dns-prefetch는 브라우저가 도메인 이름을 미리 DNS 조회하여 IP 주소를 캐시하도록 설정합니다.
preconnect는 브라우저가 외부 도메인에 대한 연결을 미리 설정하도록 지시합니다.
✔ 예시 (외부 리소스 사전 연결을 통한 최적화)
link rel="preconnect" href="https://fonts.googleapis.com"
link rel="dns-prefetch" href="https://fonts.gstatic.com"
이 기법은 TTFB(Time To First Byte)를 줄여 LCP(Largest Contentful Paint) 시간을 개선하는 데 효과적이며, 특히 구글 폰트나 외부 CDN 등 로딩이 필요한 리소스에 사용됩니다.
2. 서버와 연결 (TCP Handshake) 및 3. HTTP 요청 / 4. 서버 응답
브라우저는 DNS 조회를 통해 얻은 IP 주소를 사용하여 웹 서버와 TCP 연결을 설정합니다. 이때 데이터의 전송 속도, 패킷의 손실이나 오류 발송 등의 제어를 하게 됩니다. 연결 후 HTTP 요청을 서버에 보내고, 서버는 요청을 처리하고 HTML 코드, 상태 코드, 헤더 정보 등을 포함한 응답을 보냅니다. 이 초기 연결 및 응답 단계는 TTFB에 직접적인 영향을 미치며, TTFB가 빠를수록 전체 로딩 성능이 향상됩니다. 서버 측 최적화(CDN, 캐싱, 서버 응답 시간 단축)가 필수적입니다.
5. HTML 파싱 및 DOM 트리 생성 (DOM)
브라우저는 HTML 코드를 읽고 분석하여 DOM(Document Object Model) 트리를 생성합니다. DOM 트리는 HTML 문서의 구조를 표현하며, 이 과정에서 외부 리소스(CSS, JavaScript)를 발견하면 로드를 요청합니다. 이 파싱 과정에서 렌더링 차단 리소스(Render Blocking Resource)가 발견되면 파싱이 일시 중단될 수 있습니다.
6. CSS 처리 및 CSSOM 생성
구조가 형성되면 CSS 파일을 읽어 들여서 HTML 문서의 스타일을 정의하게 됩니다. 브라우저는 CSS를 파싱하여 CSSOM(CSS Object Model) 트리를 생성합니다. CSS는 렌더링 차단 리소스(Rendering Blocking Resource)이므로, 작은 핵심 CSS는 HTML 파일 내에 인라인으로 삽입하고(Critical CSS), 나머지 CSS는 비동기 로딩을 적용하여 FCP(First Contentful Paint)를 개선해야 합니다.
7. JavaScript 실행 및 상호작용성 최적화
브라우저는 HTML 문서에 포함된 JavaScript를 파싱하고 실행합니다. JavaScript는 DOM과 CSSOM을 수정할 수 있으며, 이로 인해 페이지의 내용이나 스타일이 동적으로 변경될 수 있습니다. JavaScript 실행은 메인 스레드를 차지하여 사용자 입력에 대한 페이지의 반응을 지연시킬 수 있습니다. 이는 INP(Interaction to Next Paint)와 TBT(Total Blocking Time)에 직접적인 영향을 미칩니다. 불필요한 스크립트는 defer나 async 속성을 사용하여 비동기적으로 로딩하고, 코드를 최소화(Minify)하여 실행 시간을 단축해야 합니다.
8. 렌더링 트리 구성 (Render Tree Creation) 및 9. 레이아웃 계산 (Reflow)
브라우저는 DOM과 CSSOM을 결합하여 렌더링 트리를 생성합니다. 렌더링 트리는 화면에 실제로 그려질 요소의 정보만을 포함합니다. 이후 브라우저는 렌더링 트리를 기반으로 각 요소의 정확한 위치와 크기를 계산합니다. 이 과정을 레이아웃 또는 리플로우라고 합니다.
검색 최적화에서 가장 중요한 CLS 측정값이 이 부분에서 가장 많은 문제를 일으키게 됩니다. 예기치 않은 레이아웃 변경을 최소화하기 위해 이미지에 width와 height를 명시하거나, 광고 영역에 공간을 미리 확보해야 CLS(Cumulative Layout Shift)를 방지할 수 있습니다.
블록 요소: 기본적으로 전체 너비를 차지하며, 줄바꿈을 발생시킵니다.
인라인 요소: 기본적으로 콘텐츠의 너비에 맞추어 배치되며, 줄바꿈을 발생시키지 않습니다.
9. 페인팅 (Painting) 및 11. 컴포지팅 (Compositing)
브라우저는 각 요소를 화면에 그립니다. 이 과정에서는 색상, 텍스트, 이미지 등이 실제로 렌더링됩니다. 컴포지팅은 각각의 렌더링된 요소를 결합하여 최종적으로 화면에 표시하는 과정입니다. 복잡한 레이아웃의 경우, 브라우저는 여러 레이어로 구성된 페이지를 이때 처리하며. 각 레이어는 독립적으로 렌더링되며, 최종적으로 화면에 표시되기 전에 합쳐집니다.
10. 페이지 로딩 완료 (Load Event)
모든 리소스가 로드되고, JavaScript가 실행되고, 페이지가 렌더링되면서 브라우저에 페이지의 로딩이 완료되는 시점입니다.
Core Web Vitals 지표와 로딩 단계별 연관성 정리
Google이 정의한 Core Web Vitals는 사용자 경험을 측정하는 핵심 지표이며, 웹페이지 로딩의 각 단계와 밀접하게 관련되어 있습니다. 아래는 주요 지표와 최적화가 필요한 로딩 단계를 정리한 표입니다.
| Core Web Vital 지표 | 측정 내용 | 양호 기준 | 주요 관련 로딩 단계 | 핵심 최적화 전략 |
|---|---|---|---|---|
| LCP (Largest Contentful Paint) |
로딩 성능 (가장 큰 콘텐츠 표시 시간) | 2.5초 이내 | 1~6단계 (특히, 서버 응답, 이미지 로딩, CSS 차단) | TTFB 단축, Critical CSS 인라인, 리소스 사전 로딩 |
| INP (Interaction to Next Paint) |
상호작용 및 반응성 (사용자 입력 후 화면 반응까지의 지연 시간) | 200ms 미만 | 7단계 (JavaScript 실행) | JavaScript 최소화/분할, 메인 스레드 점유 시간 단축 |
| CLS (Cumulative Layout Shift) |
시각적 안정성 (예기치 않은 레이아웃 이동) | 0.1 미만 | 9단계 (레이아웃 계산) | 이미지/광고 영역 크기 명시, 웹 폰트 로딩 제어 |
Q: Critical CSS를 인라인으로 처리하는 것이 정말 속도 개선에 도움이 되나요?
A: 네, 매우 효과적입니다. Critical CSS는 첫 화면을 렌더링하는 데 필요한 최소한의 CSS입니다. 이 CSS를 HTML 파일 내에 인라인으로 삽입하면, 브라우저가 외부 CSS 파일을 요청하고 다운로드하는 시간을 절약하여 CSSOM 생성 시간을 단축하고 FCP(First Contentful Paint)를 빠르게 개선할 수 있습니다.
Q: defer와 async 속성은 JavaScript 로딩에 어떻게 다른 영향을 미치나요?
A: 두 속성 모두 JavaScript를 비동기적으로 다운로드하여 HTML 파싱 차단을 방지합니다. async는 다운로드가 완료되는 즉시 실행되므로 실행 순서가 보장되지 않지만, defer는 다운로드가 완료된 후 HTML 파싱이 끝나는 시점(DOM 생성 완료 직전)에 문서 순서대로 실행되어 실행 순서가 보장됩니다. 보통 다른 스크립트에 의존하지 않는 스크립트에는 async를, DOM에 의존하거나 순서가 필요한 스크립트에는 defer를 사용합니다.
Q: 웹페이지 로딩 단계 중 CLS에 가장 큰 영향을 미치는 단계는 무엇이며, 어떻게 방지해야 하나요?
A: CLS(Cumulative Layout Shift)에 가장 큰 영향을 미치는 단계는 9. 레이아웃 계산과 7. JavaScript 실행입니다. 특히, 로딩된 리소스(이미지, 광고, 폰트)가 공간을 확보하지 못한 채 뒤늦게 나타나 레이아웃을 밀어내는 경우가 많습니다. 방지책으로는 이미지/광고 영역에 width/height를 명시하여 공간을 미리 확보하고, 웹 폰트 로딩 시 font-display: swap을 사용하여 CLS 발생을 최소화해야 합니다.