1. 소개
최신 CSS 렌더러는 웹페이지를 빠르고 효율적으로 렌더링하기 위해 다양한 복잡한 최적화를 수행합니다. 하지만 이러한 최적화를 적용하는 데는 적지 않은 초기 비용이 들 수 있어, 페이지의 반응성에 부정적인 영향을 줄 수 있습니다.
하지만, 요소를 새로운 레이어로 설정하는 작업은 비교적 비용이 많이 드는 작업으로, transform 애니메이션 시작을 눈에 띄게 지연시킬 수 있습니다.
이 명세서에서 정의한 will-change 속성을 사용하면, 작성자가 미리 어떤 속성이 미래에 변경될 가능성이 있는지 선언하여, UA가 해당 최적화를 미리 준비할 수 있게 합니다. 이렇게 하면 실제 변경이 발생할 때, 페이지가 빠르게 업데이트됩니다.
1.1. 값 정의
이 명세서는 [CSS2]의 CSS 속성 정의 규약과 [CSS-VALUES-3]의 값 정의 문법을 따릅니다. 이 명세서에서 정의되지 않은 값 유형은 CSS Values & Units [CSS-VALUES-3]에서 정의됩니다. 다른 CSS 모듈과의 결합으로 이러한 값 유형의 정의가 확장될 수 있습니다.
각 속성 정의에 명시된 속성별 값 외에도, 이 명세서에서 정의한 모든 속성은 CSS-전역 키워드를 속성값으로 허용합니다. 가독성을 위해 명시적으로 반복하지 않았습니다.
1.2. will-change 올바르게 사용하기
will-change 속성은 모든 성능 힌트와 마찬가지로 “올바르게” 사용하는 방법을 배우기 어렵지만, 특히 직접적으로 감지할 수 있는 효과가 거의 없기 때문입니다. 하지만 will-change를 잘 사용하는 데 도움이 될 수 있는 몇 가지 간단한 “해야 할 것과 하지 말아야 할 것”이 있습니다.
너무 많은 속성이나 요소에 will-change를 남발하지 마세요
will-change 속성을 처음 접하면 다음과 같은 코드가 좋은 방법이라고 생각하기 쉽습니다:
* { will-change: transform, opacity /* , ... */; }
어쨌든 이 코드는 브라우저에게 모든 것을 미리 최적화하라고 지시하니 좋다고 생각할 수 있습니다.
잘못된 생각입니다. 브라우저는 이미 모든 것을 최적화하기 위해 최대한 노력합니다. 명시적으로 그렇게 하라고 해도 도움이 되지 않으며, 오히려 심각한 해를 끼칠 수 있습니다; will-change에 연관된 강력한 최적화는 기기의 많은 자원을 사용하게 되고, 이렇게 남발하면 페이지가 느려지거나 심지어 크래시를 유발할 수 있습니다.
또한, will-change에는 일부 부작용이 있으므로, 실제로 모든 요소에 이런 부작용을 원할 가능성은 매우 낮습니다.
스타일시트에서 will-change를 신중하게 사용하세요
will-change를 스타일시트에서 직접 사용하면, 해당 요소들이 항상 곧 변경될 것임을 의미하게 됩니다. 이는 보통 실제로 의도한 바가 아닙니다; 대신 will-change는 변경이 발생하기 전후에 스크립트를 통해 켜고 끄는 방식으로 사용하는 것이 좋습니다(자세한 내용은 변경이 끝난 요소에 자원을 낭비하지 마세요 참고). 하지만 will-change를 스타일시트에서 직접 사용하는 것이 적합한 경우도 있습니다.
body > .sidebar { will-change: transform; /* 사용자가 요청할 때 transform으로 슬라이드됩니다. */ }
이처럼 소수의 요소에 한정하면, 최적화가 실제로 자주 사용되지 않더라도 큰 문제가 되지 않습니다.
.cats-flying-around-the-screen { will-change: left, top; }
will-change가 효과를 발휘할 충분한 시간을 주세요
또 다른 흔한 잘못된 패턴은, will-change를 애니메이션이나 속성 변화를 시작하기 직전에 적용하는 것입니다. 실제로 대부분의 최적화는 적용에 시간이 필요하므로, 이렇게 하면 준비할 시간이 부족해서 will-change가 거의 효과를 내지 못합니다. 실제로 변경이 일어나기 전에 미리 예측하여 will-change를 미리 설정하는 방법을 찾으세요.
.element { transition: opacity .2s; opacity: 1; } .element:hover { will-change: opacity; } .element:active { opacity: .3; }
하지만 이런 규칙은 만약 효과가 hover에서 바로 발생한다면 소용없습니다. 이런 경우에도 보통 액션을 미리 예측할 방법이 있습니다. 예를 들어, 상위 요소에 hover가 걸리면 충분한 선행 시간을 줄 수 있습니다:
.element { transition: opacity .2s; opacity: 1; } .container:hover > .element { will-change: opacity; } .element:hover { opacity: .3; }
변경이 끝난 요소에 자원을 낭비하지 마세요
일부 속성 변경을 위한 브라우저의 최적화는 비용이 많이 들기 때문에, 브라우저는 일반적으로 가능한 한 빨리 이를 제거하고 정상 동작으로 되돌립니다. 하지만 will-change는 이러한 동작을 무시하고, 브라우저가 더 오래 최적화를 유지하도록 합니다.
따라서 will-change를 요소에 추가할 때, 특히 스크립트로 추가하는 경우에는 요소의 변경이 끝나면 꼭 제거하여 브라우저가 최적화에 사용된 자원을 회수할 수 있도록 해야 합니다.
2. 미래 동작 힌트: will-change 속성
이름: | will-change |
---|---|
값: | auto | <animateable-feature># |
초기값: | auto |
적용 대상: | 모든 요소 |
상속: | no |
백분율: | 해당 없음 |
계산된 값: | 명시된 값 |
표준 순서: | 문법에 따름 |
애니메이션 유형: | 애니메이션 불가 |
<animateable-feature> = scroll-position | contents | <custom-ident>
will-change 속성은 렌더링에 대한 힌트를 사용자 에이전트(UA)에 제공하여, 작성자가 해당 요소에 어떤 종류의 변경을 수행할 것으로 예상하는지 알립니다. 이를 통해 UA는 이러한 변경을 매끄럽게 렌더링하기 위한 필요한 최적화를 미리 수행할 수 있어, 실제로 해당 기능을 변경하거나 애니메이션할 때 “버벅임”을 피할 수 있습니다.
값의 의미는 다음과 같습니다:
- auto
- 특별한 의도가 없음을 표현합니다. UA는 일반적으로 사용하는 휴리스틱과 최적화를 적용하면 됩니다.
- scroll-position
-
작성자가 가까운 미래에 해당 요소의 스크롤 위치를 변경하거나 애니메이션할 것으로 예상함을 나타냅니다.
예를 들어, 브라우저는 일반적으로 스크롤 가능한 요소에 대해 "스크롤 윈도우" 내의 콘텐츠와 그 주변 일부만 렌더링하며, 렌더링을 생략하여 메모리와 시간 절약 효과를 얻으면서도 스크롤이 부드럽게 보이도록 균형을 잡습니다. 이 값을 신호로 받아, 브라우저가 스크롤 윈도우 주변의 렌더링 범위를 확장해 더 길거나 빠른 스크롤도 부드럽게 처리할 수 있습니다.
- contents
-
작성자가 가까운 미래에 해당 요소의 콘텐츠에 대해 애니메이션하거나 변화를 줄 것으로 예상함을 나타냅니다.
예를 들어, 브라우저는 대부분의 요소가 자주 변하지 않거나 위치만 바뀌는 경우가 많기 때문에 시간이 지나면서 요소의 렌더링을 "캐시"합니다. 하지만 요소의 콘텐츠가 지속적으로 변경된다면, 캐시를 유지하는 건 시간 낭비가 될 수 있습니다. 브라우저는 이 값을 신호로 받아 해당 요소에 대한 캐싱을 덜 적극적으로 하거나, 아예 캐시하지 않고 계속 처음부터 다시 렌더링할 수 있습니다.
이 값은 주로 JS 기반 콘텐츠 애니메이션(초당 여러 번 요소의 콘텐츠가 바뀌는 경우)의 최적화를 위해 쓰입니다. 이런 최적화는 선언적 애니메이션을 사용할 때 브라우저가 이미 자동으로 해줍니다.
참고: 이 값은 해당 요소의 전체 하위 트리에도 적용될 수 있습니다. 브라우저가 모든 자손이 어떤 방식으로든 변할 것으로 기대해야 함을 의미하기 때문입니다. 문서 트리에서 "상위" 요소에 이 값을 사용하면 페이지 성능에 매우 나쁜 영향을 줄 수 있으니, 최대한 "하위" 요소에만, 가능한 한 적은 부분에만 사용하세요.
- <custom-ident>
-
<custom-ident>가 내장 CSS 속성 이름과 ASCII 대소문자 구분 없이 일치하면,
작성자가 해당 속성 명으로 요소의 속성을 가까운 미래에 변경하거나 애니메이션할 것으로 예상함을 의미합니다.
지정한 속성이 약어(shorthand)라면,
그 약어가 확장하는 모든 개별 속성에 대한 기대를 의미합니다.
예를 들어, will-change: background;를 지정하면 will-change: background-image, background-position, ...과 동일하며, background가 확장하는 모든 속성에 적용됩니다.
여기서 사용하는 <custom-ident> 생성 규칙은 will-change, none, all, auto, scroll-position, contents와, <custom-ident>에서 일반적으로 제외되는 키워드를 제외합니다.
참고: 대부분의 속성은 지정하더라도 아무 효과가 없는 경우가 많습니다. UA가 대부분의 속성 변경에 대해 특별한 최적화를 하지 않기 때문입니다. 그래도 지정해도 안전합니다. 단지 아무 효과가 없을 뿐입니다.
사용자 정의 속성(custom property)을 지정해도 아무 효과 없어야 하며, 사용자 정의 속성을 통해 발생하는 효과는 아래 규칙에서 "속성의 비초기값(non-initial value)이 무언가를 유발"하는 조건에 해당하지 않습니다.
참고: 속성으로 인식되지 않는 값을 지정해도 괜찮으며, 단순히 아무 효과가 없습니다. 이는 일부 UA에만 존재하는 새로운 속성을 지정해도, 해당 속성을 모르는 구형 UA에는 부정적인 영향이 없도록 해줍니다.
예를 들어, transform이 비초기값으로 설정된 요소는 일반 요소와 다르게 처리되며, 예를 들어 자체 “GPU 레이어”로 렌더링하거나, transform이 만들어내는 변환을 빠르게 처리할 수 있는 방식으로 처리할 수 있습니다. 브라우저는 transform 값을 신호로 받아 요소가 변환되기 전에 미리 레이어로 승격시켜, 이전/새 레이어 렌더링 지연을 피할 수 있습니다.
어떤 속성의 비초기값이 요소에 stacking context를 생성한다면, 해당 속성을 will-change로 지정하면 stacking context를 생성해야 합니다.
어떤 속성의 비초기값이 요소에 절대 위치 요소의 containing block을 생성한다면, 해당 속성을 will-change로 지정하면 절대 위치 요소의 containing block을 생성해야 합니다.
어떤 속성의 비초기값이 고정 위치 요소의 containing block을 생성한다면, 해당 속성을 will-change로 지정하면 고정 위치 요소의 containing block을 생성해야 합니다.
어떤 속성의 비초기값이 요소의 렌더링 전략(예: 텍스트 안티에일리어싱 방식)을 변경한다면, UA는 해당 속성이 will-change에 지정된 경우에도 결국 변경될 때 갑작스러운 렌더링 변화가 없도록 미리 대체 렌더링 전략을 적용해야 합니다.
예를 들어, opacity를 1이 아닌 값으로 설정하면 stacking context가 생성됩니다. 따라서 will-change: opacity를 지정하면 opacity가 현재 1이라도 stacking context가 생성됩니다.
will-change 속성은 stacking context와 containing block 생성 외에는 요소에 직접적인 영향을 주지 않습니다. 오직 UA에 렌더링 힌트를 주는 역할만 하며, 특정 변경이 실제로 시작되기 전에 비용이 많이 드는 최적화를 미리 준비할 수 있게 합니다.
3. 보안 고려 사항
이 문서에 대해 제기된 보안 문제는 없습니다.
4. 개인정보 보호 고려 사항
이 문서에 대해 제기된 개인정보 보호 문제는 없습니다.
5. 감사의 글
Benoit Girard에게 will-animate 속성을 처음 제안해주고, 초기 설계 작업을 많이 해주신 점에 감사드립니다.
6. 변경 사항
2015년 12월 3일 CR 이후 변경 사항:
-
보안 및 개인정보 보호 섹션 추가
-
알 수 없는 값은 허용되며, 아무 효과가 없다는 점 명확히 함
-
속성 이름 매칭에 ASCII 대소문자 구분 없음 명시
-
will-change 속성의 애니메이션 유형을 애니메이션 불가로 변경
-
propdef 테이블에서 "Media:" 항목 삭제 (다른 CSS 명세서와 동일)
-
사소한 편집적 명확화, 마크업 개선
2014년 4월 29일 WD 이후 변경 사항:
-
will-change를 올바르게 사용하는 방법 안내 섹션 추가
-
약어(shorthand)의 동작 명시