누적 레이아웃 이동(CLS)

누적 레이아웃 이동의 측정 대상, 영향도×거리 공식, 세션 창, 기준값, 일반 원인과 수정·디버깅 방법을 설명합니다.

최초 게시: 2026년 6월 26일 · 최근 업데이트: 2026년 8월 9일 · Advanced
언어

누적 레이아웃 이동(CLS)은 페이지 사용 중 보이는 콘텐츠의 예기치 않은 움직임을 측정하는 핵심 웹 바이탈입니다. 이동별 영향 비율과 거리 비율을 곱한 단위 없는 점수이며 2021년 6월부터 전체 합이 아닌 가장 큰 세션 창을 사용합니다. 필드 데이터 75번째 백분위수에서 0,1 이하면 좋음입니다. 크기 없는 이미지·광고·iframe·임베드, 웹 글꼴, 폴드 위 삽입이 주요 원인이며 공간 예약, 글꼴 메트릭 조정, transform 애니메이션으로 해결합니다.

요약 — CLS는 시각적 안정성을 측정하는 핵심 웹 바이탈입니다. 각 이동 점수는 impact fraction × distance fraction이며, 최종 지표는 모든 이동의 평생 합계가 아니라 가장 큰 세션 창입니다. 이동 간격은 ≤ 1 s, 전체 창은 ≤ 5 s이며 이 정의는 June 2021 이전과 다릅니다. 필드 데이터의 75th 백분위수에서 좋음은 ≤ 0,1, 개선 필요는 ≤ 0,25, 나쁨은 > 0,25입니다. 현재 뷰포트에 보이는 이동만 계산하고 불연속 입력 뒤 500밀리초 안의 이동은 제외하지만 스크롤은 제외되지 않습니다. 원인은 크기 없는 이미지·동영상·광고·iframe·임베드, 웹 글꼴, 기존 콘텐츠 위 삽입이며 해결책은 공간 예약, font-display/size-adjust, transform 전용 애니메이션입니다. Lighthouse는 상호작용이나 전체 수명을 재현하지 않아 실험실 점수가 거의 0일 수 있으므로 Google이 실제로 측정하는 필드 데이터(CrUX)를 확인해야 합니다.

CLS가 측정하는 것

Google은 CLS를 사용자가 예기치 않은 레이아웃 이동을 얼마나 자주 겪는지 수치화하는 안정적인 사용자 중심 핵심 웹 바이탈로 설명합니다. 핵심은 사용자가 행동해서가 아니라 콘텐츠가 저절로 움직이는 예기치 않은 이동입니다.

CLS는 로딩을 보는 Largest Contentful Paint, 반응성을 보는 Interaction to Next Paint와 함께 핵심 웹 바이탈을 구성합니다. LCP와 INP는 밀리초로 측정하지만 CLS는 단위 없는 비율 점수입니다. CLS 0,05를 50밀리초로 해석하면 안 됩니다.

공식: 영향도 × 거리

Google은 이동별 점수를 다음과 같이 정의합니다.

layout shift score = impact fraction × distance fraction
  • 영향 비율“measures how unstable elements impact the viewport area between two frames” (번역) 두 프레임 사이에서 불안정한 요소가 차지한 전후 가시 영역을 합쳐 뷰포트에서 차지하는 비율을 측정합니다.
  • 거리 비율“the greatest horizontal or vertical distance any unstable element has moved in the frame divided by the viewport’s largest dimension (width or height, whichever is greater).” (번역) 불안정한 요소의 최대 수평·수직 이동 거리를 뷰포트의 더 큰 치수로 나눈 값입니다.

두 차원은 독립적으로 중요합니다. 작은 요소가 화면 대부분을 가로질러 이동하는 경우와 큰 요소가 조금 움직이는 경우는 점수가 크게 다를 수 있습니다. web.dev 예시에서 영향 비율 0.75와 거리 비율 0.25를 곱하면 레이아웃 이동 점수는 0.1875입니다.

One shift scores the visible area affected multiplied by the farthest movement relative to the viewport. 출처: web.dev

