일부 애니메이션이 느린 이유는 무엇인가요?

최신 브라우저는 두 개의 CSS 속성 transformopacity에 저렴한 비용으로 애니메이션을 적용할 수 있습니다. 다른 것에 애니메이션을 적용할 경우 60FPS (초당 프레임 수)의 매끄러운 성능을 얻지 못할 가능성이 높습니다. 이 게시물에서는 이러한 이유를 설명합니다.

애니메이션 성능 및 프레임 속도

웹에서 어떤 것을 애니메이션화할 때 60FPS의 프레임 속도가 목표인 것이 널리 받아들여집니다. 이 프레임 속도를 사용하면 애니메이션이 부드럽게 표시됩니다. 웹에서 프레임은 화면을 업데이트하고 다시 페인트하는 데 필요한 모든 작업을 실행하는 데 걸리는 시간입니다. 각 프레임이 16.7ms (1000ms / 60 ate 16.7) 내에 완료되지 않으면 사용자가 지연을 인지하게 됩니다.

렌더링 파이프라인

웹페이지에 무언가를 표시하려면 브라우저는 다음과 같은 순차적 단계를 거쳐야 합니다.

  1. 스타일: 요소에 적용되는 스타일을 계산합니다.
  2. 레이아웃: 각 요소의 도형과 위치를 생성합니다.
  3. 페인트: 각 요소의 픽셀을 레이어에 채웁니다.
  4. 합성: 화면에 레이어를 그립니다.

이 4단계를 브라우저의 렌더링 파이프라인이라고 합니다.

이미 로드된 페이지에서 항목에 애니메이션을 적용할 때는 이러한 단계를 다시 수행해야 합니다. 이 프로세스는 애니메이션을 실행하기 위해 변경해야 하는 단계에서 시작됩니다.

앞서 언급했듯이 이 단계는 순차적입니다. 예를 들어 레이아웃을 변경하는 항목에 애니메이션을 적용하는 경우 페인트 및 합성 단계도 다시 실행해야 합니다. 따라서 레이아웃을 변경하는 항목에 애니메이션을 적용하는 것은 합성만 변경하는 항목에 애니메이션을 적용하는 것보다 비용이 많이 듭니다.

레이아웃 속성 애니메이션

레이아웃 변경에는 변경의 영향을 받는 모든 요소의 도형 (위치 및 크기) 계산이 포함됩니다. 한 요소를 변경하면 다른 요소의 도형을 다시 계산해야 할 수 있습니다. 예를 들어 <html> 요소의 너비를 변경하면 하위 요소도 영향을 받을 수 있습니다. 요소가 오버플로되고 서로에게 영향을 주는 방식으로 인해 트리 아래쪽의 변경사항으로 인해 레이아웃 계산이 다시 맨 위로 올라갈 수 있습니다.

표시되는 요소의 트리가 클수록 레이아웃 계산을 실행하는 데 시간이 더 오래 걸립니다.

페인트 속성 애니메이션

페인트는 화면에 요소를 페인트할 순서를 결정하는 프로세스입니다. 대체로 파이프라인의 모든 작업 중 가장 오래 실행되는 작업입니다.

최신 브라우저에서 대부분의 페인팅은 소프트웨어 래스터라이저에서 실행됩니다. 앱의 요소를 레이어로 그룹화하는 방식에 따라 변경된 요소 외의 다른 요소도 페인트해야 할 수 있습니다.

복합 속성 애니메이션

합성은 페이지를 레이어로 나누고, 페이지가 픽셀로 표시되는 방식에 관한 정보를 변환하고 (래스터화), 레이어를 모아 페이지를 만드는 (합성) 프로세스입니다.

따라서 애니메이션 작업이 적은 항목 목록에 opacity 속성이 포함됩니다. 이 속성이 자체 레이어에 있는 한 이 속성의 변경사항은 합성 단계에서 GPU에서 처리할 수 있습니다. Chromium 기반 브라우저 및 WebKit은 opacity에 CSS 전환 또는 애니메이션이 있는 모든 요소의 새 레이어를 만듭니다.

레이어란 무엇인가요?

애니메이션 처리되거나 전환될 항목을 새 레이어에 배치하면 브라우저는 해당 항목만 다시 페인트하면 되고 다른 항목도 다시 그릴 수 없습니다. 함께 이동할 수 있는 많은 요소를 포함하는 레이어라는 Photoshop의 개념에 익숙할 것입니다. 브라우저 렌더링 레이어도 이 아이디어와 비슷합니다.

브라우저가 새 레이어에 어떤 요소가 있어야 하는지 잘 결정하지만, 요소가 하나 누락되는 경우 레이어를 강제로 생성할 수 있는 방법이 있습니다. 자세한 내용은 고성능 애니메이션을 만드는 방법을 참고하세요. 그러나 각 레이어는 메모리를 사용하므로 새 레이어를 만들 때는 주의해야 합니다. 메모리가 제한된 기기에서 새 레이어를 만들면 해결하려는 문제보다 더 많은 성능 문제가 발생할 수 있습니다. 또한 각 레이어의 텍스처도 GPU로 업로드해야 합니다. 따라서 CPU와 GPU 간의 대역폭 제약이 발생할 수 있습니다.

CSS와 자바스크립트 성능 비교

애니메이션에 CSS 또는 JavaScript를 사용하는 것이 성능 관점에서 더 나은지 궁금할 수 있습니다.

CSS 기반 애니메이션과 웹 애니메이션 (API를 지원하는 브라우저의 경우)은 일반적으로 컴포지터 스레드라고 하는 스레드에서 처리됩니다. 이는 스타일 지정, 레이아웃, 페인팅 및 JavaScript가 실행되는 브라우저의 기본 스레드와 다릅니다. 즉, 브라우저가 기본 스레드에서 비용이 많이 드는 작업을 실행 중인 경우 이러한 애니메이션은 중단되지 않고 계속 진행할 수 있습니다.

이 문서에서 설명한 것처럼 많은 경우 변형 및 불투명도의 다른 변경사항도 컴포지터 스레드에 의해 처리될 수 있습니다.

애니메이션이 페인트, 레이아웃 또는 둘 다를 트리거하는 경우 기본 스레드가 작업을 실행해야 합니다. 이는 CSS 및 JavaScript 애니메이션 모두에 적용되며, 레이아웃 또는 페인트의 오버헤드가 CSS 또는 JavaScript 실행과 관련된 모든 작업을 줄여 의문을 불러일으킬 수 있습니다.