Chrome 52의 CSS 포함

요약

새로운 CSS Containment 속성을 사용하면 개발자가 브라우저의 스타일, 레이아웃, 페인트 작업의 범위를 제한할 수 있습니다.

CSS 포함 이전: 레이아웃이 59.6ms가 소요됩니다. 그 후: 레이아웃이 0.05ms 소요됨

이 요소에는 몇 가지 값이 있으며 구문은 다음과 같습니다.

    contain: none | strict | content | [ size || layout || style || paint ]

Chrome 52 이상 및 Opera 40 이상에서 사용할 수 있으며 Firefox의 공개 지원도 제공됩니다. 사용해 보고 의견을 알려주세요.

contain 속성

웹 앱 또는 복잡한 사이트를 만들 때 주요 성능 문제는 스타일, 레이아웃, 페인트의 효과를 제한하는 것입니다. 종종 DOM의 전체가 계산 작업의 '범위 내'로 간주됩니다. 즉, 웹 앱에서 독립형 '뷰'를 시도하는 것이 까다로울 수 있습니다. DOM의 한 부분에 변경사항이 있으면 다른 부분에 영향을 줄 수 있으며 브라우저에 범위 내 또는 범위 외의 항목을 알려줄 방법이 없습니다.

예를 들어 DOM의 일부가 다음과 같다고 가정해 보겠습니다.

    <section class="view">
      Home
    </section>

    <section class="view">
      About
    </section>

    <section class="view">
      Contact
    </section>

그런 다음 하나의 뷰에 새 요소를 추가하면 스타일, 레이아웃, 페인팅이 트리거됩니다.

    <section class="view">
      Home
    </section>

    <section class="view">
      About
      <div class="newly-added-element">Check me out!</div>
    </section>

    <section class="view">
      Contact
    </section>

그러나 이 경우 전체 DOM이 실제로 범위에 포함됩니다. 즉, 스타일, 레이아웃, 페인트 계산은 변경되었는지 여부와 관계없이 모든 요소를 고려해야 합니다. DOM이 클수록 더 많은 계산 작업이 포함되므로 앱이 사용자 입력에 응답하지 않을 수 있습니다.

다행히 최신 브라우저는 스타일, 레이아웃, 페인트 작업의 범위를 자동으로 제한하는 데 매우 스마트해지고 있습니다. 즉, 개발자가 아무것도 하지 않아도 속도가 빨라집니다.

하지만 더 좋은 소식은 개발자에게 범위 제어를 전달하는 새로운 CSS 속성인 Containment이 있다는 것입니다.

CSS Containment는 contain 키워드가 있는 새로운 속성으로 다음 4가지 값을 지원합니다.

  • layout
  • paint
  • size
  • style

이러한 각 값을 사용하면 브라우저에서 실행해야 하는 렌더링 작업의 양을 제한할 수 있습니다. 각 값을 좀 더 자세히 살펴보겠습니다.

레이아웃 (contain: layout)

레이아웃 컨테이닝은 contain: paint와 함께 컨테이닝의 가장 큰 이점일 수 있습니다.

레이아웃은 일반적으로 문서 범위이므로 DOM 크기에 비례하여 크기가 조정됩니다. 따라서 요소의 left 속성을 변경하면 DOM의 모든 요소를 확인해야 할 수 있습니다.

여기에서 컨테이닝을 사용 설정하면 문서 전체가 아닌 일부 요소의 수를 줄일 수 있으므로 브라우저에서 불필요한 작업을 많이 줄이고 성능을 크게 개선할 수 있습니다.

페인트 (페인트 포함)

범위 지정 페인팅은 격리의 또 다른 매우 유용한 이점입니다. 페인트 컨테이너는 기본적으로 해당 요소를 자르지만 다른 몇 가지 부작용도 있습니다.

  • 절대 위치 및 고정된 위치 요소의 포함 블록 역할을 합니다. 즉, 모든 하위 요소는 문서와 같은 다른 상위 요소가 아닌 contain: paint가 있는 요소를 기반으로 배치됩니다.
  • 비슷한 컨텍스트가 됩니다. 즉, z-index와 같은 요소가 요소에 영향을 미치고 하위 요소가 새 컨텍스트에 따라 스택됩니다.
  • 새로운 서식 지정 컨텍스트가 됩니다. 즉, 페인트 포함이 있는 블록 수준 요소가 있는 경우 새 독립형 레이아웃 환경으로 취급됩니다. 즉, 요소 외부의 레이아웃은 일반적으로 포함 요소의 하위 요소에 영향을 미치지 않습니다.

크기 (size 포함)

contain: size는 요소의 하위 요소가 상위 요소의 크기에 영향을 미치지 않으며 추론된 크기 또는 선언된 크기가 사용된다는 것을 의미합니다. 따라서 contain: size를 설정했지만 요소의 크기를 직접 또는 flex 속성을 통해 지정하지 않으면 0px x 0px로 렌더링됩니다.

크기 제한은 크기 조정에 하위 요소를 사용하지 않도록 하는 보완 조치이지만 그 자체로는 성능 이점을 많이 제공하지 않습니다.

스타일 (스타일 포함)

요소의 스타일을 변경하면 DOM 트리에 어떤 영향을 미칠지 예측하기 어려울 수 있습니다. 한 가지 예는 CSS 카운터와 같은 경우입니다. 여기서 하위 요소의 카운터를 변경하면 문서의 다른 위치에서 사용되는 동일한 이름의 카운터 값에 영향을 줄 수 있습니다. contain: style가 설정된 경우 스타일 변경사항은 포함 요소를 지나 다시 위로 전파되지 않습니다.

다시 한번 분명히 말하자면 contain: style는 Shadow DOM에서 제공하는 것과 같은 범위 지정된 스타일을 제공하지 않습니다. 여기서 컨테이닝은 스타일이 선언될 때가 아니라 변형될 때 고려되는 트리의 부분을 제한하는 것에 관한 것입니다.

엄격한 콘텐츠 격리

contain: layout paint와 같은 키워드를 결합하여 이러한 동작만 요소에 적용할 수도 있습니다. 하지만 contain은 다음 두 가지 추가 값도 지원합니다.

  • contain: strictcontain: size layout paint와 동일한 의미입니다.
  • contain: contentcontain: layout paint와 동일한 의미입니다.

엄격한 포함은 요소의 크기를 미리 알고 있거나 크기를 예약하려는 경우에 유용하지만, 크기를 지정하지 않고 엄격한 포함을 선언하면 암시된 크기 포함으로 인해 요소가 0x0 픽셀 상자로 렌더링될 수 있습니다.

반면 콘텐츠 제한은 상당한 범위 개선을 제공하지만 요소의 크기를 사전에 알거나 지정할 필요가 없습니다.

두 가지 중 기본적으로 사용해야 하는 것은 contain: content입니다. contain: content이 요구사항에 충분히 강하지 않은 경우 엄격한 격리를 일종의 탈출구로 간주해야 합니다.

진행 상황을 알려주세요

컨테이너는 페이지 내에서 격리하려는 항목을 브라우저에 표시하는 좋은 방법입니다. Chrome 52 이상에서 사용해 보고 의견을 알려주세요.