소개
브라우저 작동 방식과 같은 최신 정보를 계속 확인하는 분이라면 Chrome의 GPU 가속 렌더러/합성 작업을 자세히 설명하는 놀라운 기사가 최근에 게시되었다는 사실을 이미 알고 계실 것입니다. 먼저 Chrome의 가속 렌더링: 레이어 모델은 Chrome에서 레이어 개념을 사용하여 페이지를 그리는 방법을 소개하는 훌륭한 자료입니다. 더 자세히 알아보려면 Chrome의 GPU 가속 합성에서 Chrome이 이러한 레이어를 GPU와 함께 사용하여 페이지를 렌더링하는 방법을 설명합니다.
철학적 질문
3D용 소프트웨어 래스터라이저를 작성하는 데 많은 시간을 보낸 후, 페이지를 그릴 때 일부 CSS 속성의 성능이 달라져야 한다는 점이 분명해졌습니다. 예를 들어 작은 이미지를 화면에 래스터화하는 것은 임의의 도형에 그림자를 그리는 것과는 완전히 다른 알고리즘 작업입니다. 따라서 다양한 CSS 속성이 페이지의 렌더링 가중치에 어떤 영향을 미치는지가 문제가 되었습니다.
제 목표는 대규모 CSS 속성/값 집합을 페인트 시간별로 분류하여 어떤 유형의 CSS 속성이 다른 속성보다 성능이 우수한지 파악하는 것이었습니다. 이를 위해 CSS 페인트 시간에 수치적 가시성을 추가하기 위해 임시방편으로 자동화를 작성했습니다. 다음과 같이 작동했습니다.
- 개별 HTML 페이지 모음을 생성합니다. 각 페이지에는 단일 DOM 요소와 여기에 연결된 CSS 속성의 일부 순열이 있습니다.
- 각 페이지에 대해 다음을 수행하는 자동화 스크립트를 실행합니다.
- Chrome 실행
- 페이지 로드
- 페이지의 Skia Picture 생성
- Skia 벤치마크를 통해 촬영된 각 Skia 그림을 실행하여 타이밍을 가져옵니다.
- 모든 타이밍을 덤프하고 숫자를 확인합니다. (이 부분이 중요합니다.)
이 설정을 사용하면 HTML 페이지 모음이 생성되며, 각 페이지에는 CSS 속성과 값의 고유한 순열이 포함됩니다. 예를 들어 다음은 두 개의 HTML 파일입니다.
<style>
#example1 {
background: url(foo.png) top left / 50% 60%;
padding: 20px;
margin-top: 10px;
margin-right: 20px;
text-align: center;
}
</style>
<div id="example1">WOAH</div>
더 복잡한 또 다른 예시
<style>
#example1 {
background-color:#eee;
box-shadow: 1px 2px 3px 4px black;
border-radius: 50%;
background: radial-gradient(circle closest-corner, white, black);
padding: 20px;
margin-top: 10px;
margin-right: 20px;
text-align: center;
}
</style>
<div id="example1">WOAH</div>
아래는 마지막 예의 변형으로, radial-gradient 값만 변경합니다.
<style>
#example1
{
background-color:#eee;
box-shadow: 1px 2px 3px 4px black;
border-radius: 50%;
background: radial-gradient(farthest-side, white, black);
padding: 20px;
margin-top: 10px;
margin-right: 20px;
text-align: center;
}
</style>
<div id="example1" style="padding: 20px; margin-top: 10px;margin-right: 20px; text-align: center;">WOAH</div>
그런 다음 각 페이지가 Chrome의 새 인스턴스에 로드되고 (페이지 새로고침 시 오래된 상태로 인해 타이밍이 편향되지 않도록 하기 위함) Skia Picture (*.SKP)를 사용하여 페이지를 그리는 데 사용되는 Skia 명령어를 평가합니다. 각 HTML 파일에 대해 SKP 파일이 생성되면 다른 배치를 실행하여 Skia 벤치마크 애플리케이션(Skia 소스 코드에서 빌드됨)을 통해 *.SKP 파일을 푸시합니다. 이 애플리케이션은 해당 페이지를 렌더링하는 데 걸린 평균 시간을 덤프합니다.
데이터 평가
이를 통해 이제 CSS 속성 모음이 페인트하는 데 걸리는 시간을 대략적으로 차트로 표시할 수 있습니다. 또는 페인트 성능에 따라 CSS 속성의 스택 순위를 지정할 수 있습니다. 다음은 Chrome 27 베타로 촬영한 대형 그래프로, 이 프로세스의 전체 타이밍 데이터 세트를 보여줍니다. 시간이 지남에 따라 Chrome이 점점 더 빨라지므로 모든 데이터는 변경될 수 있습니다.
각 세로 막대는 CSS 속성의 단일 조합이 있는 페이지의 페인트 시간을 나타냅니다(100배 확대, 이 그래프의 실제 배율 값은 0,1.56ms). 선이 많지만 이 형태로는 별로 쓸모가 없습니다. 유용한 추세를 찾으려면 데이터 마이닝을 수행해야 합니다.
먼저 일부 CSS 속성은 다른 속성보다 렌더링 비용이 더 많이 든다는 증거를 찾습니다. 예를 들어 DOM 요소에 그림자를 그리는 작업은 스플라인 및 기타 복잡한 요소를 사용하는 다중 패스 작업이 포함되지만, 불투명도는 렌더링하기가 더 쉽습니다.
둘째, 더 흥미로운 점은 CSS 속성의 조합이 각 부분의 합보다 페인트 시간이 더 길 수 있다는 것입니다. 관찰자의 관점에서 보면 이는 다소 이상합니다. A+B = C가 되어야 하는데 2.2C가 되기 때문입니다. 예를 들어 box-shadow 및 border-radius-stroke를 추가하는 경우:
여기서 정말 흥미로운 점은 box-shadow 속성 자체가 아니라 특정 값 순열이라는 것입니다. 예를 들어 아래는 값 변형이 있는 box-shadow : 50% 및 border-radius의 그룹화를 보여줍니다.
데이터를 보면 이 상태가 한동안 지속됩니다. 다양하고 특이한 조합이 많지만 제 테스트 모음은 그중 일부만 다룹니다. 흥미로운 결과를 얻을 수 있는 테스트와 조합이 아직 많이 있습니다.
페이지 렌더링 가중치 찾기
페이지의 각 요소에 대한 렌더링 시간을 추적할 수 있는 기능을 갖춘 개발자는 페이지 렌더링 가중치와 이것이 사이트의 반응성에 미치는 영향을 평가할 수 있습니다. 시작하기 위한 몇 가지 팁을 소개합니다.
- Chrome 개발자 도구에서 Chrome의 연속 페인트 모드를 사용하여 어떤 CSS 속성이 비용을 발생시키는지 파악합니다.
- 기존 코드 검토 프로세스에 CSS 검토를 통합하여 성능 문제를 포착합니다. CSS에서 그라데이션 및 그림자와 같이 비용이 더 많이 드는 것으로 알려진 항목을 사용하는 위치를 찾습니다. 이러한 요소가 정말로 필요한지 자문해 보세요.
- 확실하지 않은 경우 항상 더 나은 성능을 선택하세요. 사용자는 열의 패딩 너비가 얼마인지는 기억하지 못할 수 있지만, 사이트를 방문했을 때의 느낌은 기억할 것입니다.
최종 의견
이 실험에서 가장 흥미로운 점 중 하나는 타이밍이 각 Chrome 버전에 따라 계속 변경된다는 것입니다(더 빨라지기를 바랍니다). 브라우저 소프트웨어는 끊임없이 변화하는 영역입니다. 오늘 느린 것이 내일은 빠를 수 있습니다. 이 도움말을 참고하여 이미 border-radius:5가 있는 요소에 box-shadow: 1px 2px 3px 4px를 추가하지 않도록 할 수 있습니다. 하지만 더 중요한 점은 CSS 속성이 페이지 페인트 시간에 직접적인 영향을 미친다는 것입니다.