Three cards form the equation. Impact fraction is 0.75: the visible viewport area affected between two frames. Distance fraction is 0.25: the farthest movement divided by the viewport's largest dimension. Multiplying them produces a unitless individual layout-shift score of 0.1875. CLS ultimately keeps the largest session-window total, not a lifetime sum of every shift.

© Patrick Stox LLC · CC BY 4.0 ·

세션 창: 가장 자주 잘못 설명되는 부분

CLS에서 가장 많이 틀리는 핵심은 페이지 수명 동안 일어난 모든 이동의 합이 아니라는 것입니다. 과거에는 합계였지만 June 2021에 바뀌었습니다.

현재 정의는 “CLS measures the largest burst of layout shift scores for every unexpected layout shift that occurs during the entire lifecycle of a page.” (번역) 페이지 전체 수명에서 발생한 예기치 않은 이동 중 가장 큰 묶음을 측정합니다. 이 묶음인 세션 창“one or more individual layout shifts occur in rapid succession with less than 1-second in between each shift and a maximum of 5 seconds for the total window duration.” (번역) 각 이동 사이가 1초 미만이고 전체가 최대 5초인 연속 이동입니다. CLS는 합계나 평균이 아니라 가장 큰 창의 점수입니다.

Evidence for this claim CLS uses the largest session window of unexpected layout shifts, with gaps under one second and a maximum five-second window; recent discrete input can exclude a shift. Scope: Current CLS session-window and recent-input rules. Confidence: high · Verified: web.dev: Cumulative Layout Shift

이전 합계 방식은 오래 살아 있는 페이지를 조용히 불리하게 만들었습니다. 단일 페이지 앱이나 무한 스크롤 피드는 각각의 이동이 작고 멀리 떨어져 있어도 오래 열려 있다는 이유만으로 점수가 누적됐습니다. Chrome Speed Metrics 팀은 페이지 지속 시간을 벌하지 않도록 최대 세션 창을 채택했고, 작은 보조 이동을 고쳤더니 평균이 오히려 나빠지는 역설을 피하려 평균 대신 최댓값을 선택했습니다. 변경 후 더 나빠진 오리진은 없었고 대부분은 같았으며 느린 UI와 무한 스크롤 페이지 일부가 개선됐습니다. 오래된 글에서 “모든 이동의 합”이라고 하면 현재 정의가 아닙니다.

포함되는 것과 제외되는 것

다음 세 가지 예외가 실제 점수 포함 여부를 결정합니다.

  • 폴드 아래는 포함되지 않습니다. 현재 뷰포트에 보이는 콘텐츠 이동만 계산합니다. 사용자가 보지 않은 긴 페이지 아래쪽 이동은 영향이 없으므로 보통 뷰포트 안 문제를 먼저 고치는 편이 효율적입니다.
  • 사용자 입력 뒤 500밀리초는 제외됩니다. “Layout shifts that occur within 500 milliseconds of user input will have the hadRecentInput flag set, so they can be excluded from calculations.” (번역) 사용자 입력 직후 이동에는 최근 입력 플래그가 붙어 계산에서 빠집니다. Google은 상호작용과 가까워 관계가 분명한 이동은 일반적으로 괜찮다고 설명합니다. 아코디언이나 메뉴가 열리는 움직임은 예상된 것입니다.
  • 스크롤은 예외가 아닙니다. 500밀리초 제외는 탭·클릭·키 누름 같은 불연속 이벤트에만 적용됩니다. 스크롤·핀치 줌 같은 연속 제스처는 제외 창을 만들지 않으므로 스크롤 중 콘텐츠가 움직여도 계산됩니다.
Evidence for this claim A layout shift occurring within 500 milliseconds of a qualifying recent user input has hadRecentInput set and is excluded from CLS. Scope: field and lab Confidence: high · Verified: Cumulative Layout Shift (CLS)

기준값과 점수 출처

“To provide a good user experience, sites should strive to have a CLS score of 0.1 or less,” (번역) 좋은 사용자 경험을 위해 CLS는 영점일 이하를 목표로 해야 하며, “the 75th percentile of page loads, segmented across mobile and desktop devices.” (번역) 모바일과 데스크톱을 나눈 페이지 로드의 칠십오 번째 백분위수에서 측정합니다. 전체 구간은 다음과 같습니다.

