스마트 TV용 웹뷰 개발은 도전적인 작업이었습니다. 이 장치는 PC에서 원활하게 작동하는 기능을 커버하지 못합니다.
따라서, 리플로우(Reflow)
와 리페인팅(Repainting)
이 발생하지 않도록 세심한 주의가 필요했습니다. 그 중에서 리페인팅 발생
을 어떻게 감지하고 최소화했는지에 대해 정리하고자 합니다.
제가 맡은 프로젝트는 OTT 서비스용 웹뷰 개발이었습니다. 여기에는 캐러셀이 여섯 줄 포함되어 있었고, 사용자가 키보드나 마우스로 아래로 이동할 때마다 캐러셀이 애니메이션과 함께 부드럽게 이동하는 기능이 필요했습니다.
translate
적용 이유이 프로젝트에서 translate
를 사용하기로 결정한 것은 자연스러운 결정이었습니다. top
, bottom
과 같은 위치 지정 속성을 사용할 수도 있었지만, 이러한 방법은 레이아웃의 재계산을 유발하여 성능에 부담이 있습니다. 반면, translate
를 사용하면 주변 요소의 레이아웃은 그대로 유지하면서 대상 요소만 이동시킬 수 있어 사용하였습니다.
상하 이동 시 애니메이션이 깨지거나 화면이 멈추는 문제가 발생했습니다. 캐러셀에 lazy loading을 적용하고, 메모이제이션을 통해 렌더링 시 재생성을 방지하는 등의 최적화를 시도했지만, 여전히 문제가 해결되지 않았습니다.
먼저, 성능 탭을 활용해 문제를 분석했습니다.
(참고용 이미지입니다.)
위 이미지와 같이 성능 탭에 그려지는 최상단 빈도 그래프와
(참고용 이미지입니다.)
기본에서 나오는 막대 그래프를 참고하여 분석하였습니다.
상하 이동 시 발생하는 translate(애니메이션)과 setTimeout
(애니메이션)이 성능 저하의 주범으로 보였고, 화면 렉이 발생하는 것으로 추정하였습니다.
이 문제를 해결하기 위해 렌더링 탭을 활용했습니다. 렌더링 탭의 '페인트 플래시' 기능을 사용하여 어느 부분에서 페인트가 발생하는지 구체적으로 확인할 수 있었습니다.
translate
가 적용될 때 많은 페인트가 발생하는 것을 시각적으로 확인할 수 있었습니다. 이를 해결하기 위해 먼저 떠오른 것은 will-change
속성의 적용이었습니다.
will-change
속성의 적용will-change
CSS 속성은 브라우저에게 요소에서 예상되는 변화 유형에 대한 힌트를 제공합니다. 이를 통해 브라우저는 요소가 실제로 변경되기 전에 적절하게 최적화할 준비를 할 수 있습니다. 이런 종류의 최적화는 성능에 큰 비용이 드는 작업을 사전에 처리함으로써 페이지의 반응성을 향상시킬 수 있습니다.
이 프로젝트에서 will-change
를 사용하기로 결정한 이유는 성능 비용이 큰 작업을 예상하고 이에 대비하려는 전략이었습니다.
will-change
를 적용한 후 스마트 TV에서 테스트해본 결과, 이전보다 훨씬 나은 성능을 보였습니다. 렉 없이 원활하게 동작하며 만족스러운 결과를 얻을 수 있었습니다.
그러나, will-change
를 사용할 때마다 주의사항을 강조하는 내용을 보고, 이 속성의 사용에 대해 더 신중하게 접근할 필요성을 느꼈습니다. 따라서, 추가적인 검토 후 이 속성의 사용을 잠시 보류하기로 결정했습니다. 다른 방법이 전혀 없는 경우에만 이 속성을 고려하기로 했습니다.
애플리케이션에 사용하기 전에 제반사항을 검토해보아야합니다.
저희 스마트 TV 웹 애플리케이션은 스택 형식의 네비게이션을 사용하고 있습니다.
또한will-change
는 자주 사용하는 곳에 적용하여야 효율적입니다.
이를 극복하고 효과적으로 사용하기 위해서는 will-change
를 주기적으로 추가 및 제거하는 로직을 구현해야 합니다.
그러나 이러한 로직을 추가하는 것은 로직의 복잡도를 증가시켜 바람직하지 않다고 판단했습니다. 이외에도 여러 주의사항들이 있습니다.
MDN 문서에 따르면, will-change
속성의 사용에는 주의가 필요합니다:
will-change
를 적용하지 말아야 합니다. 이러한 과도한 사용은 페이지 속도를 늦출 수 있으며 많은 자원을 소모할 수 있습니다.will-change
는 아껴서 사용해야 합니다. 활성화/비활성화하는 것이 좋습니다.will-change
는 성능 문제를 해결하기 위한 마지막 수단으로 사용되어야 합니다. 성능 문제가 발생하지 않는 경우에는 이 속성을 사용하지 않는 것이 좋습니다.
레이어 탭을 활용하여 will-change 레이어가 미리 생성하는 것을 확인할 수 있었습니다.
여러 이유들로 인해서 스택 네비게이션을 사용하는 애플리케이션에는 이러한 접근 방식이 적합하지 않다고 결론지었습니다.
translate3D
사용다음 방법으로는 translate3D
를 선택했습니다. translate와 다르게translate3d
나 translateZ
와 같은 3D 변환을 사용하면 GPU 가속을 활용할 수 있습니다.
이러한 3D 변환은 웹 브라우저가 요소를 별도의 계층(layer)으로 처리하도록 만들어 렌더링 성능을 향상하는 데 큰 도움이 됩니다.
더불어 x,y,z중 하나의 값만 주어도 translate3D를 통해 GPU 가속을 활용할 수 있습니다.
💪 GPU 가속이란?
브라우저 렌더링에서 마지막 단계인 합성(Compositing) 단계에서 중요한 역할을 합니다.
이 단계에서 Paint Layer는 CPU가, Graphics Layer는 GPU가 담당합니다. 우리가 최적화를 기대하는 부분은 Graphics Layer입니다. GPU를 활용하여 이미지로 변환하며, 병렬 처리에 특화되어 있어 빠른 속도로 작업을 처리합니다.
GPU에서 작업을 처리하면 CPU의 부담을 줄여 저사양 기기에서도 효율적으로 작동할 수 있습니다.
위에서 예측한대로 translate3D
를 적용한 결과, 기대했던 대로 매끄러운 동작을 실현할 수 있었습니다. will-change
와 달리 GPU 메모리 점유 문제도 없었고, CPU 부담도 줄어들어 효과적인 리팩토링을 달성했습니다.
이번 최적화 작업을 통해 GPU에 대한 깊은 이해를 얻었습니다. 7월 이전에는 브라우저에서 CPU와 GPU의 역할에 대해 깊이 생각해본 적이 없었지만, 이번 프로젝트를 통해 두 가지의 중요성과 브라우저 내에서의 작동 방식에 대해 배울 수 있었습니다.
스마트 TV 개발을 하지 않았다면, 이러한 경험을 얻지 못했을 것입니다.
이제 이직에 대한 도전이 끝나서 앞으로 다시 공부를 하며 블로그에 고민들을 남기며 성장하려고 합니다.. 화이팅~!💪
출처 :
https://developer.mozilla.org/ko/docs/Web/CSS/will-change
https://www.youtube.com/watch?v=TZz9VHjJzMk
https://velog.io/@moonshadow/Layer
https://ui.toast.com/fe-guide/ko_PERFORMANCE
translate3D가 퍼포먼스에 좋다 정도로 알고 있었는데 여러 시도를 통해서 알아가시는 과정이 인상 깊었습니다 ! 성능 저하 원인을 분석하는 건 어려운 작업인데 잘 해내신 것 같아요 :) 좋은 정보 공유 감사합니다 ~