페인트는 최종적으로 사용자의 화면에 합성되는 픽셀을 채우는 프로세스입니다. 대체로 파이프라인의 모든 작업 중 가장 오래 실행되는 과정으로 가급적 피해야 합니다.
페인트는 최종적으로 사용자의 화면에 합성되는 픽셀을 채우는 프로세스입니다. 대체로 파이프라인의 모든 작업 중 가장 오래 실행되는 과정으로 가급적 피해야 합니다.
요약
- 변형 또는 불투명도를 제외한 속성을 변경하면 항상 페인트가 트리거됩니다.
- 페인트는 종종 픽셀 파이프라인에서 가장 비용이 많이 드는 부분이므로 가급적 피하세요.
- 레이어 승격 및 애니메이션 오케스트레이션을 통해 페인트 영역을 줄입니다.
- Chrome DevTools 페인트 프로파일러를 사용하여 페인트 복잡성과 비용을 평가하고 가능하면 이를 줄이세요.
레이아웃 및 페인트 트리거
요소의 도형을 변경하면 픽셀을 수정해야 하므로 레이아웃을 트리거하는 경우 항상 페인트를 트리거합니다.
![전체 픽셀 파이프라인](https://web.developers.google.cn/static/articles/simplify-paint-complexity-and-reduce-paint-areas/image/the-full-pixel-pipeline-2db0601111cfe.jpg?authuser=0&hl=ko)
배경, 텍스트 색상 또는 그림자와 같은 비기하학적 속성을 변경하는 경우에도 페인트를 트리거할 수 있습니다. 이러한 경우에는 레이아웃이 필요하지 않으며 파이프라인은 다음과 같습니다.
![레이아웃이 없는 픽셀 파이프라인](https://web.developers.google.cn/static/articles/simplify-paint-complexity-and-reduce-paint-areas/image/the-pixel-pipeline-withou-b4844130ec9db.jpg?authuser=0&hl=ko)
Chrome DevTools를 사용하여 빠르게 페인트 병목 현상 식별
Chrome DevTools를 사용하여 페인트 중인 영역을 빠르게 식별할 수 있습니다. Rendering 탭을 열고 Paint Flashing을 사용 설정합니다.
이 옵션을 사용 설정하면 페인트 작업이 발생할 때마다 Chrome에서 화면이 녹색으로 깜박입니다. 전체 화면이 녹색으로 깜박이거나 화면에서 페인트해야 한다고 생각하지 않은 부분을 페인트해야 하는 경우 좀 더 자세히 살펴봐야 합니다.
![페인팅할 때마다 페이지가 녹색으로 깜박입니다.](https://web.developers.google.cn/static/articles/simplify-paint-complexity-and-reduce-paint-areas/image/the-page-flashing-green-w-f830587a03866.png?authuser=0&hl=ko)
이동 또는 페이드 요소 승격
페인팅이 항상 메모리에 단일 이미지로 수행되는 것은 아닙니다. 실제로, 필요한 경우 브라우저에서 여러 이미지 또는 컴포지터 레이어로 페인트할 수 있습니다.
![컴포지터 레이어의 표현](https://web.developers.google.cn/static/articles/simplify-paint-complexity-and-reduce-paint-areas/image/a-representation-composi-c93c6e6c3367e.jpg?authuser=0&hl=ko)
이 접근 방식의 장점은 정기적으로 다시 페인트하거나 변형으로 화면에서 움직이는 요소를 다른 요소에 영향을 주지 않고 처리할 수 있다는 것입니다. 이는 Sketch, GIMP 또는 Photoshop과 같은 아트 패키지와 동일합니다. 개별 레이어를 서로 처리하고 합성하여 최종 이미지를 만들 수 있습니다.
새 레이어를 만드는 가장 좋은 방법은 will-change
CSS 속성을 사용하는 것입니다. 이 코드는 Chrome, Opera, Firefox에서 작동하며 transform
값으로 새 컴포지터 레이어를 만듭니다.
.moving-element {
will-change: transform;
}
will-change
를 지원하지 않지만 레이어 생성의 이점이 있는 Safari 및 Mobile Safari와 같은 브라우저의 경우 3D 변환을 사용하여 새 레이어를 강제 적용해야 합니다.
.moving-element {
transform: translateZ(0);
}
그러나 각 레이어에는 메모리와 관리가 모두 필요하므로 너무 많은 레이어를 만들지 않도록 주의해야 합니다. 자세한 내용은 컴포지터(compositor) 전용 속성 고수 및 레이어 수 관리 섹션을 참고하세요.
요소를 새 레이어로 승격한 경우 DevTools를 사용하여 그렇게 하면 성능상의 이점이 있는지 확인합니다. 프로파일링 없이 요소를 승격하지 않습니다.
페인트 영역 줄이기
그러나 요소를 승격하더라도 페인트 작업이 필요한 경우도 있습니다. 페인트 문제의 큰 문제는 브라우저가 페인트가 필요한 두 영역을 함께 결합하고 전체 화면이 다시 페인트될 수 있다는 점입니다. 예를 들어 페이지 상단에 헤더가 고정되어 있고 화면 하단에 페인트되는 항목이 있다면 전체 화면이 다시 페인트될 수 있습니다.
페인트 영역을 줄이는 것은 애니메이션과 전환이 많이 겹치지 않도록 오케스트레이션하거나 페이지의 특정 부분에 애니메이션을 적용하지 않는 방법을 찾는 경우에 종종 사용됩니다.
페인트 복잡성 단순화
![화면의 일부를 페인트하는 데 걸린 시간입니다.](https://web.developers.google.cn/static/articles/simplify-paint-complexity-and-reduce-paint-areas/image/the-taken-paint-part-t-3dda443178b76.jpg?authuser=0&hl=ko)
페인팅은 다른 작업에 비해 비용이 많이 듭니다. 예를 들어 그림자와 같이 블러와 관련된 모든 작업은 빨간색 상자를 그리는 것보다 그리는 데 더 오래 걸립니다. 그러나 CSS 관점에서 이 점이 항상 명확하지는 않습니다. background: red;
및 box-shadow: 0, 4px, 4px, rgba(0,0,0,0.5);
는 성능 특성이 크게 다른 것처럼 보이지는 않지만 그렇습니다.
위의 페인트 프로파일러를 사용하면 효과를 달성하기 위해 다른 방법을 살펴보아야 하는지 결정할 수 있습니다. 더 저렴한 스타일 세트나 대체 수단을 사용하여 최종 결과를 얻을 수 있는지 자문해 보세요.
특히 애니메이션 도중에는 항상 페인트를 피해야 할 수 있습니다. 프레임당 10ms는 일반적으로 특히 휴대기기에서 페인트 작업을 완료하기에 충분하지 않기 때문입니다.