Evidence for this claim CLS is good at 0.1 or less and poor above 0.25, assessed at the 75th percentile of page loads. Scope: Current web.dev CLS field thresholds. Confidence: high · Verified: web.dev: Cumulative Layout Shift
  • 좋음: ≤ 0,1
  • 개선 필요: 0,1 – 0,25
  • 나쁨: > 0,25
Evidence for this claim CLS is good at 0.1 or less and poor above 0.25, assessed at the 75th percentile of page loads. Scope: Current web.dev CLS field thresholds. Confidence: high · Verified: web.dev: Cumulative Layout Shift

0,1 기준은 임의로 정한 것이 아닙니다. Google 연구에서는 “levels of shift from 0.15 and higher were consistently perceived as disruptive, while shifts of 0.1 and lower were noticeable but not excessively disruptive.” (번역) 0,15 이상은 일관되게 방해로 느껴졌고 0,1 이하는 눈에 띄지만 지나치게 방해되지는 않았습니다. 광고·소셜 같은 제삼자 임베드가 흔히 이동을 만들기 때문에 더 엄격한 기준은 실제 웹에서 비현실적이라는 점도 반영됐습니다.

“필드 데이터의 75th 백분위수”는 매우 중요하며 가장 큰 측정 함정으로 이어집니다.

실험실과 필드: 수치가 다른 이유

Lighthouse 같은 실험실 도구는 CLS를 거의 0,0으로 표시하지만 필드 데이터와 Google에서는 훨씬 나쁘게 나오는 일이 흔합니다. 어느 도구가 거짓말하는 것이 아니라 범위가 다릅니다. 실험실 실행은 짧고 스크립트화된 단일 로드라서 스크롤·클릭·장기 체류 없이 초기 로드 이동만 봅니다. 필드 데이터(CrUX)는 이동 기간 동안 다양한 사용자·기기·탐색의 실제 방문을 집계하며 CLS는 메뉴 열기, 스크롤 중 지연 로드, 늦은 광고 등 페이지 전체 수명을 대상으로 합니다. 짧은 실험실 실행은 구조적으로 대부분을 볼 수 없습니다.

실무 원칙은 특정 이동을 디버깅할 때는 실험실 데이터, 실제 점수를 알 때는 필드 데이터를 쓰는 것입니다. Google은 **Chrome User Experience Report(CrUX)**의 필드 데이터를 순위에 사용하며 PageSpeed Insights와 Search Console에 표시합니다. Lighthouse가 0,0이고 PageSpeed Insights가 0,18이면 실제 사용자를 반영하는 필드 값을 기준으로 삼고, 실제 방문처럼 상호작용해 실험실에서 재현하세요. iframe 이동은 CrUX에는 반영될 수 있지만 Lighthouse를 포함한 많은 도구에서 부모 문서 점수로 전파되지 않습니다. Layout Instability API 기반 RUM도 같은 사각지대가 있어 자체 모니터링으로는 더 나쁜 CrUX 수치를 완전히 설명하지 못할 수 있습니다.

일반적인 원인

제가 자주 보는 순서로 정리하면 다음과 같습니다.

  1. 치수가 없는 이미지와 동영상. 높이가 예약되지 않아 미디어가 로드될 때 아래 콘텐츠가 움직입니다.
  2. 공간을 확보하지 않은 광고, 임베드, iframe. 광고 크기는 동적이고 임베드는 로드 전에 높이를 알리지 않습니다.
  3. 기존 콘텐츠 위에 동적으로 삽입되는 콘텐츠. 쿠키 배너, 알림 바, 관련 위젯, 늦게 뜨는 프로모션이 화면 내용을 아래로 밉니다.
  4. 웹 글꼴(FOIT/FOUT). 사용자 글꼴과 대체 글꼴의 메트릭이 다르면 교체 순간 텍스트가 다시 흐릅니다.
  5. 레이아웃을 유발하는 속성의 애니메이션. top, left, margin, box-shadow, box-sizing을 애니메이션하면 매 프레임 레이아웃을 다시 계산합니다.

