CLS (Cumulative Layout Shift)
최종 업데이트:
정의
CLS(Cumulative Layout Shift)는 페이지 로딩 과정에서 발생하는 예상치 못한 레이아웃 변동(Layout Shift)의 누적 점수다. 사용자가 페이지를 보고 있는 동안 콘텐츠 위치가 갑자기 이동하는 현상을 정량화한다.
Google Core Web Vitals의 세 가지 지표 중 하나로, 시각적 안정성(Visual Stability)을 측정한다. 자세히는 Core Web Vitals 항목 참조.
요약
CLS 기준: 0.1 이하 = 좋음 / 0.1–0.25 = 개선 필요 / 0.25 초과 = 나쁨. 이미지에 HTML width/height 속성만 추가해도 CLS의 절반 이상이 해결되는 경우가 많다. 광고 영역 공간 예약과 웹폰트 font-display: swap 적용이 나머지 주요 개선 포인트다.
CLS 점수 계산 방식
CLS 점수는 단순히 발생 횟수가 아닌, 각 시프트의 영향력을 계산한 값이다.
공식
각 레이아웃 시프트 점수 = 영향 분율(Impact Fraction) × 거리 분율(Distance Fraction)
영향 분율(Impact Fraction): 이동 전후 요소가 차지한 화면 영역의 합 비율
거리 분율(Distance Fraction): 요소가 이동한 최대 거리 / 화면 크기
누적 방식
모든 레이아웃 시프트의 점수를 더한 값이 CLS다. 단, 2021년 업데이트에서 연속적이지 않은 시프트 세션(1초 이상 간격)을 별도 세션으로 계산해 최댓값을 취하는 방식으로 변경됐다. 스크롤 중 발생하는 긴 세션 전체 누적이 과도하게 불리했던 문제를 해결한 것이다.
CLS 권장 기준 (Google)
[COMPARISON_TABLE: CLS 점수별 평가]
| 등급 | CLS 점수 |
|---|---|
| 좋음 (Good) | 0.1 이하 |
| 개선 필요 (Needs Improvement) | 0.1 – 0.25 |
| 나쁨 (Poor) | 0.25 초과 |
Core Web Vitals 통과 조건: 75번째 퍼센타일 사용자의 CLS가 0.1 이하여야 한다. 즉 전체 방문자의 75%가 0.1 이하를 경험해야 "통과"가 된다.
CLS가 발생하는 5가지 주요 원인
원인 1: 이미지·비디오에 크기 미지정
가장 흔한 원인. HTML width와 height 속성이 없으면 브라우저가 이미지 로딩 전까지 공간을 예약하지 못해, 이미지가 로드되면서 기존 콘텐츠를 아래로 밀어낸다.
<!-- 나쁨: 크기 미지정 -->
<img src="hero.jpg" alt="..." />
<!-- 좋음: 크기 명시 -->
<img src="hero.jpg" width="1200" height="630" alt="..." />
CSS로 aspect-ratio를 지정하는 방법도 효과적이다.
img {
aspect-ratio: 16 / 9;
width: 100%;
}
원인 2: 동적 콘텐츠 삽입 (광고, 임베드, iframe)
광고 네트워크나 써드파티 콘텐츠가 비동기로 로드되어 기존 콘텐츠를 밀어내는 현상이다. 해결책: 광고 영역에 min-height로 공간을 미리 예약한다.
.ad-slot {
min-height: 250px; /* 예상 광고 크기 */
}
원인 3: 웹 폰트 지연 로딩 (FOIT/FOUT)
시스템 폰트에서 웹 폰트로 전환될 때 텍스트 크기가 바뀌며 레이아웃이 변동한다.
- FOIT (Flash of Invisible Text): 폰트 로딩 중 텍스트 안 보임
- FOUT (Flash of Unstyled Text): 폰트 로딩 전 시스템 폰트 표시 후 교체
해결책:
@font-face {
font-display: optional; /* 또는 swap */
}
font-display: optional은 폰트가 즉시 로드되지 않으면 시스템 폰트를 계속 사용해 시프트를 없앤다.
원인 4: 화면 상단에 동적 요소 삽입
쿠키 동의 배너, 앱 설치 안내 배너, 알림 바 등이 페이지 상단에 나타나면 아래 모든 콘텐츠가 밀린다. 처음부터 공간을 확보하거나 화면 고정(position: fixed) 방식으로 처리한다.
원인 5: 비동기 JavaScript 콘텐츠 삽입
JS로 늦게 렌더링되는 요소가 기존 요소를 밀어내는 경우. 자세히는 JavaScript SEO 항목 참조.
CLS 개선 7가지 방법
1. 모든 이미지에 width/height 지정
현대 CSS는 HTML width/height 속성을 aspect-ratio로 자동 변환해 반응형 이미지에서도 공간을 예약한다.
2. 광고·임베드 공간 사전 예약
.ad-container {
min-height: 90px; /* 배너 광고 표준 높이 */
display: flex;
align-items: center;
}
3. 웹 폰트 최적화
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin />
폰트 프리로드와 font-display: optional 또는 swap 조합으로 FOUT를 최소화한다.
4. 동적 콘텐츠는 사용자 액션 후
콘텐츠를 자동으로 삽입하는 대신 버튼 클릭, 스크롤 트리거 등 사용자 액션 후에 나타나도록 설계한다. 사용자 액션에 의한 레이아웃 변동은 CLS에 포함되지 않는다.
5. CSS transform 활용
요소를 이동할 때 top, left, margin 대신 transform: translate()를 사용한다. transform은 레이아웃 레이어가 아닌 별도 레이어에서 처리되므로 CLS를 유발하지 않는다.
6. contain 속성 활용
.ad-slot {
contain: layout;
}
CSS contain: layout은 요소 내부의 변화가 외부 레이아웃에 영향을 주지 않도록 격리한다.
7. Chrome DevTools로 시프트 원인 진단
Chrome DevTools → Performance 탭 → 레코딩 시작 → 페이지 로드 → Layout Shift 이벤트 확인. 어떤 요소가 시프트를 일으키는지 시각적으로 확인할 수 있다.
CLS 측정 도구
PageSpeed Insights
pagespeed.web.dev에서 URL 입력 시 CrUX 기반 실제 사용자 CLS와 실험실 CLS를 모두 제공한다. CrUX 데이터는 최소 28일 이상의 실제 사용자 데이터다.
Google Search Console (GSC)
GSC → 경험 → Core Web Vitals 보고서에서 사이트 전체 CLS 현황을 URL 단위로 확인한다. "나쁨" 또는 "개선 필요" 상태의 URL을 우선 처리한다. 자세히는 구글 서치 콘솔 항목 참조.
Web Vitals Chrome 확장 프로그램
브라우저 확장 프로그램으로 실시간 CLS 측정. 실제 탐색 환경에서 CLS가 발생하는 시점을 바로 확인할 수 있다.
Lighthouse
Chrome DevTools → Lighthouse 탭에서 실험실 환경 CLS를 측정. 실제 사용자 데이터와 다를 수 있지만 즉각적인 개선 피드백이 가능하다.
CLS와 SEO 랭킹
구글은 2021년 6월 Core Web Vitals를 공식 랭킹 신호로 도입했다. CLS는 세 지표 중 하나로 포함된다.
Google 공식 입장: 콘텐츠 품질이 페이지 경험(CLS 포함)보다 우선한다. 같은 콘텐츠 품질의 두 페이지가 있다면 CLS가 낮은 페이지가 유리하다.
실무적으로 CLS 단독 영향은 크지 않지만, CLS가 나쁜 사이트는 사용자 이탈률이 높아지고 이는 사용자 신호로 간접 영향을 줄 수 있다.
한국 시장 적용
한국 사이트의 흔한 CLS 원인
광고 삽입: 네이버 애드포스트, 구글 애드센스, 카카오 애드핏은 비동기로 광고를 로드해 CLS를 일으키는 대표적 원인이다. 각 광고 SDK가 제공하는 공간 예약 옵션을 활성화해야 한다.
한국어 웹폰트: Pretendard, Noto Sans KR, 나눔고딕은 파일 크기가 크다. font-display: optional로 처음 방문 시 시스템 폰트를 사용하고, 캐시된 이후부터 웹폰트를 적용하는 전략이 CLS 최소화에 효과적이다.
카페24 자동 배너: 카페24 스마트 스토어에서 자동으로 삽입되는 이벤트 배너나 쿠폰 바가 CLS를 유발할 수 있다. 테마 CSS를 수정해 공간을 미리 확보한다.
자주 묻는 질문
Q. CLS 0.15인데 얼마나 개선해야 하나요?
A. Core Web Vitals 통과 기준(0.1 이하)에서 0.05 차이다. 먼저 이미지 width/height 지정을 전체 페이지에 적용하고, PageSpeed Insights에서 "CLS 개선 기회" 항목을 확인한다. 이 두 단계만으로 0.1 이하로 내려가는 경우가 많다.
Q. 모바일 CLS와 데스크탑 CLS가 다른 이유는 무엇인가요?
A. 화면 크기가 다르면 레이아웃이 달라져 CLS 발생 패턴도 다르다. 구글은 모바일과 데스크탑을 별도로 평가한다. 모바일에서만 나타나는 CLS는 모바일 전용 광고, 모바일 헤더 배너 등이 원인인 경우가 많다.
Q. 사용자 클릭으로 인한 레이아웃 변동도 CLS에 포함되나요?
A. 포함되지 않는다. CLS는 예상치 못한 레이아웃 변동만 측정한다. 사용자가 버튼을 클릭해 아코디언이 열리거나 탭이 전환되는 등 의도된 상호작용에 의한 변동은 CLS에서 제외된다.
Q. iframe 광고를 사용하는데 CLS 개선이 가능한가요?
A. 가능하다. iframe의 width와 height를 명시하거나, CSS aspect-ratio를 적용하면 iframe 로딩 전 공간이 예약된다. 광고 플랫폼이 고정 크기 광고를 보장하지 않는다면 min-height를 설정해 최소한의 공간을 확보한다.
Q. CLS가 나빠도 콘텐츠가 좋으면 순위에 영향이 없나요?
A. 구글 공식 입장은 콘텐츠 품질 우선이다. 그러나 나쁜 CLS(0.25 이상)는 사용자 이탈을 유발하고, 사용자가 잘못된 위치를 클릭하는 등 UX를 직접적으로 저해한다. 사용자 경험이 장기적으로 사이트 신뢰도에 영향을 주므로 CLS 개선은 SEO와 무관하게 권장된다.
관련 출처
- web.dev (2024). Cumulative Layout Shift (CLS). https://web.dev/articles/cls
- web.dev (2024). Optimize Cumulative Layout Shift. https://web.dev/articles/optimize-cls
- Google Search Central (2021). Evaluating page experience for a better web. https://developers.google.com/search/blog/2020/05/evaluating-page-experience