무거운 콘텐츠 렌더링 지연

웹 기능: content-visibility

무한 스크롤, 복잡한 대시보드, 밀도 높은 기사와 같이 콘텐츠가 많은 웹페이지는 초기 렌더링이 느리고 상호작용이 느릴 수 있습니다. 최신 웹 기술을 사용하면 즉시 표시되지 않는 콘텐츠의 렌더링 워크로드를 지연시켜 접근성이나 사용자 기대치를 저해하지 않으면서 성능을 크게 향상할 수 있습니다.

렌더링을 최적화하려면 CSS content-visibility 속성과 HTML hidden="until-found" 속성을 활용하면 됩니다. 두 기능 모두 성능을 개선하지만 사용 사례는 서로 다릅니다.

각 도구의 사용 상황

시나리오/예시 기능 적용됨 실적 이점
1. 스크롤해야 볼 수 있는 부분 (초기 로드 지연) content-visibility: auto 브라우저는 컨테이너가 스크롤되어 보기에 가까워질 때까지 레이아웃/페인트 워크로드를 자동으로 오프로드하여 표준 페이지 로드 속도를 원활하게 유지합니다.
2. 상태 전환 (빠른 뷰 전환) content-visibility: hidden 숨겨진 div의 레이아웃 계산을 건너뛰지만 스타일 포함 상태를 유지하므로 구조적 변화 없이 즉시 전환할 수 있습니다(display: none보다 우수함).
3. 검색 가능 및 지연 (접을 수 있는 공개 정보) hidden="until-found" 렌더링 성능과 페이지 내 검색 접근성을 결합하는 방법에 관한 자세한 내용은 숨겨진 콘텐츠 검색을 참고하세요.

content-visibility: auto 구현 방법

화면 밖 콘텐츠 선택

필수: content-visibility: auto를 수신하는 요소를 신중하게 식별해야 합니다(MUST).

  • 엄격하게 초기 스크롤 없이 볼 수 있는 부분 아래에 있는 크고 독립적인 레이아웃 블록(예: 무한 피드의 카드 항목, 후행 댓글 또는 하단이 무거운 레이아웃 섹션)을 타겟팅해야 합니다.
  • 초기 스크롤 없이 볼 수 있는 표시 영역 내의 요소에는 이 속성을 적용하지 마세요. 이렇게 하면 브라우저가 렌더링 전에 가시성 경계를 평가해야 하므로 역설적으로 중요한 페이지 로드 성능이 지연됩니다.
  • 렌더링 비용 절감을 극대화하려면 내부 DOM 구조가 깊거나 복잡한 요소를 타겟팅해야 합니다.

구현 단계

  1. 필수: 초기 로드 시 화면에 표시되지 않는 것으로 확인된 무거운 섹션을 식별합니다.
  2. 필수: 이러한 각 오프스크린 요소에 content-visibility: auto를 적용합니다.
  3. 필수: 각 요소에 contain-intrinsic-size를 사용하여 예상 레이아웃 구조 크기를 제공합니다.

contain-intrinsic-size 사용 방법

필수: content-visibility: auto를 contain-intrinsic-size와 페어링해야 합니다(MUST). 이렇게 하지 않으면 브라우저가 화면에서 벗어날 때 요소를 0px 높이로 축소하여 사용자가 스크롤할 때 심각한 레이아웃 변경과 스크롤바 점프가 발생합니다.

contain-intrinsic-size CSS 약식 속성은 자리표시자 크기 역할을 합니다. auto 키워드를 사용하면 요소가 최종적으로 렌더링된 후 브라우저가 정확한 크기를 '기억'할 수 있으며, 요소가 다시 화면에서 벗어나는 경우 플레이스홀더 대신 계산된 크기를 사용합니다.

예시 코드

/* DO ONLY apply this class to items OUTSIDE the initial layout viewport */
.heavy-section-deferred {
  /* MANDATORY: Skips rendering calculations when off-screen */
  content-visibility: auto;
  
  /* Mandatory: Provide an estimated size to prevent layouts shifts.
    - 'auto' is optional and enables the browser to remember the actual size
      once rendered. It must be paired with a <length> value to be used for
      the first render.
    - 'none' tells the browser not to apply any intrinsic width to this element.
      It can be used for either the height or the width value.
    - '150px' is the estimated height of this element. This can be any valid
      CSS <length> value.
   */
  contain-intrinsic-size: auto none auto 150px; 
}

content-visibility: hidden 구현 방법

  1. 무거운 섹션 식별: 처음에 숨겨진 레이아웃 블록 (예: 대규모 데이터 테이블의 추가 행)을 찾습니다.
  2. CSS 적용: 요소에 content-visibility: hidden를 추가합니다.
  3. 요소 표시: 요소를 표시해야 하는 경우 content-visibility 속성을 visible 또는 auto로 변경합니다.

예시 코드

.cached-view {
  /* Hides content but caches rendering state */
  content-visibility: hidden;
}

.cached-view.is-active {
  content-visibility: visible;
}

content-visibility: hidden는 접근성 트리 및 페이지 내 검색에서 요소와 하위 요소를 제외하므로 콘텐츠가 숨겨진 상태에서 검색 가능해야 하는 경우 사용하지 마세요. 숨겨진 콘텐츠를 기본 페이지 내 찾기를 통해 검색할 수 있도록 유지해야 하는 경우 숨겨진 콘텐츠 검색에 설명된 대로 hidden="until-found"를 사용하세요.

권장사항

  • contain-intrinsic-size를 content-visibility: auto와 함께 사용합니다. 그렇지 않으면 스크롤 시 높이가 다시 계산되어 표시 영역 레이아웃이 점프하거나 시각적 결함이 발생합니다.
  • 초기 폴드 표시 영역 내의 요소에는 content-visibility: auto를 적용하지 마세요. 중요한 페이지 렌더링이 지연됩니다.
  • 필수 접근성 확인: content-visibility: auto를 적용할 때는 순차적 키보드 접근성을 확인해야 합니다(MUST). 특정 보조 기술 구성에서는 content-visibility: auto를 활용하는 화면 외부 노드가 포커스가 강제로 내부로 이동될 때까지 접근성 트리 또는 순차 탐색 경로에서 제외될 수 있습니다. 키보드만 사용하여 화면 경계를 벗어나는 선형 탐색을 테스트합니다.

대체 전략

content-visibility 대체

content-visibility가 지원되지 않으면 브라우저에서 무시됩니다. 대부분의 경우 content-visibility: auto에는 대체가 필요하지 않지만, 대체가 없으면 성능 향상이 사라집니다. 지원되지 않는 브라우저에서는 content-visibility: hidden 요소가 완전히 표시됩니다. 기능 감지를 사용하여 대체 기능을 구현합니다.

/* Default for everyone */
.inactive {
  display: none;
}

/* Modern Browsers only */
@supports (content-visibility: hidden) {
 .inactive {
    display: block; /* Turn the layout box back on */
    content-visibility: hidden;
  }
}