요약
새로운 CSS Containment 속성을 사용하면 개발자가 브라우저의 스타일, 레이아웃, 페인트 작업의 범위를 제한할 수 있습니다.
이 요소에는 몇 가지 값이 있으며 구문은 다음과 같습니다.
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: strict
는contain: size layout paint
와 동일한 의미입니다.contain: content
은contain: layout paint
와 동일한 의미입니다.
엄격한 포함은 요소의 크기를 미리 알고 있거나 크기를 예약하려는 경우에 유용하지만, 크기를 지정하지 않고 엄격한 포함을 선언하면 암시된 크기 포함으로 인해 요소가 0x0 픽셀 상자로 렌더링될 수 있습니다.
반면 콘텐츠 제한은 상당한 범위 개선을 제공하지만 요소의 크기를 사전에 알거나 지정할 필요가 없습니다.
두 가지 중 기본적으로 사용해야 하는 것은 contain: content
입니다. contain: content
이 요구사항에 충분히 강하지 않은 경우 엄격한 격리를 일종의 탈출구로 간주해야 합니다.
진행 상황을 알려주세요
컨테이너는 페이지 내에서 격리하려는 항목을 브라우저에 표시하는 좋은 방법입니다. Chrome 52 이상에서 사용해 보고 의견을 알려주세요.