will-change

브라우저에 곧 변경될 속성을 미리 알려 최적화를 준비하게 합니다. 남용하면 오히려 성능이 저하되므로 필요한 경우에만 사용하고, wca로 리셋합니다.

클래스 목록

클래스CSS설명
wcawill-change: auto기본값. 브라우저가 자동으로 최적화를 판단
wctwill-change: transformtransform 변경 예고(GPU 가속 힌트)
wcowill-change: opacityopacity 변경 예고
wcspwill-change: scroll-position스크롤 위치 변경 예고
wccwill-change: contents내용(contents) 변경 예고

시각 데모 — 왜 아무 변화도 없는가

두 상자는 마우스를 올리면 똑같이 커집니다. 오른쪽에만 힌트 클래스가 붙어 있지만 화면상 차이는 전혀 없습니다. 이 속성은 모양을 바꾸는 속성이 아니라 브라우저에게 준비를 시키는 예고이기 때문입니다.

tall300msease

힌트 없음

tall300msease wca

힌트 있음 — 보이는 차이 없음

차이는 화면이 아니라 브라우저 내부에 있습니다. 힌트를 받은 요소는 미리 별도 레이어로 승격되어 첫 프레임이 매끄러워질 수 있지만, 그 대가로 메모리를 계속 차지합니다.

사용 예시

will-change는 브라우저가 별도의 레이어를 생성하여 GPU 가속을 준비하게 합니다. 애니메이션이 끝나면 반드시 리셋하세요.

<!-- Atomic CSS supports will-change: auto (wca) —
     the browser default / reset value. -->

<!-- Reset will-change after an animation finishes -->
<div class="wca">
  Element with will-change reset to auto
</div>

<!-- Tip: for a specific hint like will-change: transform,
     the browser also auto-optimizes elements that already have
     a transition/animation, so tall200msease + hover-ts1-1
     already gets GPU acceleration without a will-change hint. -->
<div class="tall200msease hover-ts1-1">
  Card that scales up on hover (auto-optimized)
</div>

클래스별 상세

wcawill-change: auto

기본값이자 사실상의 해제 값입니다. 브라우저가 알아서 판단하게 두며, 애니메이션이 끝난 뒤 힌트를 걷어낼 때 이 클래스로 되돌립니다. 이 문서 세트에서 실제 클래스로 제공되는 값이기도 합니다.

<!-- Drop the hint again once the animation is done -->
<div class="wca tall300msease">
  Back to letting the browser decide.
</div>

wctwill-change: transform

변형이 곧 바뀔 것이라고 예고합니다. 드로어가 열리기 직전, 캐러셀이 넘어가기 직전처럼 무거운 이동이 예정된 순간에만 붙였다가 끝나면 즉시 걷어냅니다.

<!-- Panel that is about to slide in from the right -->
<aside class="wct tall300msease pf t0 r0 h100vh w30rem bg18181B">
  Remove the hint as soon as the slide finishes.
</aside>

wcowill-change: opacity

투명도가 곧 바뀔 것이라고 예고합니다. 화면 전체를 덮는 오버레이가 서서히 나타나는 연출처럼 넓은 면적의 투명도 변화에 한해 의미가 있습니다.

<!-- Full-screen overlay fading in: a large area of opacity -->
<div class="wco tall300msease o0 pf t0 l0 w100p h100vh bg0-0-0-50"></div>

wcspwill-change: scroll-position

스크롤 위치가 곧 바뀔 것이라고 예고합니다. 긴 목록을 코드로 스크롤하기 직전에 붙이며, 스크롤이 멈추면 해제합니다.

<!-- Long list about to be scrolled programmatically -->
<div class="wcsp oya h40rem">
  <p class="fs14px c71717A">Thousands of rows.</p>
</div>

wccwill-change: contents

요소의 내용 자체가 자주 바뀔 것이라고 예고합니다. 브라우저가 이 요소의 그림을 캐싱하지 않게 하므로, 매 프레임 내용이 갈리는 캔버스형 영역에만 씁니다.

<!-- Region whose content is repainted every frame -->
<div class="wcc w100p h30rem bg18181B br8px">
  Live chart output.
</div>

실전 예시 — 드로어 열기 직전에만 힌트 주기

힌트를 처음부터 마크업에 박아 두지 않고, 열기 버튼에 마우스가 닿는 순간 코드로 붙였다가 애니메이션이 끝나면 떼어내는 흐름입니다. 이것이 이 속성을 쓰는 유일하게 안전한 방식입니다.

<!-- Markup ships WITHOUT the hint -->
<button id="open-drawer" class="bg6366F1 cFFFFFF br6px py12px px16px fs14px">
  Open
</button>

<aside id="drawer" class="tall300msease pf t0 r0 h100vh w30rem bg18181B">
  <p class="p2rem fs14px cA1A1AA">Drawer contents</p>
</aside>

<!-- JS adds the hint on pointer approach, removes it after the animation:
     open.addEventListener('pointerenter', () => drawer.classList.add('wct'));
     drawer.addEventListener('transitionend', () => drawer.classList.remove('wct'));
     Leaving 'wct' on permanently would pin a compositor layer for the whole
     session, which costs memory and can slow the page down. -->

팁 / 주의사항

절대로 계속 켜 두지 말 것

힌트가 붙은 요소는 별도 레이어로 승격되어 그 메모리를 계속 붙들고 있습니다. 목록의 모든 항목에 붙이면 레이어가 수백 개 생겨 오히려 스크롤이 끊깁니다. 반드시 필요한 순간에만 붙였다가 곧바로 해제하세요.

마우스를 올린 다음에 붙이면 이미 늦다

브라우저가 준비할 시간을 주려고 있는 속성인데, 애니메이션이 시작되는 바로 그 순간에 붙이면 준비할 틈이 없습니다. 효과가 없을 뿐 아니라 레이어 생성 비용만 애니메이션 도중에 발생합니다.

대부분의 트랜지션에는 필요 없다

변형과 투명도 애니메이션은 브라우저가 이미 알아서 최적화합니다. 실제로 프레임이 끊기는 것을 측정으로 확인한 뒤에 마지막 수단으로 쓰세요.

쌓임 맥락이 새로 생겨 겹침 순서가 바뀐다

힌트가 붙은 요소는 새로운 쌓임 맥락을 만듭니다. 갑자기 드롭다운이 다른 요소 뒤로 숨거나 고정 요소가 이상하게 잘린다면 이 속성이 원인일 수 있습니다.

예고한 속성과 실제 바꾸는 속성이 같아야 한다

변형을 예고해 놓고 폭과 높이를 바꾸면 준비는 헛수고가 되고 레이아웃 재계산은 그대로 일어납니다. 예고와 실제 변경 대상을 반드시 일치시키세요.

남용 금지 -- 성능 저하 원인

will-change를 모든 요소에 적용하면 브라우저가 불필요한 레이어를 대량 생성하여 메모리 소비가 증가하고 오히려 성능이 나빠집니다.

애니메이션 직전에 추가, 이후에 제거

JavaScript로 애니메이션 시작 직전에 will-change를 추가하고, 완료 후 wca로 리셋하는 것이 이상적입니다.

최후의 수단으로 사용

대부분의 CSS 트랜지션과 애니메이션은 브라우저가 자동으로 최적화합니다. will-change는 성능 문제가 확인된 경우에만 적용하세요.