반응형

css를 통해 animation을 사용하거나 마우스오버 혹은 특정 버튼을 클릭했을 때 클래스 추가하여 transform을 조정하게 될 경우 영역이 깜빡이거나 잠시 흐려지는 현상을 경험한 적이 있을 것이다.

 

1. CSS핵 (translateZ or translate3d) 사용

위와 같은 부자연스러운 transform, animation 현상이 발생하는 것을 해결하기 위해 '*하드웨어 가속'을 활성화해 대상이 되는 엘리먼트를 빠르게 렌더링 처리하는 방법을 사용했다.

*하드웨어 가속
- 하드웨어 가속은 중앙처리장치(CPU)가 하는 일을 그래픽 처리 장치(GPU)가 분담하여 처리해서 컴퓨터의 성능을 최대한으로 끌어올리고 브라우저 렌더링을 보다 빠르게 할 수 있게 만든다.

 

일반적인 css animation, transform, transition 속성에는 하드웨어 가속이 적용되지 않기 때문에 브라우저를 속여서 강제로 3D 처리를 하도록 브라우저에 지시해 하드웨어를 가속화 하는 방법을 사용했다.

그 방법이 translateZ 혹은 translate3d이다.

transform: translate3d(0,0,0);

transform: translateZ(0)

하지만 이러한 방법은 RAM이나 그래픽 처리 장치(GPU)의 사용량을 커지게하여 페이지에 병목 현상을 줘서 오히려 악영향을 끼치게 한다.

 

2. will-change

위 css핵을 대체할 수 있는 새로운 css 속성이 생겼다. 그 속성이 will-change 이다.

속성명 그대로 어떤 속성이 변경이 될 것인지 미리 엘리먼트에 적용하여 브라우저가 해당 css를 읽을 때 변경 될 속성을 알게하여 미리 그 변경에 대비할 수 있게 하는 것이다.

will-change: auto;		/* 기본 값 */
will-change: scroll-position;	/* 스크롤 위치가 변경 될 예정 */
will-change: contents;		/* 요소의 컨텐츠 내용이 변경 될 예정 */

/* 특정 css 속성 적용 */
will-change: transform;		/* transform 속성이 변경 될 예정 */
will-change: opacity;		/* opacity 속성이 변경 될 예정 */
will-change: left, top;		/* left, top 값이 변경 될 예정 */
will-change: transform, opacity

 

 

적용예시)

<style>
  .thmb {width:100px; height:100px; border-radius:50%; overflow:hidden;}
  .thmb img {transition:0.3s transform; will-change:transform;}
  .thmb:hover img {transform:scale(1.2);}
</style>

<!-- .thmb 마우스오버시 img 확대 -->
<div class="item">
  <div class="thmb">
    <img src="picture.jpg">
  </div>
</div>

위와 같은 소스상 .thmb에 마우스 오버시 img가 확대되는 효과를 구현하고자 할 때

transform을 통해 scale을 변경할 img태그에 미리 will-change 속성을 적용해줄 수 있다.

 

3. will-change 사용상의 주의사항

브라우저 성능을 최적화 하겠다고 will-change를 과다하게 사용하면 안된다.

브라우저는 기본적으로 브라우저가 사용할 수 있는 최적화를 최대한으로 적용한다.

그리고 브라우저가 적용한 최적화를 삭제하고 가능한한 빨리 브라우저가 처리해야할 다른 작업들을 실행한다.

그런데 will-change를 선언하게 되면 이러한 브라우저의 특성을 무시하고 브라우저가 최적화에 더 많은 시간을 쏟게 한다.

즉, 오히려 브라우저 최적화에 악영향을 끼친다.

 

그렇기 때문에 will-change는 정말 필요한 경우에만 적절하게 사용해야한다.

 

4. 자바스크립트를 이용한 will-change 적용

3번과 같은 브라우저 최적화 이슈가 있기 때문에 가능하면 will-change를 사용할 때는 자바스크립트를 사용해서 필요한 순간에만 적용하고 다시 will-change를 초기화 시키는 방법을 적용할 수 있다.

<!-- .thmb 마우스오버시 img 확대 -->
<div class="item">
  <div class="thmb">
    <img src="picture.jpg">
  </div>
</div>

<script>
  // 클릭할 때 애니메이션을 재생할 엘리먼트를 선택합니다.
  var item = document.querySelector('.item');

  // 엘리먼트의 조상 요소에 마우스 커서가 올라가면 will-change를 설정한다.
  item.addEventListener('mouseenter', hintBrowser);
  // 엘리먼트의 조상 요소에 마우스 커서가 내려가면 will-change를 초기화한다.
  item.addEventListener('mouseleave', removeHint);

  function hintBrowser() {
    this.querySelector('img').style.willChange = 'transform, opacity';
  }

  function removeHint() {
    this.querySelector('img').style.willChange = 'auto';
  }
 </script>

 

 


참조

https://dev.opera.com/articles/ko/css-will-change-property/

 

 

반응형

+ Recent posts