모바일 웹에서 성능을 높이는 방법으로 GPU가속을 사용하기 위해 translateZ(0)와 같은 hack코드를 넣곤 했다. 이후에 will-change가 나와서 hack을 대신해서 사용했다. 둘 다 GPU가속을 위해 사용했는데 굳이 will-change을 사용하는 이유는 "브라우저가 효과적으로 GPU가속을 사용할 수 있기" 때문이였다.
문서에는 브라우저마다 will-change을 다르게 사용한다고 하지만, 실제로 크롬에서는 will-change가 어떤 영향을 주는지 코드로 확인하고 싶었다. 아쉽게도 당시 코드를 봤을 때 딱히 크롬이 스마트하게 판단하는지는 찾지 못했다. 그렇게 내가 아직 잘 모르는구나 하는 생각을 하고 지나갔다.
그리고 몇 일전에 will-change: scroll-position, content이 성능에 어떤 영향을 받는지 문의한 글이 있었는데 이 글을 보고 예전 생각이 나서 정리한다.
일단 scroll-position는 스크롤의 위치가 변경될 수 있음을 알려주는 힌트이고 content는 엘리먼트가 변경될 수 있음을 알려주는 힌트다. [링크]
답변 내용은 현재까진 will-change: scroll-position은 어떤 영향을 미치지 않는다. will-change: content의 경우는 content을 가진 엘리먼트의 자식 엘리먼트가 will-change: <hint>을 가지면 변경할 가능성이 있다고 판단하여 자식 엘리먼트는 composited layer을 만들지 않는다.
예제를 보면 이해하기 쉬운데 아래 두개만 composited layer을 만든다.
<div style="will-change: scroll-position"></div> <div style="will-change: contents"></div> <div style="will-change: transform"></div> // <--------- composited layer <div style="will-change: contents"> <div style="will-change: transform"></div> </div> <div style="will-change: scroll-position"> <div style="will-change: transform"></div> // <--------- composited layer </div>
blink코드를 보면 더 정확히 할 수 있다.
if (style.hasWillChangeCompositingHint() && !style.subtreeWillChangeContents()) reasons |= CompositingReasonWillChangeCompositingHint;
그리고 will-change에 들어갈 수 있는 style은 [opacity, transform, webkit-transform, top, left, bottom, right]이다.
switch (rareNonInheritedData->m_willChange->m_properties[i]) { case CSSPropertyOpacity: case CSSPropertyTransform: case CSSPropertyAliasWebkitTransform: case CSSPropertyTop: case CSSPropertyLeft: case CSSPropertyBottom: case CSSPropertyRight: return true; default: break; }
이걸 보면서, 예전에 궁금했던 점이 조금 이해됐다. 현재는 content속성에 대해서만 되어 있지만, 나중에는 scroll-position에 대해서도 최적화가 들어갈 것 같고 이후에는 W3C에 나와 있는 것 처럼 최적화가 되지 않을까 생각된다.