Chrome 52의 CSS 포함

요약

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

CSS 포함 이전: 레이아웃에 59.6ms가 걸림 후: 레이아웃에 0.05밀리초가 걸림

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

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

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

include 속성

웹 앱 또는 복잡한 사이트를 만들 때 성능상의 주요 문제는 스타일, 레이아웃 및 페인트의 효과를 제한하는 것입니다. 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는 새로운 속성으로, 다음과 같은 4개의 값을 지원하는 '포함' 키워드를 사용합니다.

  • layout
  • paint
  • size
  • style

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

레이아웃 (포함: 레이아웃)

레이아웃 포함은 아마도 contain: paint와 함께 포함의 가장 큰 이점일 것입니다.

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

여기에서 격리를 활성화하면 전체 문서가 아닌 소수의 요소로 줄여 브라우저의 불필요한 작업을 줄이고 성능을 크게 개선할 수 있습니다.

페인트 (포함: 페인트)

페인트 범위 지정은 억제의 또 다른 매우 유용한 이점입니다. 페인트 억제는 기본적으로 문제의 요소를 클립하지만, 몇 가지 다른 부작용도 있습니다.

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

크기 (포함: 크기)

contain: size의 의미는 요소의 하위 요소가 상위 요소의 크기에 영향을 미치지 않으며, 추론되거나 선언된 크기가 사용됩니다. 따라서 contain: size를 설정하려고 했지만 직접 또는 가변 속성을 통해 요소의 크기를 지정하지 않은 경우 0x0픽셀로 렌더링됩니다.

크기 포함은 크기 조정을 위해 하위 요소에 의존하지 않도록 하기 위한 실제로 벨트와 브레이스를 위한 조치이지만, 그 자체로는 큰 성능 이점을 제공하지 않습니다.

스타일 (포함: 스타일)

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

명확히 말하자면, contain: style가 제공하지 않는 것은 Shadow DOM에서 얻을 수 있는 범위 지정 스타일 지정입니다. 여기서 포함은 순전히 스타일이 선언될 때가 아니라 스타일 변경 시 고려 중인 트리의 부분을 제한하는 것입니다.

엄격한 콘텐츠 격리

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

  • contain: strictcontain: size layout paint와 같은 의미입니다.
  • contain: contentcontain: layout paint와 같은 의미입니다.

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

반면에 콘텐츠 포함은 범위를 크게 개선할 수 있지만 요소의 크기를 미리 알거나 지정할 필요는 없습니다.

두 가지 중 contain: content가 기본적으로 사용하도록 되어 있습니다. contain: content가 요구에 비해 충분히 강력하지 않을 때는 엄격한 격리를 이스케이프 해치로 취급해야 합니다.

진행 상황을 알려주세요.

억제는 여러분이 페이지 내에서 격리하고자 하는 대상을 브라우저에 알리는 좋은 방법입니다. Chrome 52 이상에서 사용해 보고 방법을 알려주세요.