본문 바로가기
UX 개발/CSS

CSS `will-change` 완전 이해하기: 언제 쓰고, 어떻게 써야 할까?

반응형

 

웹 애니메이션이나 인터랙션을 만들다 보면 “이 요소가 더 부드럽게 움직였으면 좋겠다”는 생각이 들 때가 있습니다. 이때 한 번쯤 보게 되는 CSS 속성이 바로 will-change입니다.

이 속성은 이름만 보면 뭔가 대단한 성능 최적화 옵션처럼 느껴지지만, 실제로는 꽤 조심해서 써야 하는 “브라우저에게 주는 힌트”에 가깝습니다. 잘 쓰면 도움이 될 수 있지만, 무분별하게 쓰면 오히려 성능이 나빠질 수도 있습니다.

이번 글에서는 will-change가 정확히 무엇인지, 왜 존재하는지, 언제 써야 하는지, 그리고 실제로 어떻게 사용하는지를 차근차근 정리해보겠습니다.


will-change란?

will-change는 요소에 어떤 변화가 곧 일어날 것이라고 브라우저에 미리 알려주는 CSS 속성입니다.

즉, 개발자가 브라우저에게 이렇게 말하는 셈입니다.

“이 요소는 곧 transform이나 opacity 같은 속성이 바뀔 예정이니, 미리 준비해 둬.”

브라우저는 이 힌트를 바탕으로 렌더링 최적화를 미리 수행할 수 있고, 경우에 따라 애니메이션이나 전환이 더 부드럽게 동작할 수 있습니다.

기본 예시는 아주 단순합니다.

.box {
  will-change: transform;
}

위 코드는 .box 요소의 transform 값이 곧 바뀔 수 있으니 브라우저가 사전 준비를 하도록 힌트를 주는 코드입니다.


왜 필요한가?

브라우저는 화면을 그릴 때 단순히 HTML과 CSS를 한 번에 처리하는 것이 아니라, 여러 단계를 거쳐 렌더링합니다. 어떤 속성이 바뀌느냐에 따라 다시 레이아웃을 계산하거나, 다시 페인트를 하거나, 합성 단계만 다시 수행할 수도 있습니다.

이때 transform이나 opacity처럼 비교적 효율적으로 처리할 수 있는 속성이 자주 바뀌는 경우, 브라우저가 미리 준비해두면 애니메이션이 더 자연스럽게 보일 가능성이 있습니다.

즉, will-change는 성능을 직접 높여주는 마법 같은 속성이 아니라, 브라우저가 더 나은 최적화를 할 수 있도록 사전 정보를 제공하는 역할을 합니다.


자주 사용하는 값

will-change에는 보통 다음과 같은 값이 들어갑니다.

1. transform

요소의 이동, 회전, 확대/축소 같은 변형이 일어날 때 사용합니다.

.card {
  will-change: transform;
}

2. opacity

투명도 변화가 예정되어 있을 때 사용합니다.

.modal {
  will-change: opacity;
}

3. 여러 값 함께 사용

.panel {
  will-change: transform, opacity;
}

슬라이드되면서 동시에 페이드 효과가 들어가는 UI에서 자주 볼 수 있는 형태입니다.

4. auto

기본값입니다. 특별한 최적화 힌트를 주지 않는 일반 상태라고 보면 됩니다.

.element {
  will-change: auto;
}

실제 사용 예제

가장 이해하기 쉬운 예시는 버튼을 눌렀을 때 박스가 옆으로 이동하는 경우입니다.

HTML

<div class="box"></div>
<button id="moveBtn">Move</button>

CSS

.box {
  width: 120px;
  height: 120px;
  background: royalblue;
  transition: transform 0.4s ease;
}

.box.animate {
  will-change: transform;
  transform: translateX(200px);
}

JavaScript

const box = document.querySelector('.box');
const button = document.querySelector('#moveBtn');

button.addEventListener('click', () => {
  box.classList.add('animate');

  box.addEventListener(
    'transitionend',
    () => {
      box.style.willChange = 'auto';
    },
    { once: true }
  );
});

이 예제는 어떻게 동작할까?

버튼을 클릭하면 .boxanimate 클래스가 추가되고, transform: translateX(200px)가 적용되면서 요소가 오른쪽으로 이동합니다.

이때 will-change: transform이 함께 적용되어 브라우저는 해당 요소의 transform 변화에 대비할 수 있습니다. 결과적으로 상황에 따라 더 부드러운 애니메이션이 가능해집니다.

그리고 애니메이션이 끝난 뒤에는 will-change를 다시 auto로 돌려놓습니다. 이 부분이 중요합니다. will-change를 계속 유지하면 불필요한 리소스를 점유할 수 있기 때문입니다.


더 나은 사용 방식

실무에서는 will-change를 CSS에 상시 넣어두기보다, 변화가 일어나기 직전에 적용하고 끝나면 제거하는 방식이 더 낫습니다.

예를 들어 다음처럼 작성할 수 있습니다.

const box = document.querySelector('.box');
const button = document.querySelector('#moveBtn');

