CLS(누적 레이아웃 이동) 문제를 해결하는 방법
게시 됨: 2022-03-10CLS(Cumulative Layout Shift)는 이미지, 광고 등 새로운 콘텐츠가 페이지의 나머지 부분보다 늦게 재생될 때 페이지의 거슬리는 움직임을 측정하려고 시도합니다. 페이지가 예기치 않게 이동하는 정도와 빈도에 따라 점수를 계산합니다. 콘텐츠의 이러한 이동 은 매우 성가시며 읽기 시작한 기사에서 위치를 잃거나 더 나쁜 것은 잘못된 버튼을 클릭하게 만듭니다!
이 기사에서는 CLS를 줄이기 위한 몇 가지 프런트 엔드 패턴에 대해 논의할 것입니다. 이전 기사에서 이미 다루었으므로 CLS 측정에 대해 너무 많이 이야기하지 않을 것입니다. 또한 CLS가 계산되는 방식에 대해 너무 많이 이야기하지 않을 것입니다. Google에는 이에 대한 몇 가지 좋은 문서가 있으며 Jess Peck의 누적 레이아웃 이동에 대한 거의 완전한 가이드도 이에 대한 굉장한 심층 분석입니다. 그러나 몇 가지 기술을 이해하는 데 필요한 약간의 배경 지식을 제공합니다.
CLS가 다른 이유
내 생각에 CLS는 Core Web Vitals 중에서 가장 흥미로운데, 부분적으로는 이전에 실제로 측정하거나 최적화한 적이 없었기 때문입니다. 따라서 이를 최적화하려면 새로운 기술과 사고 방식이 필요한 경우가 많습니다. 이는 다른 두 핵심 Web Vitals와 매우 다른 짐승입니다.
다른 두 핵심 Web Vitals를 간략히 살펴보면 LCP(Large Contentful Paint)는 이름에서 알 수 있듯이 페이지 로드 속도를 측정하는 이전 로드 메트릭을 약간 변형한 것입니다. 예, 가장 관련성이 높은 콘텐츠 의 로드 속도를 확인하기 위해 페이지 로드의 사용자 경험을 정의하는 방법을 변경했지만 기본적으로 콘텐츠가 최대한 빨리 로드되도록 하는 기존 기술을 재사용하고 있습니다. LCP를 최적화하는 방법은 대부분의 웹 페이지에서 비교적 잘 알려진 문제입니다.
FID(First Input Delay)는 상호 작용의 지연을 측정하며 대부분의 사이트에서 문제가 되지 않는 것 같습니다. 이를 최적화하는 것은 일반적으로 JavaScript를 정리(또는 줄이기!)하는 문제이며 일반적으로 사이트별로 다릅니다. 즉, 이 두 가지 메트릭으로 문제를 해결하는 것이 쉽다는 것은 아니지만 합리적으로 잘 이해되는 문제입니다.
CLS가 다른 한 가지 이유는 이름의 "누적" 부분인 페이지의 수명을 통해 측정되기 때문입니다! 다른 두 핵심 웹 바이탈은 로드 후(LCP의 경우) 페이지에서 주요 구성 요소가 발견된 후 또는 첫 번째 상호 작용(FID의 경우)에 대해 중지됩니다. 즉, Lighthouse와 같은 기존 실험실 기반 도구는 초기 부하 CLS만 계산하므로 CLS를 완전히 반영하지 못하는 경우가 많습니다. 실제 생활에서 사용자는 페이지를 아래로 스크롤하고 더 많은 콘텐츠가 드롭되어 더 많은 이동을 일으킬 수 있습니다.
CLS는 또한 페이지가 얼마나 자주 이동하는지에 따라 계산되는 약간의 인위적인 숫자입니다. LCP와 FID는 밀리초 단위로 측정되지만 CLS는 복잡한 계산에 의해 출력되는 단위 없는 숫자 입니다. 이 핵심 Web Vital을 통과하려면 페이지가 0.1 이하가 되기를 바랍니다. 0.25 이상이면 "나쁨"으로 간주됩니다.
사용자 상호 작용으로 인한 이동은 계산되지 않습니다 . 이것은 포인터 이벤트와 스크롤이 제외되지만 특정 사용자 상호 작용 세트의 500ms 이내로 정의됩니다. 버튼을 클릭하는 사용자는 예를 들어 접힌 섹션을 확장하여 콘텐츠가 나타날 것으로 예상할 수 있습니다.
CLS는 예상치 못한 변화를 측정하는 것입니다. 페이지가 최적으로 구축된 경우 스크롤해도 콘텐츠가 움직이지 않아야 하며, 예를 들어 확대된 버전을 보기 위해 제품 이미지 위로 마우스를 가져가도 다른 콘텐츠가 건너뛰지 않아야 합니다. 그러나 물론 예외가 있으며 해당 사이트는 이에 대응하는 방법을 고려해야 합니다.
CLS는 또한 조정 및 버그 수정을 통해 지속적으로 발전하고 있습니다. SPA(Single Page Apps) 및 무한 스크롤 페이지와 같이 CLS에서 부당하게 불이익을 받았다고 생각했던 장수 페이지에 약간의 유예를 제공해야 하는 더 큰 변경 사항이 발표되었습니다. 지금까지처럼 CLS 점수를 계산하기 위해 전체 페이지 시간에 걸쳐 교대를 누적하는 대신 점수는 특정 타임박스 창 내에서 가장 큰 교대 집합을 기반으로 계산됩니다.
즉, 0.05, 0.06 및 0.04의 CLS 3개 청크가 있는 경우 이전에는 0.15(즉, "양호한" 한계 0.1 초과)로 기록되었지만 지금은 0.06으로 점수가 매겨집니다. 점수가 해당 시간 프레임 내에서 별도의 이동으로 구성될 수 있다는 점에서 여전히 누적 되지만(즉, 해당 0.06 CLS 점수가 0.02의 세 가지 개별 이동으로 인해 발생한 경우), 더 이상 페이지의 전체 수명 동안 누적되지 않습니다. .
즉, 해당 0.06 이동의 원인을 해결하면 CLS가 다음으로 큰 것으로 보고되므로(0.05) 여전히 페이지의 수명 동안 모든 이동을 보고 있습니다. CLS 점수로 가장 큰 것.
CLS에 대한 몇 가지 방법론에 대한 간략한 소개와 함께 몇 가지 솔루션 으로 이동하겠습니다! 이러한 모든 기술은 기본적으로 추가 콘텐츠가 로드되기 전에 적절한 공간을 확보하는 것과 관련이 있습니다. 미디어 또는 JavaScript 삽입 콘텐츠인지 여부에 관계없이 웹 개발자가 이를 수행할 수 있는 몇 가지 다른 옵션이 있습니다.
이미지 및 iFrame의 너비와 높이 설정
이전에 이에 대해 쓴 적이 있지만 CLS를 줄이기 위해 할 수 있는 가장 쉬운 방법 중 하나는 이미지에 width
및 height
속성을 설정하는 것 입니다. 그것들이 없으면 이미지는 다운로드 후 후속 콘텐츠가 이동하도록 합니다.
이것은 단순히 다음에서 이미지 마크업을 변경하는 문제입니다.
<img src="hero_image.jpg" alt="...">
에게:
<img src="hero_image.jpg" alt="..." width="400" height="400">
DevTools를 열고 요소 위로 마우스를 가져가거나 탭하여 이미지의 크기를 찾을 수 있습니다.
Intrinsic Size (이미지 소스의 실제 크기)를 사용하는 것이 좋습니다. 그러면 CSS를 사용하여 변경할 때 브라우저에서 렌더링된 크기로 축소합니다.
빠른 팁 : 저처럼 너비와 높이 또는 높이와 너비가 기억나지 않으면 X와 Y 좌표로 생각하여 X와 같이 너비가 항상 먼저 주어집니다.
반응형 이미지 가 있고 CSS를 사용하여 이미지 크기를 변경하는 경우(예: max-width
를 화면 크기의 100%로 제한하기 위해) 이러한 속성을 사용하여 height
를 계산할 수 있습니다. CSS에서 auto
:
img { max-width: 100%; height: auto; }
모든 최신 브라우저는 현재 이를 지원하지만 최근까지 내 기사에서 다루지 않았습니다. 이것은 <picture>
요소와 srcset
이미지(대체 img
요소의 width
와 height
설정)에도 작동하지만 아직 다른 종횡비의 이미지에는 적용되지 않습니다. 작업 중이며 그때까지 width
와 height
를 설정해야 합니다. 모든 값이 0
x 0
기본값보다 나을 것이기 때문입니다!
이것은 기본 지연 로드 이미지 에서도 작동합니다(Safari는 기본적으로 기본 지연 로드를 아직 지원하지 않음).
새로운 aspect-ratio
CSS 속성
반응형 이미지의 높이를 계산하기 위해 위의 width
및 height
기술은 새로운 CSS aspect-ratio
속성을 사용하여 다른 요소로 일반화할 수 있습니다. 이 속성은 현재 Chromium 기반 브라우저와 Firefox에서 지원되지만 Safari Technology Preview에도 있으므로 곧 안정 버전이 나올 것이라는 뜻입니다.
예를 들어 16:9 비율로 포함된 비디오에 사용할 수 있습니다.
video { max-width: 100%; height: auto; aspect-ratio: 16 / 9; }
<video controls width="1600" height="900" poster="..."> <source src="/media/video.webm" type="video/webm"> <source src="/media/video.mp4" type="video/mp4"> Sorry, your browser doesn't support embedded videos. </video>
흥미롭게도 aspect-ratio
속성을 정의하지 않으면 브라우저는 반응형 비디오 요소의 높이를 무시하고 기본 가로 세로 비율 2:1을 사용하므로 여기에서 레이아웃 이동을 피하기 위해 위의 항목이 필요합니다.
미래에는 aspect-ratio
-ratio: attr aspect-ratio: attr(width) / attr(height);
그러나 슬프게도 이것은 아직 지원되지 않습니다.
또는 반응형으로 만들기 위해 만들고 있는 일종의 사용자 정의 컨트롤에 대해 <div>
요소에 aspect-ratio
를 사용할 수도 있습니다.
#my-square-custom-control { max-width: 100%; height: auto; width: 500px; aspect-ratio: 1; }
<div></div>
aspect-ratio
지원하지 않는 브라우저의 경우 이전 패딩 하단 핵을 사용할 수 있지만 최신 aspect-ratio
의 단순성과 광범위한 지원(특히 Safari Technical Preview에서 일반 Safari로 이동하면) 오래된 방법을 정당화하기 어렵습니다.
Chrome은 CLS를 Google에 피드백 하는 유일한 브라우저이며 Core Web Vitals 측면에서 CLS 문제를 해결할 aspect-ratio
의미를 지원합니다. 나는 사용자보다 메트릭의 우선 순위를 지정하는 것을 좋아하지 않지만, 다른 Chromium 및 Firefox 브라우저에 이 기능이 있고 Safari가 곧 지원될 것이라는 사실과 이것이 점진적인 개선 사항이라는 사실은 우리가 다음과 같은 시점에 있다고 말하고 싶습니다. padding-bottom 핵을 뒤에 남겨두고 더 깨끗한 코드를 작성할 수 있습니다.
min-height
자유롭게 사용
반응형 크기가 필요하지 않고 대신 고정 높이가 필요한 요소의 경우 min-height
사용을 고려하십시오. 이것은 고정 높이 헤더 에 대한 것일 수 있으며 평소와 같이 미디어 쿼리를 사용하여 다른 중단점에 대해 다른 제목을 가질 수 있습니다.
header { min-height: 50px; } @media (min-width: 600px) { header { min-height: 200px; } }
<header> ... </header>
물론 수평으로 배치된 요소의 min-width
에도 동일하게 적용되지만 일반적으로 CLS 문제를 일으키는 높이입니다.
삽입된 콘텐츠 및 고급 CSS 선택기에 대한 고급 기술은 예상 콘텐츠가 아직 삽입되지 않은 경우 대상을 지정하는 것입니다. 예를 들어 다음 콘텐츠가 있는 경우:
<div class="container"> <div class="main-content">...</div> </div>
그리고 JavaScript를 통해 추가 div
가 삽입됩니다.
<div class="container"> <div class="additional-content">.../div> <div class="main-content">...</div> </div>
그런 다음 main-content
div가 처음에 렌더링될 때 다음 스니펫을 사용하여 추가 콘텐츠를 위한 공간을 남겨둘 수 있습니다.
.main-content:first-child { margin-top: 20px; }
이 코드는 여백이 해당 요소의 일부로 계산되므로 실제로 main-content
요소로의 이동을 생성 하므로 해당 요소가 제거될 때 이동하는 것처럼 보일 것입니다(실제로 화면에서 이동하지 않더라도). 그러나 최소한 그 아래의 콘텐츠는 이동되지 않으므로 CLS를 줄여야 합니다.
또는 ::before
pseudo-element를 사용하여 main-content
요소 의 이동을 피하기 위해 공백을 추가할 수도 있습니다.
.main-content:first-child::before { content: ''; min-height: 20px; display: block; }
그러나 솔직히 말해서 더 나은 솔루션은 HTML에 div
를 포함하고 min-height
를 사용하는 것입니다.
대체 요소 확인
나는 가능한 한 JavaScript 없이도 기본적인 웹사이트를 제공하기 위해 점진적 향상을 사용하는 것을 좋아합니다. 불행히도 이것은 내가 유지하는 한 사이트에서 최근 JavaScript가 아닌 대체 버전이 JavaScript가 시작되었을 때와 다를 때 발견했습니다.
이 문제는 헤더의 "목차" 메뉴 버튼으로 인해 발생했습니다. JavaScript가 시작되기 전에 목차 페이지로 이동하는 버튼처럼 보이도록 스타일이 지정된 간단한 링크가 있습니다. JavaScript가 시작되면 해당 페이지에서 이동하려는 페이지로 직접 이동할 수 있는 동적 메뉴 가 됩니다.
시맨틱 요소를 사용했기 때문에 대체 링크에 앵커 요소( <a href="#table-of-contents">
)를 사용했지만 JavaScript 기반 동적 메뉴의 경우 이를 <button>
으로 대체했습니다. 이것들은 똑같이 보이도록 스타일이 지정되었지만 대체 링크는 버튼보다 몇 픽셀 작습니다!
이것은 너무 작았고 JavaScript는 일반적으로 너무 빨리 시작되어 꺼진 줄도 몰랐습니다. 그러나 Chrome은 CLS를 계산할 때 이를 알아차렸고 이것이 헤더에 있는 것처럼 전체 페이지를 몇 픽셀 아래로 이동했습니다 . 따라서 이것은 CLS 점수에 상당한 영향을 미쳤습니다. 우리의 모든 페이지를 "개선 필요" 범주로 분류하기에 충분했습니다.
이것은 내 오류였으며 수정은 단순히 두 요소를 동기화 하는 것이었지만(위에서 설명한 것처럼 헤더의 min-height
를 설정하여 수정할 수도 있음) 약간 혼란스러웠습니다. 이 오류를 범한 유일한 사람은 아니므로 JavaScript 없이 페이지가 렌더링되는 방식을 알고 있어야 합니다. 사용자가 JavaScript를 비활성화한다고 생각하지 않습니까? JS를 다운로드하는 동안 모든 사용자는 JS가 아닙니다.
웹 글꼴로 인해 레이아웃 이동
웹 글꼴은 브라우저가 초기에 대체 글꼴을 기반으로 필요한 공간을 계산한 다음 웹 글꼴을 다운로드할 때 다시 계산 하기 때문에 CLS의 또 다른 일반적인 원인입니다. 일반적으로 CLS는 작아서 비슷한 크기의 대체 글꼴이 사용되므로 종종 Core Web Vitals에 실패할 만큼 충분한 문제를 일으키지 않지만 그럼에도 불구하고 사용자에게 방해가 될 수 있습니다.
불행히도 웹폰트를 미리 로드하는 것조차도 여기에 도움이 되지 않습니다. 그 이유는 폴백 글꼴이 사용되는 시간을 줄이는 반면(로드 성능에 좋습니다 — LCP), 여전히 가져오는 데 시간이 걸리므로 폴백이 계속 사용되기 때문입니다. 대부분의 경우 브라우저에서 CLS를 피하지 않습니다. 즉, 다음 페이지에 웹 글꼴이 필요하다는 것을 알고 있다면(예를 들어 로그인 페이지에 있고 다음 페이지에서 특수 글꼴을 사용한다는 것을 알고 있는 경우) 해당 글꼴을 미리 가져올 수 있습니다.
글꼴로 인한 레이아웃 변경 을 모두 피하기 위해 시스템 글꼴을 대신 사용하거나 font-display: optional
을 포함하여 웹 글꼴을 전혀 사용하지 않을 수 있습니다. 하지만 둘 다 솔직히 만족스럽지는 않습니다.
또 다른 옵션은 섹션의 크기가 적절하게 조정 되도록 하는 것입니다(예: min-height
사용). 그러면 그 안의 텍스트가 약간 이동할 수 있지만 이 경우에도 그 아래의 내용이 아래로 밀려나지 않습니다. 예를 들어, <h1>
요소에 min-height
를 설정하면 약간 더 큰 글꼴이 로드되는 경우 전체 기사가 아래로 이동하는 것을 방지할 수 있습니다. 이렇게 하면 이동의 영향을 줄일 수 있지만 많은 사용 사례(예: 일반 단락)의 경우 최소 높이를 일반화하기 어려울 것입니다.
이 문제를 해결하기 위해 가장 기대되는 것은 CSS에서 대체 글꼴을 보다 쉽게 조정할 수 있는 새로운 CSS 글꼴 설명자입니다.
@font-face { font-family: 'Lato'; src: url('/static/fonts/Lato.woff2') format('woff2'); font-weight: 400; } @font-face { font-family: "Lato-fallback"; size-adjust: 97.38%; ascent-override: 99%; src: local("Arial"); } h1 { font-family: Lato, Lato-fallback, sans-serif; }
이전에는 JavaScript에서 Font Loading API를 사용하여 대체 글꼴을 조정해야 하는 것이 더 복잡했지만 곧 출시될 이 옵션은 마침내 더 쉽게 관심을 끌 수 있는 솔루션을 제공할 수 있습니다. 이 다가오는 혁신에 대한 자세한 내용과 이에 대한 추가 리소스는 이 주제에 대한 이전 기사를 참조하십시오.
클라이언트 측 렌더링 페이지의 초기 템플릿
많은 클라이언트 측 렌더링 페이지 또는 단일 페이지 앱은 HTML 및 CSS만 사용하여 초기 기본 페이지를 렌더링한 다음 JavaScript가 다운로드 및 실행된 후 템플릿을 "수화"합니다.
새로운 구성 요소와 기능이 JavaScript의 앱에 추가되지만 먼저 렌더링되는 초기 HTML 템플릿에는 추가되지 않기 때문에 이러한 초기 템플릿이 JavaScript 버전과 동기화되지 않기 쉽습니다. 그러면 JavaScript에서 이러한 구성 요소를 삽입할 때 CLS가 발생합니다.
따라서 모든 초기 템플릿을 검토하여 여전히 좋은 초기 자리 표시자인지 확인하십시오. 그리고 초기 템플릿이 빈 <div>
로 구성된 경우 위의 기술을 사용하여 이동을 방지하기 위해 적절한 크기인지 확인합니다.
또한 앱과 함께 주입되는 초기 div
에는 초기 템플릿이 삽입되기 전에 처음에 0 높이로 렌더링되지 않도록 min-height
가 있어야 합니다.
<div></div>
예를 들어 min-height
가 대부분의 뷰포트보다 크면 웹사이트 바닥글에 대한 CLS를 피할 수 있습니다. CLS는 뷰포트에 있을 때만 측정되므로 사용자에게 영향을 줍니다. 기본적으로 빈 div
의 높이는 0px이므로 앱이 로드될 때 실제 높이에 더 가까운 min-height
를 지정합니다.
사용자 상호 작용이 500ms 이내에 완료되도록 보장
콘텐츠 이동을 유발하는 사용자 상호 작용은 CLS 점수에서 제외됩니다. 상호 작용 후 500ms로 제한됩니다. 따라서 버튼을 클릭하고 500ms가 넘는 복잡한 처리를 수행한 다음 새 콘텐츠를 렌더링하면 CLS 점수가 낮아질 것입니다.
성능 탭 을 사용하여 페이지를 기록하고 다음 스크린샷과 같이 이동을 찾아 Chrome DevTools에서 이동이 제외 되었는지 확인할 수 있습니다. DevTools를 열고 매우 위협적인(하지만 익숙해지면 매우 유용합니다!) 성능 탭으로 이동한 다음 왼쪽 상단의 기록 버튼(아래 이미지에 동그라미로 표시됨)을 클릭하고 페이지와 상호 작용하고 한 번 기록을 중지합니다. 완벽한.
다른 Smashing Magazine 기사에 대한 댓글 중 일부를 로드한 페이지의 필름 스트립을 볼 수 있으므로 내가 동그라미로 표시한 부분에서 댓글이 로드되고 빨간색 바닥글이 화면 밖으로 이동하는 것을 확인할 수 있습니다. 성능 탭 아래의 경험 라인 아래에 Chrome은 각 교대조에 대해 붉은빛이 도는 분홍색 상자를 표시하고 이를 클릭하면 아래 요약 탭에서 더 자세한 정보를 얻을 수 있습니다.
여기에서 우리가 목표로 하는 임계값 0.1을 훨씬 넘어 엄청난 0.3359점 을 얻었음을 알 수 있습니다. 그러나 최근 입력 이 사용으로 설정되어 있기 때문에 누적 점수 에는 이를 포함하지 않습니다.
상호 작용은 First Input Delay가 측정하려고 하는 범위 내에서만 500ms 경계 내에서 콘텐츠를 이동하도록 보장하지만 사용자가 입력이 영향을 미쳤음을 확인할 수 있는 경우(예: 로딩 스피너가 표시됨) FID는 좋지만 콘텐츠는 500ms 제한이 끝날 때까지 페이지에 추가되지 않으므로 CLS가 좋지 않습니다.
이상적으로는 전체 상호 작용이 500ms 이내에 완료되지만 처리가 진행되는 동안 위의 기술을 사용하여 필요한 공간을 따로 확보하는 몇 가지 작업을 수행할 수 있으므로 마법의 500ms보다 더 오래 걸리는 경우 이미 교대 근무를 처리했으므로 이에 대해 불이익을 받지 않습니다. 이것은 가변적이고 제어할 수 없는 네트워크에서 콘텐츠를 가져올 때 특히 유용합니다.
주의해야 할 다른 항목은 500ms보다 오래 걸리므로 CLS에 영향을 줄 수 있는 애니메이션 입니다. 이것이 약간 제한적으로 보일 수 있지만 CLS의 목표는 "재미"를 제한하는 것이 아니라 사용자 경험에 대한 합리적인 기대치를 설정하는 것이며 500ms 이하가 걸릴 것으로 기대하는 것이 비현실적이라고 생각하지 않습니다. 그러나 동의하지 않거나 고려하지 않은 사용 사례가 있는 경우 Chrome 팀은 이에 대한 피드백을 받을 수 있습니다.
동기 자바스크립트
내가 논의할 마지막 기술은 잘 알려진 웹 성능 조언에 위배되기 때문에 약간 논란의 여지가 있지만 특정 상황에서는 유일한 방법이 될 수 있습니다. 기본적으로 이동을 일으킬 것이라는 것을 알고 있는 콘텐츠가 있는 경우 이동을 방지하는 한 가지 솔루션은 안정화될 때까지 렌더링하지 않는 것입니다!
아래 HTML은 처음에 div
를 숨긴 다음 일부 렌더링 차단 JavaScript를 로드하여 div
를 채운 다음 숨기기를 해제합니다. JavaScript가 렌더링을 차단하기 때문에 이 아래의 아무 것도 렌더링되지 않으며(숨기기를 해제하는 두 번째 style
블록 포함) 시프트가 발생하지 않습니다.
<style> .cls-inducing-div { display: none; } </style> <div class="cls-inducing-div"></div> <script> ... </script> <style> .cls-inducing-div { display: block; } </style>
이 기술을 사용 하여 HTML에 CSS를 인라인하는 것이 중요하므로 순서대로 적용됩니다. 대안은 JavaScript 자체로 콘텐츠 숨김을 해제하는 것이지만 위의 기술에서 내가 좋아하는 것은 JavaScript가 실패하거나 브라우저에서 꺼진 경우에도 여전히 콘텐츠 숨김을 해제한다는 것입니다.
이 기술은 외부 JavaScript에도 적용할 수 있지만 외부 JavaScript가 요청 및 다운로드되므로 인라인 script
보다 지연이 더 많이 발생합니다. 이러한 지연은 JavaScript 리소스를 미리 로드하여 최소화할 수 있으므로 파서가 코드의 해당 섹션에 도달하면 더 빨리 사용할 수 있습니다.
<head> ... <link rel="preload" href="cls-inducing-javascript.js" as="script"> ... </head> <body> ... <style> .cls-inducing-div { display: none; } </style> <div class="cls-inducing-div"></div> <script src="cls-inducing-javascript.js"></script> <style> .cls-inducing-div { display: block; } </style> ... </body>
자, 내가 말했듯이 이것은 특히 차단을 피하기 위해 JavaScript에서 async, defer
defer
최신 type="module"
(기본적으로 지연됨)을 사용하는 것이므로 일부 웹 성능 사람들이 움츠러들게 만들 것이라고 확신합니다. render , 반면 우리는 여기서 반대입니다! 그러나 내용을 미리 결정할 수 없고 혼란스러운 변화를 일으킬 경우 조기에 렌더링하는 것은 의미가 없습니다.
페이지 상단에 로드되고 콘텐츠를 아래쪽으로 이동하는 쿠키 배너 에 이 기술을 사용했습니다.
이를 위해서는 쿠키 배너를 표시할지 여부를 확인하기 위해 쿠키를 읽어야 했으며, 이는 서버 측에서 완료될 수 있지만 반환된 HTML을 동적으로 변경할 수 있는 기능이 없는 정적 사이트였습니다.
쿠키 배너는 CLS를 피하기 위해 다양한 방식으로 구현될 수 있습니다. 예를 들어 콘텐츠를 아래로 이동하는 대신 페이지 하단에 배치하거나 콘텐츠 상단에 오버레이합니다. 콘텐츠를 페이지 상단에 유지하는 것을 선호했기 때문에 이동을 피하기 위해 이 기술을 사용해야 했습니다. 사이트 소유자가 다양한 이유로 페이지 상단에 표시하는 것을 선호할 수 있는 기타 다양한 알림 및 배너가 있습니다.
나는 또한 JavaScript가 "main" 및 "aside" 열로 콘텐츠를 이동 하는 다른 페이지에서 이 기술을 사용했습니다. JavaScript가 콘텐츠를 재정렬할 때까지 콘텐츠를 다시 숨기고 표시한 다음에만 이러한 페이지의 CLS 점수를 끌어내리는 CLS 문제를 방지했습니다. 그리고 또 어떤 이유로 JavaScript가 실행되지 않고 이동되지 않은 콘텐츠가 표시되더라도 콘텐츠는 자동으로 숨김이 해제됩니다.
이 기술을 사용하면 렌더링을 지연하고 잠재적으로 브라우저의 미리보기 프리로더를 차단할 수 있으므로 다른 메트릭(특히 LCP 및 First Contentful Paint)에 영향을 줄 수 있지만 다른 옵션이 없는 경우 고려해야 할 또 다른 도구입니다.
결론
누적 레이아웃 이동은 콘텐츠가 치수를 변경하거나 늦게 실행되는 JavaScript로 인해 페이지에 새 콘텐츠가 삽입되어 발생합니다. 이 게시물에서는 이를 방지하기 위한 다양한 팁과 요령에 대해 논의했습니다. Core Web Vitals가 이 짜증나는 문제에 대해 스포트라이트를 받은 것을 기쁘게 생각합니다. 너무 오랫동안 우리 웹 개발자(그리고 저도 여기에 포함되어 있음)는 이 문제를 무시해 왔습니다.
내 웹 사이트를 정리하면 모든 방문자에게 더 나은 경험을 제공할 수 있습니다. CLS 문제도 살펴보시기 바랍니다. 이 팁 중 일부가 유용할 수 있기를 바랍니다. 누가 알겠습니까? 모든 페이지에서 CLS 점수가 0점까지 도달할 수도 있습니다!
추가 리소스
- 이미지의 너비 및 높이 설정, 핵심 웹 바이탈 측정 및 CSS 글꼴 설명자에 대한 필자의 기사를 포함하여 여기 Smashing Magazine의 Core Web Vitals 기사.
- CLS의 페이지를 포함하는 Google의 핵심 성능 향상 문서.
- CLS의 최근 변경 사항에 대한 자세한 내용과 이 변경 사항은 다양한 Google 도구에서 업데이트되기 시작했습니다.
- 각 Chrome 버전의 변경 사항을 자세히 설명하는 CLS 변경 로그입니다.
- Jess Peck의 누적 레이아웃 이동에 대한 거의 완전한 안내서.
- 누적 레이아웃 이동: Karolina Szczur의 시각적 불안정성을 측정하고 방지합니다.
- CLS의 공유 가능한 데모를 생성하는 데 도움이 되는 레이아웃 시프트 GIF 생성기.