목차
will-change 속성이란?
will-change css 속성은 요소의 변화를 미리 브라우저에게 알려주어 브라우저가 미리 최적화를 하게 할 수 있는 속성입니다.
사용법
will-change: auto; // 기본 값
will-change: scroll-position; // 요소의 스크롤의 위치가 변한다는것을 미리 알림
will-change: contents; // 요소의 내용이 바뀐다는 것을 미리 알림
will-change: transform; // 이렇게 CSS 속성을 직접 명시할 수 있습니다.
will-change: opacity;
/* 이렇게 적게되면 어느 부분에 적용될까요?*/
will-change: background;
/* 속기로 적게된 속성은 아래와 같이 모든 것에 적용하는 것과 동일합니다.*/
will-change: background-image;
will-change: background-position;
will-change: background-size; 등등등
언제 사용해야 할까?
이 속성은 언제사용하면 좋을까요?
우리는 웹사이트 개발을 하다보면 JavaScript를 이용하여 CSS를 제어하는 상황이 생길 수 있습니다.
한 두번이야 괜찮지만 같은 엘리먼트를 계속해서 변형시키는 작업이면 어떨까요?? 브라우저가 CSS의 변형에 따라 계산을 해서 화면에 렌더링을 하는데 시간이 오래 걸릴 것입니다.
예를 들어, scroll에 따라 element의 transform: translateX 속성을 변경하는 일이 있을 수 있습니다.
그러면 사용자가 스크롤을 할 때마다 그 값에 따라서 css가 계속해서 바뀔 것입니다. 이런 경우 브라우저는 계속해서 바뀌는 translateX 값에 따라 계속해서 요소를 계산해서 렌더링을 할 것입니다. 이런 경우에 will-change를 사용하면 조금이나마 최적화에 도움이 될 것입니다.
한번 예시를 들어보겠습니다.
See the Pen Untitled by dnjs2618 (@dnjs2618) on CodePen.
위의 경우에는 will-change를 쓰면 브라우저가 최적화하기에 좋아보입니다.
그러면 will-change가 브라우저에게 미리 변화를 알려주어 최적화를 진행할 수 있다면 그냥 전역 상태에 모든 변화를 걸어버리는게 좋을까요? 아래와 같이요.
* {
will-change: oacity, left, top, transform;
}
이렇게하면 브라우저는 최적화하기 위해서 많은 시간을 들이기 때문에 최적화가 되기보다 되려 페이지의 속도가 저하될 수 있습니다. 그러면 이것을 방지하기 위해서 어떻게 작성하면 좋을까요?
특정 엘리먼트에만 넣는방법
/*위에 보여드린 예시에서 특정 부분입니다.*/
.slide-wrapper {
will-change: transform;
/* 이런식으로 사용자에게 빠르게 반응해야 하는 페이지의 소수의
지속적 UI 요소에 대해 will-change를 지정하는 것은 적절합니다.*/
}
변화가 일어날 것 같을 때만 미리 will-change 넣고 auto로 되돌리기
// 아래는 MDN에 나와있는 예제입니다.
var el = document.getElementById('element');
// Set will-change when the element is hovered
el.addEventListener('mouseenter', hintBrowser);
el.addEventListener('animationEnd', removeHint);
function hintBrowser() {
// The optimizable properties that are going to change
// in the animation's keyframes block
this.style.willChange = 'transform, opacity';
}
function removeHint() {
this.style.willChange = 'auto';
}
이제 아래에서는 주의할 점에 대해서 알아볼 것입니다.
주의할 점
will-change가 마냥 좋지만은 않습니다.
MDN 문서에 보면 will-change로 인한 최적화는 성능 비용이 커서 요구 되기 전에 미리 실행시켜서 페이지의 반응성이 증가될 수 있다고 하면서 5가지의 조언이 남겨져있습니다.
우선 간단하게 살펴보고 아래에서 자세하게 설명하겠습니다.
- 너무 많은 요소에 will-change를 적용하지 마라.
- 아껴서 사용하라.
- 최적화하기 위해 서둘러 will-change를 적용하지 마라.
- 브라우저가 작업할 시간을 충분히 줘라.
- will-change 속성은 스택 Context가 미리 생기기 때문에 요소의 시각적인 모양에 영향을 미칠 수 있다.
1. 너무 많은 요소에 will-change를 적용하지 마라.
-> 이미 브라우저는 최적화를 하기 위해 모든 것을 시도하고 있는데 거기에서 will-change와 같이 강한 최적화는 기기 자원을 많이 소모할 것이며 과도한 사용은 페이지 속도를 느리게 하거나 엄청난 자원을 소비할 수 있다.
2. 아껴서 사용하라.
-> 브라우저가 만드는 최적화의 기본 행동은 가능한 바로 최적화를 제거하고 기본 상태로 돌리는 것이다. 그러나 will-change를 스타일시트에 직접 추가하는 것은 목표요소가 곧 변경되어 더 오랫동안 최적화를 유지하라는 것이기에 기본상태로 돌리기 까지 시간이 걸린다.
3. 최적화 하기위해 서둘러 will-change를 적용하지 마라.
-> will-change는 당장의 성능문제를 해결하기 위해 마지막 수단으로 이용하려고 만든 것이다. 성능 문제를 예상해서 굳이 잘 작동중인 웹사이트에 적용할 필요는 없다. 너무 많은 사용은 브라우저가 가능한 변화를 미리 다 준비하려고 하기 때문에 과도한 메모리 사용과 복잡한 렌더링으로 열악한 성능을 이끌 것이다.
4. 브라우저가 작업할 시간을 충분히 줘라
-> user-agent(브라우저)가 변경가능한 속성을 미리 알 수 있게 하도록 고안된 속성이기에 브라우저는 실제 속성변화가 발생하기 전에 속성에 요구되는 최적화를 미리 적용하는 것을 선택할 수 있다. 브라우저가 실제 최적화를 할 수 있는 시간을 주는 것이 중요하다! 변화가 발생하기 전에라도 그 변화를 예상할 방법을 찾아 will-change를 설정하라.
만약에 hover시에 opacity가 바뀔 때 제가 will-change를 걸고 싶어졌다고 치고 코드를 작성하겠습니다.
.element {
transition: opacity .2s linear; opacity: 1;
}
.container:hover > .element {
will-change: opacity;
}
.element:hover {
opacity: .3;
}
/* 이 경우에는 will-change 효과가 전혀 없습니다.
아래에 속성이 변경되기 직전에 will-change 요소를 넣었기 때문에(container hover 시에 will-change)
will-change 최적화를 하기 위한 시간이 충분하지 않습니다.
그래서 무언가가 바뀔것이라고 미리 예측하는 방법을 찾아서 설정하는 것이 좋습니다.
*/
5. will-change 속성은 스택 Context가 미리 생기기 때문에 요소의 시각적인 모양에 영향을 미칠 수 있다.
-> 브라우저에서 opacity 값이 1인 경우에는 스택 Context에 값이 생기지 않습니다. 그러나 opacity가 1이 아닐 경우에는
stack Context가 생깁니다. 그런데 will-change: opacity를 주게 되면 opacity가 1이어도 stack Context가 생성됩니다.
will-change는 정말 필요할 때가 아니면 가급적이면 사용을 안하는 것이 좋겠습니다. 그러나 위에서 보여드린 예시와 같이 저런 슬라이드를 구현하게 된다면 한번 쯤 사용해보시면 좋을 것 같습니다. 주의사항을 잘 읽어보시고 해당하지 않는다면 사용하시면 될것같아요.
긴 글 읽어주셔서 감사합니다.
'CSS' 카테고리의 다른 글
CSS Rendering - Float (코드 스피츠 76회차를 보고 정리) (0) | 2022.07.11 |
---|---|
CSS Rendering - 코드 스피츠 76회차를 보고나서 정리 (0) | 2022.07.10 |