button.addEventListener('click', () => {
  box.style.willChange = 'transform';

  requestAnimationFrame(() => {
    box.style.transform = 'translateX(200px)';
  });

  box.addEventListener(
    'transitionend',
    () => {
      box.style.willChange = 'auto';
    },
    { once: true }
  );
});

이 방식이 더 좋은 이유는 분명합니다.

첫째, 정말 변화가 필요할 때만 will-change를 적용합니다.
둘째, 애니메이션이 끝나면 즉시 해제합니다.
셋째, 브라우저가 불필요하게 최적화 상태를 오래 유지하지 않도록 할 수 있습니다.


언제 사용하면 좋을까?

will-change는 모든 요소에 붙이는 속성이 아닙니다. 아래처럼 성능 민감도가 높은 인터랙션에서 제한적으로 사용하는 것이 맞습니다.

사용하기 좋은 경우

  • 큰 요소에 hover 애니메이션이 들어가는 경우
  • 사이드 메뉴가 슬라이드로 열리고 닫히는 경우
  • 카드 드래그 인터랙션이 있는 경우
  • 복잡한 UI 전환에서 transform, opacity가 자주 바뀌는 경우

예를 들어 사이드 패널이 열릴 때 다음처럼 생각할 수 있습니다.

.sidebar {
  transition: transform 0.3s ease;
}

.sidebar.is-opening {
  will-change: transform;
}

즉, “곧 움직일 요소”가 명확할 때만 써야 합니다.


언제 사용하면 안 될까?

이 부분이 더 중요합니다. will-change는 남용하면 오히려 성능이 나빠질 수 있습니다.

대표적으로 좋지 않은 예시는 이런 코드입니다.

* {
  will-change: transform;
}

혹은 아래와 같은 코드도 위험합니다.

.card {
  will-change: transform;
}

이 자체가 무조건 잘못은 아니지만, 만약 .card가 수십 개, 수백 개 존재한다면 이야기가 달라집니다. 브라우저는 많은 요소를 미리 최적화하려고 하면서 메모리를 더 많이 사용하게 되고, 결과적으로 전체 성능이 떨어질 수 있습니다.

즉, will-change는 “많이 쓸수록 좋은 옵션”이 아니라 “꼭 필요한 요소에만 잠깐 쓰는 옵션”입니다.


will-change에 대한 흔한 오해

많은 초급 개발자가 will-change를 보면 “이거 넣으면 무조건 부드러워지겠네”라고 생각합니다. 하지만 그건 사실이 아닙니다.

will-change는 다음과 같은 성격을 가집니다.

  • 성능 보장 옵션이 아니다
  • 브라우저 최적화를 강제하는 기능이 아니다
  • 잘못 쓰면 메모리 사용량만 늘릴 수 있다
  • 애니메이션 성능 문제의 근본 원인을 해결해주지 않는다

애니메이션이 끊긴다면 먼저 확인해야 할 것은 보통 다음과 같습니다.

  • top, left, width, height처럼 비용이 큰 속성을 애니메이션하고 있지는 않은가
  • transform, opacity 중심으로 바꿀 수 없는가
  • 너무 많은 DOM 요소가 동시에 움직이고 있지는 않은가
  • repaint나 layout이 과도하게 발생하고 있지는 않은가

즉, will-change는 마지막 미세 조정에 가까운 도구이지, 구조적으로 잘못된 애니메이션을 구해주는 해결책은 아닙니다.


실무 기준으로 정리하면

실무에서 will-change를 볼 때는 아래 기준으로 판단하면 됩니다.

써도 되는 경우

  • 곧 변화가 일어날 요소가 명확하다
  • transform, opacity 중심의 애니메이션이다
  • 실제로 성능 이슈가 있거나 부드러움 개선이 필요하다
  • 변화 직전에 넣고, 끝난 뒤 제거할 수 있다

피해야 하는 경우

  • 특별한 이유 없이 습관처럼 넣는 경우
  • 많은 요소에 한꺼번에 적용하는 경우
  • 성능 측정 없이 막연히 “좋아 보이니까” 넣는 경우
  • 레이아웃 변경이 큰 속성을 남발하면서 will-change로 해결하려는 경우

결론

will-change는 CSS에서 성능 최적화를 위해 존재하는 속성이지만, 그 정체는 어디까지나 브라우저에게 주는 사전 힌트입니다.

핵심은 간단합니다.

will-change는 필요한 순간에, 필요한 요소에만, 짧게 써야 합니다.

애니메이션 성능을 개선하고 싶다면 먼저 transformopacity를 중심으로 설계를 바꾸고, 그다음 정말 필요한 경우에만 will-change를 추가하는 편이 맞습니다.

무턱대고 전역으로 넣는 것은 최적화가 아니라 오히려 성능 낭비에 가깝습니다.

한 줄로 정리하면 이렇습니다.

will-change는 성능을 위한 힌트이지, 만능 해결책이 아닙니다.

원하시면 다음 단계로 이어서, 이 글을 더 블로그 스타일에 맞게 다듬은 버전이나, 예제 중심의 초급자용 버전으로 다시 써드리겠습니다.

반응형
🖥️ 클라우드 메뉴판 : 디지털팝