Layout Shift
란 페이지 콘텐츠가 예기치 않게 이동하는 현상이다.
보통 리소스가 비동기식으로 로드되거나 DOM 요소가 동적으로 추가되어 발생한다.
크기를 알 수 없는 이미지나 동영상, 대체 크기보다 크거나 작게 렌더링 되는 글꼴, 동적으로 크기가 조정되는 광고나 위젯이 원인일 수도 있다.
뉴스 홈페이지 같은 경우 광고 이미지가 추가되면서 텍스트가 움직이는 현상이 흔하게 발생한다.
또한 위와 같은 쇼핑몰 주문 화면에서 버튼이 움직인다면, 사용자와 의도와 다른 버튼을 클릭하게 되어 실제로 피해를 볼 수도 있다.
대부분 개발 환경에서는 이미지 캐시, API 호출 속도 등이 프로덕선 환경과 차이가 있기 때문에 Layout Shift가 눈에 띄지 않을 수 있다. 따라서 항상 프로덕션 환경의 Layout Shift를 고려해야 한다.
모든 Layout Shift가 나쁜 것은 아니고, 동적 웹 페이지에서는 Layout Shift가 필요한 경우가 있다.
링크 클릭, 버튼 클릭, 검색 입력 등 사용자의 상호작용으로 발생하는 레이아웃은 사용자에게 그 관계가 명확하게 보인다면 괜찮다.
예를 들어 버튼을 클릭했을 때 네트워크 요청을 트리거하는 경우, 다른 클릭을 방지하거나 로딩 상태를 알리기 위해서는 로딩 화면을 즉시 표시해주는 것이 좋다.
사용자 입력 후 500ms 이내에 발생하는 Layout Shift는 계산에서 제외된다.
애니메이션과 트랜지션은 사용자를 놀라게 하지 않고 컨텐츠를 업데이트 하는 좋은 방법이다.
한 위치에서 다음 위치로 점진적이고 자연스럽게 이동하기 때문에 사용자가 상황을 더 잘 이해하고 상태를 안내하는 데 도움이 된다.
CSS transform
속성을 사용하면 Layout Shift를 트리거하지 않고 애니메이션을 적용할 수 있다.
transform: scale()
사용transform: translate()
사용CLS (Cumulative Layout Shift)
란 페이지 전체 수명 동안 발생하는 모든 Unexpected Layout Shift 중, 가장 큰 Layout Shift의 점수이다.
CLS는 Layout Shift 측정하여 시각정 안정성(Visual Stability)을 나타내는 데 중요한 UX 지표이다.
CLS가 낮을수록 우수한 사용자 경험을 보장하는 데 도움이 된다.
Impact Fraction은 불안정 요소의 두 프레임이 뷰포트 영역에 미치는 영향을 측정한다.
위와 같은 경우 뷰포트의 절반을 차지하는 요소가 다음 프레임에서 25%만큼 아래로 이동했다. 따라서 두 프레임이 전체 뷰포트의 75%를 차지하여 Impact Fraction은 0.75이다.
Distance Fraction은 뷰포트를 기준으로 불안정 요소가 이동한 거리를 측정한다.
이때 기준이 되는 치수는 뷰포트의 너비, 높이 중 큰 것으로 한다.
위와 같은 경우 기준은 뷰포트의 높이이고, 불안정 요소가 높이의 25% 만큼 이동했으므로 Distance Fraction은 0.25이다.
Layout Shift 점수는 Impact Fraction * Distance Fraction = 0.75 * 0.25 = 0.1875
이다.
Reference