오늘의 'The Fast and the Curious' 포스팅에서는 웹 애플리케이션의 성능을 최적화하기 위해 업그레이드된 새로운 브라우저 벤치마크 툴인 Speedometer 3.0에서 Chrome이 어떻게 역대 최고 점수를 달성했는지 살펴봅니다. 지금 바로 Chrome을 사용해 보세요!
Speedometer 3.0은 Google, Apple, Mozilla, Intel, Microsoft와 같은 기업들 간의 업계 협력을 통해 만들어진 브라우저 성능 측정용 벤치마크로 최근 발표되었습니다. 이 벤치마크는 모든 사용자에게 더 빠른 브라우저 경험을 제공하기 위해 Chrome을 최적화할 수 있는 영역을 식별하는 데 큰 도움이 되었습니다.
업데이트된 벤치마크가 개발되는 동안 Chrome의 최근 성능 변화를 면밀히 추적하여, Speedometer 3에서 역대 최고 점수를 달성하기 위해 Chrome을 어떻게 더욱 최적화했는지 자세히 살펴보겠습니다. 2022년 5월 Speedometer 3 개발이 시작된 이래, 저희는 Chrome의 Speedometer 점수를 72% 향상시켰으며, 이는 사용자들을 위한 성능 이득으로 이어졌습니다.
워크로드 최적화
Speedometer의 워크로드를 분석하고 Chrome이 어떤 함수에서 가장 많은 시간을 소비하는지 파악함으로써, Chrome의 점수를 끌어올릴 수 있는 특정 함수들에 대해 맞춤형 최적화를 진행할 수 있었습니다. 예를 들어, SpaceSplitString 함수는 class='foo bar'와 같이 공백으로 구분된 문자열을 리스트 형태로 변환할 때 많이 사용됩니다. 이 함수에서 저희는 불필요한 범위 체크(bound checks)를 제거했습니다. 또한 중복된 스타일시트가 감지되면 이를 데듀프(dedupe, 중복 제거)하고 단일 스타일시트 인스턴스를 참조하도록 했습니다. 메모리 할당을 조정하여 경로(paths)와 호(arcs)를 그리는 비용을 줄이는 최적화도 진행했습니다. 폼 에디터를 생성할 때 폼 요소가 만들어지는 과정에서 발생하는 불필요한 처리를 감지하여 제거했습니다. querySelector 내에서는 어떤 선택자(selector)가 흔히 사용되는지 감지하여 그에 대한 '핫 패스(hot-path, 주요 경로)'를 생성할 수 있었습니다.
저희는 이전에 파싱을 위한 특화된 패스트 패스를 사용하여 innerHTML을 최적화한 방법을 공유한 바 있으며, 이 구현은 WebKit에도 적용되었습니다. Speedometer 3의 일부 워크로드는 DOMParser를 사용하므로, 동일한 최적화를 확장 적용하여 1%의 추가 성능 향상을 얻었습니다.
또한 Harfbuzz 메인테이너와 협력하여 Apple Mac OS 시스템 폰트 등에서 사용되는 AAT 폰트의 렌더링 방식을 최적화했습니다. 텍스트는 처리된 유니코드 문자 스트림으로 시작하여 글리프(glyph) 스트림으로 변환된 후, AAT 폰트에 정의된 상태 머신을 거치게 됩니다. 이번 최적화를 통해 글리프가 실제로 상태 머신의 규칙에 참여하는지 여부를 더 빠르게 판단할 수 있게 되어, AAT를 사용하는 텍스트 처리 속도가 향상되었습니다.
집중해야 할 코드 선별
높은 성능을 달성하기 위한 중요한 전략 중 하나는 '티어링 업(tiering up)', 즉 엔진 내에서 더 최적화해야 할 적절한 코드를 선택하는 것입니다. Intel은 V8 엔진에 '프로필 기반 티어링(profile guided tiering)'을 기여했습니다. 이는 과거의 티어링 결정을 기억해 두었다가, 특정 함수가 과거에 안정적으로 티어링 업 되었다면 향후 실행 시 이를 미리 티어링 업 하는 방식입니다.
가비지 컬렉션 개선
Speedometer 3에서 약 3%의 점수 향상을 이끈 또 다른 분야는 가비지 컬렉션(garbage collection) 관련 개선입니다. V8의 가비지 컬렉터는 실제 애플리케이션 코드의 방해를 피하기 위해 렌더러의 유휴 시간(idle time)을 활용해 온 오랜 역사가 있습니다. 최근의 변경 사항들도 이러한 정신을 계승하여, 가능한 경우 매우 활발하게 작동 중인 렌더러에서도 유휴 시간에 가비지 컬렉션을 우선적으로 수행하도록 기존 메커니즘을 확장했습니다. 구체적으로, 객체를 회수할 때 실행되는 DOM 종료 코드(finalization code)가 이제 유휴 시간에도 실행됩니다. 이전에는 이러한 작업들이 일반 애플리케이션 코드와 CPU 자원을 놓고 경쟁하곤 했습니다. 또한, V8은 이제 DOM 요소를 래핑하는 객체(즉, JavaScript 프레임워크에 노출되는 모든 객체)에 대해 훨씬 더 압축된 레이아웃을 지원합니다. 이 압축된 레이아웃은 메모리 압박을 줄이고 가비지 컬렉션에 소요되는 시간을 단축시킵니다.
Chrome 제품 매니저 Thomas Nattestad 작성

