애니메이션 측정, 애니메이션 프레임 고려 방법, 전반적인 페이지 매끄러움에 대해 알아보세요.
페이지가 '버벅거리는' 문제를 경험한 적이 있을 것입니다. 또는 "고정" 스크롤하거나 있습니다. 이러한 경험은 원활하지 않습니다. 도착지 주소 Chrome팀에서는 더 많은 사용자에게 더 많은 지원을 제공하기 위해 애니메이션 감지를 위한 실험실 도구에 더 많은 시간을 할애할 수 있을 뿐 아니라 Chromium 내의 렌더링 파이프라인 진단에 액세스할 수 있습니다
최근 진행 상황을 공유하고 구체적인 도구 안내를 제공해 드리려고 합니다. 향후 애니메이션 부드러움 측정항목에 대한 아이디어에 대해 논의합니다. 언제나 그렇듯이 의견을 들어주세요.
이 게시물에서는 세 가지 주요 주제를 다룹니다.
- 애니메이션 및 애니메이션 프레임 간단히 살펴보기
- 전반적인 애니메이션의 매끄러움 측정에 관한 Google의 현재 의견입니다.
- 지금 바로 실습 도구에 활용할 수 있는 몇 가지 실용적인 권장사항을 소개합니다.
애니메이션이란 무엇인가요?
애니메이션으로 콘텐츠에 생동감을 불어넣을 수 있습니다. 특히 공격에 대응하여 콘텐츠를 이동시킴 애니메이션을 통해 보다 자연스러운 경험을 할 수 있으며, 이해할 수 있고 재미있습니다.
하지만 잘못 구현되거나 너무 많은 애니메이션을 추가하는 것만으로는 경험의 질을 떨어뜨리고 전혀 재미없게 만듭니다. 우리는 아마도 '도움이 되는' 항목이 너무 많이 추가된 인터페이스와 상호 작용함 전환 이러한 효과는 성능이 떨어지면 실제로 경험하기에 적대적으로 변할 수 있습니다. 일부 사용자는 실제로 작은 움직임 선호: 사용자 환경설정 몇 가지 있습니다.
애니메이션은 어떻게 작동하나요?
간단히 요약하자면 렌더링 파이프라인에서는 몇 가지 순차적 단계로 구성됩니다.
- 스타일: 요소에 적용되는 스타일입니다.
- 레이아웃: 이러한 형상과 위치를 지정해야 합니다.
- 페인트: 페인트칠 레이어로 변환할 수 있습니다.
- 복합: 레이어가 있습니다.
애니메이션을 정의하는 방법에는 여러 가지가 있지만 기본적으로 모두 다음 중 하나:
- 레이아웃 조정 속성
- 페인트 조정 중 속성
- 복합 조정 속성
이러한 단계는 순차적이기 때문에 애니메이션은 순차적으로 속성 용어에 대해 학습합니다. 업데이트가 일어날 때마다 비용이 더 많이 들고 부드럽게 처리하세요. 자세한 내용은 렌더링 실적 참조하세요.
레이아웃 속성에 애니메이션을 적용하는 것이 편리할 수 있지만 이러한 비용이 즉시 드러나지 않더라도 말이죠. 애니메이션은 를 사용하는 것이 좋습니다.
선언적 CSS 애니메이션 정의 또는 웹 사용 애니메이션, 또한 컴포지션의 합성 요소를 속성, 은 원활하고 효율적인 애니메이션을 보장하기 위한 훌륭한 첫 단계입니다. 그래도 이것만으로는 매끄러움을 보장하지 않습니다. 효율적인 웹 애니메이션도 성능 제한이 있습니다 그렇기 때문에 실적을 측정하는 것이 항상 중요합니다.
애니메이션 프레임이란 무엇인가요?
페이지의 시각적 표현이 업데이트되려면 시간이 걸립니다. 시각적 새 애니메이션 프레임이 만들어지고, 이 프레임은 지정할 수 있습니다.
일정한 간격으로 업데이트를 표시하므로 시각적 업데이트가 일괄 처리됩니다. 다양한 디스플레이 초당 60회와 같이 고정된 시간 간격으로 업데이트 (예: 60Hz) 일부 최신 디스플레이는 화면 재생 빈도가 높습니다. (90~120Hz가 보편화됨) 이러한 디스플레이는 상황에 따라 화면 재생 빈도를 조정할 수도 있고, 심지어 완전히 가변적인 프레임 속도를 제공할 수도 있습니다.
게임이나 브라우저 같은 모든 애플리케이션의 목표는 시각적 업데이트를 일괄 처리하고 이미지 내에서 시각적으로 완전한 애니메이션 프레임을 확신합니다. 이 목표는 다른 광고 목표와 완전히 네트워크의 콘텐츠를 빠르게 로드하거나 실행할 수도 있습니다
언젠가는 내에서 모든 시각적 업데이트를 완료하기가 너무 어려울 수 있습니다. 디스플레이에서 할당한 기한을 뜻합니다. 이 경우 브라우저가 프레임 드롭: 화면이 검은색으로 바뀌지 않고 계속 반복됩니다. 보시다시피 조금 더 오래 전과 동일한 시각적 업데이트를 적용했습니다. 살펴봤습니다
실제로도 이런 일이 자주 발생합니다. 그것은 항상 인지할 수 있는 것은 아닙니다. 정적 또는 문서 형식의 콘텐츠에 사용할 수 있습니다. 이는 웹 플랫폼에서 일반적으로 사용되는 특히 중요합니다 삭제된 프레임은 중요한 시각적 요소가 있을 때만 꾸준한 애니메이션 스트림이 필요한 애니메이션과 같은 업데이트 부드러운 모션을 표시하도록 업데이트됩니다.
애니메이션 프레임에 영향을 미치는 요인
웹 개발자는 브라우저의 기능에 효율적으로 렌더링하고 시각적 업데이트를 표시합니다.
예를 들면 다음과 같습니다.
- 너무 크거나 리소스 집약적인 콘텐츠를 사용하여 대상 기기입니다.
- 너무 많은 사용 레이어 GPU 메모리가 너무 많이 필요함
- 지나치게 복잡한 CSS 스타일 또는 웹 애니메이션 정의
- 빠른 렌더링 최적화를 비활성화하는 디자인 안티패턴 사용
- 기본 스레드에서 JS 작업이 너무 많아서 시각적 요소를 차단하는 긴 작업이 발생함 업데이트.
하지만 애니메이션 프레임이 기한을 놓쳤거나 어떻게 해야 할까요?
한 가지 가능한 방법은
requestAnimationFrame()
드림
그러나 몇 가지 단점이 있습니다 requestAnimationFrame()
또는 'rAF'
브라우저에 애니메이션을 수행할 것을 알리고
렌더링 파이프라인에서 다음 페인트 단계 전에 이 작업을 수행할 수 있습니다. 만약
콜백 함수가 예상한 시점에 호출되지 않습니다. 즉,
페인트가 실행되지 않아 하나 이상의 프레임을 건너뛰었습니다. 이를 통해
rAF가 호출되는 빈도를 세는 방식으로 '초당 프레임 수'를 계산할 수 있습니다.
FPS 측정항목입니다.
let frameTimes = [];
function pollFramesPerSecond(now) {
frameTimes = [...frameTimes.filter(t => t > now - 1000), now];
requestAnimationFrame(pollFramesPerSecond);
console.log('Frames per second:', frameTimes.length);
}
requestAnimationFrame(pollFramesPerSecond);
requestAnimationFrame()
폴링은 다음과 같은 이유로 좋은 생각이 아닙니다.
- 모든 스크립트는 자체 폴링 루프를 설정해야 합니다.
- 핵심 경로를 차단할 수 있습니다.
- rAF 폴링이 빠르더라도
requestIdleCallback()
드림 긴 유휴 블록이 지속적으로 사용되면( 초과). - 마찬가지로 긴 유휴 블록이 없으면 브라우저가 장기 실행 작업 (예: 더 긴 가비지 컬렉션, 기타 백그라운드 또는 일종의 추측 작업).
- 폴링이 사용 설정 또는 사용 중지로 전환되면 프레임 예산이 제대로 작동하지 않는 경우를 놓칠 수 있습니다. 한도를 초과했습니다.
- 설문조사에서 브라우저에서 거짓양성을 보고 가변적인 업데이트 빈도 (예: 전원 또는 가시성 상태)가 원인일 수 있습니다.
- 가장 중요한 점은, 모든 유형의 애니메이션을 실제로 캡처하지는 않는다는 것입니다. 업데이트!
기본 스레드에서 너무 많은 작업을 수행하면 애니메이션 프레임을 보는 기능에 영향을 줄 수 있습니다. Jank에서 샘플을 참고하여 rAF 기반 애니메이션: 기본 스레드에 너무 많은 작업 (예: 레이아웃)이 되면 프레임이 드롭되고 rAF 콜백이 줄어들며 FPS가 낮아집니다.
기본 스레드가 멈춤 상태가 되면 시각적 업데이트가 끊기기 시작합니다. 버벅거림 현상입니다.
많은 측정 도구는 주요 통계의 핵심 기능에 애니메이션 프레임이 원활하게 실행되도록 해야 합니다. 하지만 이게 전부가 아닙니다. 다음 예를 참고하세요.
위의 동영상은 기본 인스턴스에 주기적으로 긴 작업을 주입하는 페이지를 보여줍니다.
있습니다. 이처럼 긴 작업은 페이지의
특정 유형의 시각적 업데이트로 표시되며, 왼쪽 상단에서
보고된 requestAnimationFrame()
FPS를 0으로 변경합니다.
이러한 긴 작업에도 불구하고 페이지는 계속해서 부드럽게 스크롤됩니다. 이 최신 브라우저에서 스크롤이 대화목록, 전적으로 컴포지터에 의해 구동됩니다.
이 예시는 기본 스레드에 드롭된 많은 프레임을 동시에 있지만 여전히 컴포지터 스레드가 됩니다. 긴 작업이 완료되면 기본 스레드 페인트가 업데이트됩니다. 시각적으로 변화가 없습니다. rAF 폴링은 프레임 드롭을 0으로 제안했습니다. 그러나 시각적으로는 사용자가 차이를 느끼지 못할 것입니다.
애니메이션 프레임의 경우 스토리가 그렇게 간단하지는 않습니다.
애니메이션 프레임: 중요한 업데이트
위의 예시는 스토리에 더 많은 요소가 있다는 것을 보여줍니다.
requestAnimationFrame()
그렇다면 애니메이션 업데이트와 애니메이션 프레임은 언제 중요한가요? 다음과 같습니다. 다음 사항에 대해 의견을 듣고자 합니다.
- 기본 및 컴포지터 스레드 업데이트
- 페인트 업데이트 누락
- 애니메이션 감지
- 양과 질의 비교
기본 및 컴포지터 스레드 업데이트
애니메이션 프레임 업데이트는 불리언 값이 아닙니다. 프레임이 한 번에 여러 개의 완전히 드롭되거나 완전히 표시되어야 합니다. 애니메이션이 작동하지 않는 데는 프레임이 일부 표시될 수 있습니다. 다시 말해, 동일한 포드에 대한 오래된 콘텐츠와 새로운 시각적 업데이트로 인해 있습니다.
이에 대한 가장 일반적인 예는 브라우저가 새로운 프레임 기한 내에 기본 스레드가 업데이트되지만 새 컴포지터 스레드가 있음 (이전의 스레드 스크롤 예 등).
합성 애니메이션을 위해 선언적 애니메이션을 사용하는 한 가지 중요한 이유 이렇게 하면 원하는만큼 애니메이션을 재생할 수 있기 때문에 컴포지터 스레드에 의해서만 발생합니다. 이러한 유형 시각적 업데이트를 계속해서 효율적으로 생성하는 데 사용할 수 있는 애니메이션의 비율 있습니다.
반면에 기본 스레드 업데이트가 최종적으로 여러 프레임 기한을 놓친 후에만 사용할 수 있습니다. 여기 브라우저에 몇 가지 새로운 업데이트가 있을 수 있지만 최신 버전은 아닐 수 있습니다.
개략적으로 말하자면, 새로운 시각적 업데이트가 포함된 프레임, 새로운 시각적 업데이트 없이 부분 프레임으로 표시할 수 있습니다. 부분 프레임은 공통점입니다. 부분 업데이트에는 최소한 가장 중요한 업데이트 항목이 시각적 업데이트도 있지만 이는 애니메이션이 컴포지터 스레드에 의해 구동됩니다.
페인트 업데이트 누락
부분 업데이트의 또 다른 유형은 이미지와 같은 미디어가 완료되지 않은 것입니다. 디코딩 및 래스터화가 가능합니다.
또는 페이지가 완전히 정적인 경우에도 브라우저가 여전히 뒤처질 수 있습니다. 빠르게 스크롤할 때 시각적 업데이트가 가능합니다. 왜냐하면 GPU 메모리를 절약하기 위해 표시된 표시 영역 밖의 콘텐츠는 삭제될 수 있습니다. 그것은 픽셀을 렌더링하는 데 시간이 걸리며 단일 프레임보다 손가락 이동처럼 크게 스크롤하면 모든 것을 렌더링할 수 있습니다. 이는 일반적으로 체커보딩이라고 합니다.
각 프레임 렌더링 기회를 통해 각 프레임에서 최신 시각적 업데이트가 화면에 표시되었죠. 업무 수행 능력 측정 프레임 처리량으로 널리 알려져 있습니다.
GPU가 너무 느려지면 브라우저 (또는 플랫폼)가 시각적 업데이트 시도 속도를 제한하여 최대 64개의 프레임 속도를 제공합니다 기술적으로 이 방법은 손실된 데이터 손실 수를 줄일 수 있지만 시각적으로 여전히 낮은 프레임 처리량으로 표시됩니다.
하지만 모든 유형의 로우 프레임 처리량이 나쁜 것은 아닙니다. 페이지가 주로 유휴 상태인 경우 활성 애니메이션이 없으며 낮은 프레임 속도는 시각적으로 높은 프레임 속도로 매력적일 수 있습니다 (배터리를 절약할 수 있음).
그렇다면 프레임 처리량은 언제 중요한가요?
애니메이션 감지
높은 프레임 처리량은 특히 있습니다. 다양한 애니메이션 유형은 화면의 시각적 업데이트에 따라 특정 스레드 (기본, 컴포지터 또는 작업자)를 정의하기 때문에 시각적 업데이트가 기한 내에 업데이트를 제공하는 스레드에 종속되지 않습니다. 우리는 해당 스레드는 활성 애니메이션이 있을 때마다 부드러움에 영향을 미침 스레드 업데이트에 종속됩니다
일부 애니메이션 유형은 다른 유형보다 더 쉽게 정의하고 감지할 수 있습니다. 선언형 애니메이션, 즉 사용자 입력 기반 애니메이션은 애니메이션 파일에 대한 주기적인 업데이트로 구현되는 JavaScript 기반 애니메이션보다 스타일 속성
requestAnimationFrame()
사용 시
모든 rAF 호출이 반드시 시각적 이미지를 생성한다고 항상 가정할 수는 없습니다
애니메이션을 적용할 수 있습니다. 예를 들어 rAF 폴링을 사용하여 프레임 속도만 추적하고
(위에 표시된 것처럼) 자체는 부드러움 측정에 영향을 미치지 않습니다.
시각적 업데이트가 없습니다.
양과 질의 비교
마지막으로, 애니메이션과 애니메이션 프레임 업데이트를 감지하는 것은 왜냐하면 애니메이션 업데이트의 양만 캡처하고 있습니다.
예를 들어 동영상을 시청할 때 프레임 속도가 60fps로 일정할 경우 있습니다. 기술적으로는 완벽하게 매끄럽지만 동영상 자체는 비트 전송률이 낮거나 네트워크 버퍼링 문제가 있을 수 있습니다. 이것은 다음에 의해 캡처되지 않습니다. 애니메이션의 매끄러운 정도를 조정하는 데 문제가 있을 수도 있지만 있습니다.
또는 <canvas>
를 활용하는 게임 (예:
오프스크린
캔버스를
안정된 프레임 속도 보장)을 사용할 수 있고, 프레임 속도 측면에서
높은 품질의 게임 애셋을
렌더링 아티팩트가 있는 것을 볼 수 있습니다.
물론 사이트에 아주 나쁜 애니메이션이 있을 수도 있습니다. 며칠
내 말은, 그들이 그 시간에 꽤 멋졌던 것 같아!
단일 애니메이션 프레임의 상태
프레임이 부분적으로 표시되거나 누락된 프레임이 여러 방식으로 발생할 수 있기 때문입니다. 부드러운 움직임에 영향을 주지 않는 선에서 각 프레임에 완전성 또는 부드러움 점수를 측정할 수 있습니다.
이것은 단일 안테나에 대한 상태를 해석하는 애니메이션 프레임으로 표시되며, 가장 실적이 좋은 것에서 가장 나쁜 것 순으로 정렬됩니다.
원하는 업데이트 없음 | 유휴 시간으로, 이전 프레임의 반복입니다. |
완전히 발표됨 | 기본 스레드 업데이트가 기한 내에 커밋되었거나 포함되지 않았습니다. 기본 스레드를 업데이트하려고 했습니다. |
일부만 제시됨 | 컴포지터 전용, 지연된 기본 스레드 업데이트에 있습니다. |
일부만 제시됨 | 컴포지터 전용, 기본 스레드에 시각적 업데이트가 있었지만 업데이트에 부드러움에 영향을 미치는 애니메이션이 포함되어 있지 않습니다. |
일부만 제시됨 | 컴포지터 전용, 기본 스레드에 영향을 주는 시각적 업데이트가 있어서 이전에 오래된 프레임이 도착하여 대신 사용되었습니다. |
일부만 제시됨 | 컴포지터 전용, 원하는 기본 업데이트 없이 컴포지터 업데이트에 부드러움에 영향을 미치는 애니메이션이 있습니다. |
일부만 제시됨 | 컴포지터만 가능하지만 컴포지터 업데이트에 부드러움에 영향을 미치는 애니메이션입니다. |
드롭된 프레임 | 업데이트가 없습니다. 원하는 컴포지터 업데이트가 없으며 기본 지연되고 있습니다. |
드롭된 프레임 | 컴포지터 업데이트가 필요했지만 지연되었습니다. |
오래된 프레임 | 업데이트가 필요하고 렌더러에서 생성되었지만 vsync 기한 전에 GPU가 여전히 이를 표시하지 않았습니다. |
이러한 상태를 어느 정도의 점수로 변환할 수 있습니다. 아마도 한 가지 방법은 이는 각 단계에서 관측 가능한 확률로 간주하는 것입니다. 있습니다. 드롭된 단일 프레임은 잘 관찰되지 않을 수 있지만 연속으로 매끄러움에 영향을 주는 드롭된 프레임이 많습니다.
종합하기: 드롭된 프레임 비율 측정항목
가끔은 각 입찰의 상태를 자세히 검토해야 할 수도 있지만 애니메이션 프레임의 경우 점수 경험해 보세요.
프레임이 부분적으로 표시될 수 있고 완전히 건너뛰어도 되므로 프레임 업데이트는 실제로 부드러움에 영향을 미치지 않을 수 있으므로 프레임만 계산하고 브라우저가 액세스할 수 없는 범위에서 필요한 경우 시각적으로 완전한 업데이트를 제공해야 합니다.
멘탈 모델은 다음에서 나아가야 합니다.
- 초당 프레임 수:
- 누락된 애니메이션 업데이트와 중요한 애니메이션 업데이트 감지
- 특정 기간 동안 감소한 비율
중요한 것은 중요한 문제까지 대기한 시간의 비율 업데이트를 참조하세요. 이는 사용자가 자연스러운 방식으로 매끄러움을 경험하는 방식과 일치한다고 생각합니다. 실제 웹 콘텐츠의 양상을 보여줍니다. 지금까지 우리는 다음을 사용하여 측정항목의 초기 집합:
- 평균 감소 비율: 전체 기간 내내 유휴 상태가 아닌 모든 애니메이션 프레임이 전체 타임라인
- 최악의 프레임 드롭 비율: 1초 슬라이딩 동안 측정됨 기간입니다.
- 삭제된 프레임 비율의 95번째 백분위수: 1초 동안 측정됨 슬라이딩 윈도우가 있습니다.
지금 바로 일부 Chrome 개발자 도구에서 이러한 점수를 확인할 수 있습니다. 이러한 측정항목은 전체 프레임 처리량에만 중점을 두지만 프레임 지연 시간 등의 요인이 있을 수 있습니다.
개발자 도구에서 직접 사용해 보세요.
성능 HUD
Chromium에는 깃발 뒤에 숨겨진 멋진 성능 HUD가 있습니다.
(chrome://flags/#show-performance-metrics-hud
) 여기에서 라이브 콘텐츠를
점수 및 몇 가지 실험적 정의에 대해 알아볼 수 있습니다.
시간 경과에 따른 드롭된 프레임 비율에 따른 애니메이션 매끄러움
프레임 렌더링 통계
프레임 렌더링 사용 설정 통계' 렌더링 설정을 통해 DevTools에서 새 애니메이션 프레임의 실시간 보기를 확인하고, 완전히 드롭된 프레임과 부분 업데이트를 구분하기 위해 색상으로 구분됩니다. 업데이트. 보고된 fps는 완전히 표시된 프레임에만 해당합니다.
DevTools 성능 프로필 기록의 프레임 뷰어
DevTools 성능 패널에는 오랫동안 Frames가 뷰어를 참고하세요. 하지만 최신 렌더링 파이프라인이 이전 작업을 처리하는 방식과 실제로 작동합니다. 최근의 산업에서조차 많은 부분이 개선되어 Chrome Canary를 사용하면 애니메이션 문제를 디버깅하는 데 큰 도움이 될 것이라고 생각합니다.
오늘은 프레임 뷰어의 프레임이 vsync 경계이며 상태에 따라 색상으로 구분됩니다. 아직 충전이 완료되지 않았습니다. 시각화에 대해 설명하고 있지만 앞으로는 더 많은 기능들이 사용할 수 있게 될 것입니다.
Chrome 추적
마지막으로, 세부 정보를 자세히 살펴보기 위해 선택하는 도구인 Chrome Tracing을 사용하면
'웹 콘텐츠 렌더링'을 기록하여 새로운 Perfetto를 통해 트레이스
UI (또는 about:tracing
)를 살펴보고 Chrome의
그래픽 파이프라인의
인프라를 사용합니다 어렵게 느껴질 수 있지만 몇 가지
최근 Chromium에 추가되었습니다. Google Cloud에서 제공하는
광고 수명 주기 동안
프레임
문서를 참조하세요.
트레이스 이벤트를 통해 다음을 명확하게 확인할 수 있습니다.
- 실행 중인 애니메이션 (
TrackerValidation
이벤트 사용) - 애니메이션 프레임의 정확한 타임라인 가져오기(
PipelineReporter
)을 입력합니다. - 버벅거림이 발생하는 애니메이션 업데이트의 경우, 애니메이션을 차단하는 요소가 정확히 무엇인지
애니메이션이 더 빨리 실행되지 않도록 할 수 있습니다 (이벤트 분석 사용).
PipelineReporter
이벤트) - 입력 기반 애니메이션의 경우 시각적 업데이트를 받는 데 걸리는 시간을 확인하세요.
(이름이
EventLatency
인 이벤트 사용)
다음 단계
웹 바이탈 이니셔티브의 목표는 훌륭한 사용자 환경을 구축하는 것입니다. 실험실 기반 측정항목(예: 총계) 차단 시간 (TBT)은 잠재적인 상호작용 문제를 포착하고 진단합니다 이제 애니메이션의 매끄러움을 위해 이와 유사한 실습 기반 측정항목을 설계합니다.
새로운 게재위치 디자인에 대한 아이디어를 구상하는 대로 포괄적인 측정항목입니다.
또한 향후에 정확한 측정이 가능하도록 API를 설계하고자 합니다. 애니메이션의 매끄러운 동작을 원활하게 필드에서 커스텀 학습을 사용할 수 있습니다. 이 사이트에서 새로운 소식도 기대해 주세요.
의견
최근의 모든 개선사항과 개발자 도구를 통해 Chrome에 제공되며, 애니메이션의 매끄러운 정도를 측정할 수 있습니다. 이러한 도구를 사용해 보세요. 애니메이션을 벤치마킹하고 어디로 연결되는지 Google에 알려주세요.
이 web-vitals-feedback을 사용하세요 '[Smoothness Metrics]'가 포함된 그룹 있습니다. 정말로 의견을 들려주세요.