문제
사파리에서 hover시에 filter: drop-shadow 속성 적용이 안 되는 이슈가 있었다.
// CSS
.box {
width: 300px;
height: 300px;
background: skyblue;
color: white;
}
.box:hover {
transform: translateY(10px);
filter: drop-shadow(0, 2, 16, rgba(0 0 0 / 0.12));
}
// HTML
<div class="box"></div>
원인
사파리에서 CSS filter 속성을 제대로 처리하지 못하는 렌더링 이슈이다. 대부분의 브라우저들은 filter 속성을 GPU를 통해 처리한다. 하지만 사파리에서는 filter 속성을 GPU가 아닌 CPU를 사용한다고 한다. filter는 복잡한 그래픽을 처리하기 때문에 그래픽 처리에 적합한 GPU가 아닌 CPU로 처리했을 때 렌더링 문제가 발생할 수 있다.
참고1, 참고2 앞선 글들에서 사파리에서는 filter속성을 CPU로 처리한다고 하였지만 더 확인이 필요하다. 이 내용에 대한 출처나 증명이 명확하지 않다. 중요한 건 사파리에서 filter를 처리할 때 렌더링 이슈가 있고 의도적으로 GPU 가속 처리를 해야 한다는 점이다.
해결
방법 1.
translateZ는 GPU를 가속하는 속성 중 하나이다. 이 방법은 버그가 간헐적으로 발생하는 문제가 있었다.
방법 2. will-change 사용
will-change 속성은 GPU 가속에 더해 브라우저에 최적화 작업을 돕는다. will-change: filter 속성은 브라우저에게 filter 속성이 변경된다고 암시하고 브라우저가 미리 최적화 작업을 할 수 있게 돕는다. 실제로 사파리 개발자도구를 열어서 Layers 탭을 확인에 보니 코드 아래 오른쪽 사진처럼 hover 되지 않아도 미리 레이어를 그려놓는다.
// CSS
.box {
width: 100px;
height: 100px;
background: orange;
color: white;
will-change: filter; // 추가
}
...
주의할 점
will-change 속성은 꼭 필요한 곳에서만 사용해야 한다. 과도한 메모리 사용과 렌더링의 복잡성을 증가시켜 오히려 성능이 저하될 수 있다. 위 예시를 보면 알 수 있듯이 will-change 속성을 사용했을 때 더 많은 레이어를 그린다. 유저에게 원활하게 애니메이션을 보여주게 되었지만, 더 많은 레이어를 그리면서 렌더링 비용이 증가했다. 이러한 trade-off가 있다는 걸 염두해야 한다. MDN에 따르면 will-change 속성은 성능 문제를 예상하면서 미리 최적화를 하기 위해 쓰지 말고 최후의 수단으로 쓰라고 강조한다.
Ref
https://developer.mozilla.org/en-US/docs/Web/CSS/will-change
https://www.smashingmagazine.com/2016/12/gpu-animation-doing-it-right/
'프론트엔드 > Javascript' 카테고리의 다른 글
잊을만하면 찾아왔던 오디오 재생버그 (0) | 2023.08.21 |
---|---|
사파리 비동기 함수에서 window.open 우회하기 (0) | 2023.07.02 |
화살표 함수는 언제, 왜 써야할까? (0) | 2020.10.30 |
JavaScript- require vs import (CommonJs와 ES6) 차이점 (0) | 2020.10.30 |
실행 컨텍스트 정리 (0) | 2020.10.23 |