Layout Shift는 웹 페이지를 탐색하는 동안 사용자에게 예기치 않은 변화를 일으키는 요소로, 사용자 경험에 큰 영향을 미칩니다.
예를 들어, 사용자가 읽고 있는 내용 옆에서 갑작스럽게 광고가 뜨거나 이미지가 로드되어 페이지 내용이 밀리는 현상이 발생하면, 사용자의 주의를 산만하게 만들고, 전반적인 경험을 방해합니다. (극단적인 예시로는 사용자가 버튼을 클릭하는 중 갑자기 바뀐 레이아웃으로 원치않는 버튼을 클릭할 수 있습니다.)
Layout Shift는 사용자가 페이지를 보는 동안 발생하는 예기치 않은 레이아웃 변경을 의미합니다. 주로 이미지, 광고, 동적 콘텐츠 로드 등으로 인해 발생할 수 있으며, 사용자 경험에 부정적인 영향을 미칠 수 있습니다.
Layout Shift를 측정하는 지표는 'Cumulative Layout Shift'(CLS)가 있습니다. CLS는 사용자가 페이지와 상호작용하는 동안 발생하는 모든 레이아웃 변경의 총합을 측정합니다. 이 지표는 두 가지 주요 요소를 고려합니다:
개발자들은 이 지표를 사용하여 페이지의 시각적 안정성을 평가하고, 필요한 경우 레이아웃 변경을 최소화하여 사용자 경험을 개선할 수 있습니다. 예를 들어, 이미지나 광고의 크기를 미리 지정하거나, 동적으로 콘텐츠를 로드하는 방식을 조정하는 것이 포함됩니다. 이렇게 하면 사용자가 페이지를 보는 동안 요소가 갑자기 이동하여 사용자의 작업을 방해하는 것을 방지할 수 있습니다.
광고나 리스트 항목처럼 동적으로 로드되는 콘텐츠의 경우, 이들이 차지할 공간을 미리 지정해두면 콘텐츠가 로드될 때 레이아웃이 변경되는 것을 최소화할 수 있습니다.
'공간 예약 O' 섹션은 높이가 미리 지정되어 있어 광고가 로드되어도 레이아웃 쉬프트가 발생하지 않습니다. 반면, '공간 예약 X' 섹션은 광고가 로드될 때까지 공간이 없어 광고가 로드되는 순간 주변 레이아웃이 변화하게 됩니다.
애니메이션 또는 전환을 위해 top
이나 left
대신 transform
속성을 사용하면 레이아웃 변경을 유발하지 않으면서 시각적 변경을 만들어낼 수 있습니다.
hover 상태일 때, width
와 height
를 증가시켜 확대되는 버튼은 레이아웃에 영향을 미치기 때문에 버튼이 커질 때 옆에 있는 "Text"가 밀려납니다. 반면 transform
속성을 사용해 확대하면 레이아웃에 영향을 주지 않기 때문에 버튼이 커져도 옆에 있는 "Text"는 그대로 유지됩니다.
이외에도 웹 폰트가 로드될 때 텍스트의 크기나 모양이 변경되어 발생하는 레이아웃 시프트를 font-display
속성을 사용해 폰트 로딩을 제어하거나, 사용자가 콘텐츠를 보기 시작하기 전에 폰트를 로드하는 방법으로 최소화하는 방법도 있습니다.
웹 폰트 로드 최적화하기: 이전에 작성한 포스트에 관련 내용이 있습니다.
사내에서 진행 중인 종합 학생 관리 솔루션의 백오피스 개발 프로젝트에서, 저와 동료인 승원님은 배너관리 파트를 담당하고 있습니다. 이 파트에서는 마우스를 올리면 드래그할 수 있는 영역이 나타나는 기능이 있습니다.
승원님과 디자인 시안대로 구현된 결과물을 리뷰하던 중 호버시 나타나는 드래그 영역으로 레이아웃이 밀려나는 layout shift 현상을 발견했습니다.
이러한 문제를 해결하기 위해, 승원님과 저는 두 가지 수정안을 생각하였습니다:
두 가지 수정안을 디자이너분께 제안한 결과, 요청이 수락되어 디자인 시안이 수정되었습니다.
수정된 결과물에서는 드래그 아이콘 위치 자체로 인한 레이아웃 변경을 최소화하여, 새롭게 나타나는 영역에도 기존 레이아웃의 움직임이 없습니다. 그러나 hover 시 발생하는 border
로 인해 여전히 전체 레이아웃에 작은 변화가 있었습니다. 이를 해결하기 위해, border
대신 outline
을 사용할 수 있습니다.
border
사용 시: 요소의 외곽선이 추가되며, 이것은 요소의 전체 크기에 영향을 줍니다. 즉, 요소에 border
가 추가되거나 변경되면, 그 요소의 전체 크기가 변경되고, 이는 주변 레이아웃에 영향을 줄 수 있습니다.outline
사용 시: 요소의 외곽에 선을 그리지만, 이는 레이아웃 크기 계산에 포함되지 않습니다. outline은 요소의 밖에 그려지고, 요소의 실제 크기나 주변 요소에 영향을 주지 않습니다. 따라서 outline
을 추가하거나 변경해도, 요소의 크기가 변경되지 않아 주변 레이아웃에 영향을 주지 않습니다.Hover 시에 발생하는 border로 인한 레이아웃의 미묘한 변화는 outline을 사용함으로써 완전히 제거되었습니다. outline은 요소의 외곽에 선을 추가하지만, 레이아웃의 크기에는 영향을 주지 않기 때문에, 사용자 인터랙션에 따른 레이아웃 변화 없이도 시각적 피드백을 제공할 수 있었습니다.