해결법

해결책은 각 원인과 정확히 대응합니다.

  • 이미지·동영상 — 공간을 예약하세요. widthheight 속성으로 브라우저가 종횡비와 상자 크기를 계산하게 하고, 반응형에는 img { height: auto; width: 100%; } for responsive behavior, or use the CSS aspect-ratio 속성을 사용합니다. 대부분 사이트에서 효과가 가장 큰 CLS 수정입니다.
  • 광고·임베드·iframe — 역시 공간을 예약하세요. 컨테이너에 min-heightaspect-ratio를 쓰세요. Google Publisher Tag 지침은 “Setting a fixed height and width directly on the ad slot div is the most effective way to do this.” (번역) 광고 슬롯 div에 고정 높이와 너비를 직접 지정하는 것이 가장 효과적이라고 합니다. 여러 크기 슬롯은 가장 큰 구성 크기를 예약하고 늦게 로드되는 콘텐츠는 가능한 한 폴드 아래로 내립니다.
  • 동적 콘텐츠 — 흐름 중간에 삽입하지 마세요. 최종 크기와 맞는 자리표시자를 확보하거나 콘텐츠를 오버레이하세요. 스켈레톤은 최종 치수와 정확히 같을 때만 도움이 됩니다. 몇 픽셀만 작아도 이동합니다. 예고 없는 삽입보다 “더 보기” 같은 사용자 작동 로드를 권합니다.
  • 글꼴 — 메트릭을 맞추세요. font-display: optional은 CLS 위험이 사실상 인 유일한 값입니다. swap은 보이지 않는 텍스트를 줄이지만 교체 때 이동할 수 있습니다. size-adjust, ascent-override, descent-override, line-gap-override로 대체 글꼴을 웹 글꼴에 맞추고 중요 글꼴을 미리 로드하세요.
  • 애니메이션 — transform만 사용하세요. top/left/margin 대신 transform의 이동·크기·회전을 사용하면 합성 단계에서 처리돼 레이아웃을 유발하지 않습니다.

순위에서 CLS의 비중

CLS는 Google 페이지 경험 신호의 입력 중 하나입니다. Google은 순위 시스템이 핵심 웹 바이탈을 사용한다고 말하지만 현재 검색 문서에는 정확한 CLS 가중치, 동률 결정 규칙, 순위 보장이 없습니다. 따라서 “동률 결정 요소” 같은 구체적 메커니즘은 문서화된 사실이 아니라 근사로 보세요. 제 일관된 조언은 “좋음” 구간에 들어가면 다음 문제로 이동하라는 것입니다. 0,08을 0,02로 낮춘다고 대부분의 사이트에서 의미 있는 순위·매출 상승이 생기지는 않으며 단일 점수만으로 수익 결과를 설명하기도 어렵습니다. CLS는 통과해야 할 기본 조건이지만 LCP, INP, 실제 콘텐츠보다 SEO 프로그램의 중심이 되어서는 안 됩니다.

혼란을 크게 줄이는 운영상 참고 사항 두 가지가 있습니다.

  • CrUX는 약 28일 늦습니다. 이동 28일 창이므로 오늘 배포한 수정은 PageSpeed Insights나 Search Console에 완전히 반영되기까지 몇 주 걸립니다. 다음 날 숫자가 그대로여도 당황하지 마세요.
  • 귀속된 요소가 근본 원인이 아닐 수 있습니다. Layout Shift Attribution API는 움직인 요소를 알려 주지만 web.dev는 “it’s possible that these elements are only indirectly related to the ‘root cause’ of layout instability.” (번역) 이 요소가 불안정성의 근본 원인과 간접적으로만 관련될 수 있다고 설명합니다. 움직인 텍스트는 위쪽의 크기 없는 이미지가 늦게 로드된 피해자일 수 있습니다. 이동 시작 시각과 같은 창에서 완료된 네트워크 요청, 이미지·글꼴 도착, 크기 변경, 클래스·스타일 변경을 맞춰 보고 귀속 노드는 증거가 아니라 단서로 취급하세요.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.