컴포지션 애니메이션의 위험

2025년 9월 앱지면을 웹뷰 지면으로 전환해서 배포했다. 해당 지면은 무한스크롤로 구성되어 있었는데, 배포하고 운영에서 확인해보니 iOS에서 스크롤이 버벅였다. 안드로이드에는 문제 없었다. 확인해보니 레이어가 무수히 많았다. 우리는 will-change 속성 때문이라고 생각했다. 터치로 메뉴를 꾹 누르면 메뉴 이미지가 확장(css scale)되는 애니메이션이 있었는데 scale되는 순간 레이어 순서가 바뀌어서 메뉴 이미지 위로 있던 배지가 사라지는 이슈가 있었다. 이 문제를 해결하기 위해 iOS에서 컴포지션 문제 때문에 will-change 속성을 할당했고 이 때문에 문제가 생겼다고 판단했다. will-change만 없애면 문제를 해결 할 수 있다고 생각했다. 하지만 문제는 사라지지 않았다. 레이어의 개수는 사라지지 않았다.

(번역) CSS GPU 애니메이션 제대로 하기 따르면 CSS 명세서에는 이 특별한 GPU 컴포징 모드에 대한 설명이 없다고 한다. 브라우저마다 특별한 합의 없이 각자 구현했다. 레이어는 함부러 낭비하면 안된다. 레이어를 사용하면 GPU로 지속적으로 데이터를 보내고 받아야 하기 때문이다. 해당 글에서는 개발자가 의도하지 않은 암묵적 컴포지팅을 경고한다.

바로 암묵적 컴포지팅이라고 불리는 과정입니다. 아직 컴포짓 레이어에 올라가지 않은 요소가 하나 이상 존재할 때, 쌓임 순서(stacking order) 때문에 이들이 컴포짓 레이어 위에 존재하는 요소보다 위에 와야 하는 경우, 이 요소들 때문에 컴포짓 레이어가 추가적으로 생성됩니다. 별도의 이미지로 페인팅 되어서 GPU로 보내지게 되는 것이죠.

암묵적 컴포지팅은 사파리 브라우저의 layer 탭을 이용하면 알 수 있다.

선배 개발자 분께서 will-change를 없애고 상위 컨테이너에 will-change: transform;을 지정하는 방법으로 레이어가 과도하게 생성되는 것을 막았다. 왜 상위 컨테이너에 will-change를 적용했는지 궁금했다.

참고