일부 일반적인 DOM 작업의 속도가 급격히 향상된 것을 확인하고 매우 기쁩니다. WebKit 수준에서 변경사항이 적용되어 Safari (JavaScriptCore)와 Chrome (V8)의 성능이 모두 향상되었습니다.
Chrome 엔지니어 켄타로 하라가 WebKit 내에서 7가지 코드 최적화를 수행했습니다. 아래는 JavaScript DOM 액세스가 얼마나 빨라졌는지 보여주는 결과입니다.
DOM 성능 향상 요약
div.innerHTML
및div.outerHTML
성능이 2.4배 개선됨 (V8, JavaScriptCore)- Chromium/Mac의
div.innerText
및div.outerText
성능이 4배 향상됨 (V8/Mac) - CSS 속성 액세스가 35% 개선됨 (JavaScriptCore)
div.classList
,div.dataset
,div.attributes
성능이 최대 10.9배 향상됨 (V8)div.firstElementChild
,lastElementChild
,previousElementSibling
,nextElementSibling
성능이 7.1배 향상됨 (V8)- V8 DOM 속성 액세스가 4~5% 개선됨 (V8)
아래에서 켄타로 하라가 적용한 일부 패치에 대해 자세히 설명합니다. 링크는 테스트 사례가 포함된 WebKit 버그로 연결되므로 직접 테스트를 시도해 볼 수 있습니다. WebKit r109829와 r111133 사이에 변경사항이 적용되었습니다. Chrome 17에는 이러한 변경사항이 포함되지 않으며 Chrome 19에는 포함됩니다.
div.innerHTML
및 div.outerHTML
의 성능을 2.4배 개선 (V8, JavaScriptCore)
WebKit의 이전 동작:
- 각 태그에 문자열을 만듭니다.
- 생성된 문자열을
Vector<string>
에 추가하여 DOM 트리를 파싱합니다. - 파싱 후
Vector<string>
의 모든 문자열의 합계와 같은 크기의 문자열을 할당합니다. Vector<string>
의 모든 문자열을 연결하여innerHTML
로 반환합니다.
WebKit의 새로운 동작:
1. 문자열 하나(예: S)를 할당합니다.
1. 각 태그의 문자열을 S에 연결하여 DOM 트리를 점진적으로 파싱합니다.
1. S를 innerHTML
로 반환합니다.
간단히 말해 패치는 많은 문자열을 만든 다음 연결하는 대신 하나의 문자열을 만든 다음 문자열을 점진적으로 추가합니다.
Chromium/Mac에서 div.innerText
및 div.outerText
의 성능을 4배 개선 (V8/Mac)
패치로 innerText
생성을 위한 초기 버퍼 크기가 변경되었습니다. 초기 버퍼 크기를 2^16에서 2^15로 변경하면 Chromium/Mac 성능이 4배 향상되었습니다. 이 차이는 기본 malloc 시스템에 따라 다릅니다.
JavaScriptCore에서 CSS 속성 액세스의 성능을 35%개선
CSS 속성 문자열 (예: .fontWeight
, .backgroundColor
)은 WebKit에서 정수 ID로 변환됩니다. 이 변환은 부담이 됩니다. 패치는 전환이 여러 번 실행되지 않도록 맵 (즉, 속성 문자열 => 정수 ID)에 전환 결과를 캐시합니다.
테스트는 어떻게 진행되나요?
속성 액세스 시간을 측정합니다. innerHTML
(bugs.webkit.org/show_bug.cgi?id=81214의 성능 테스트)의 경우 테스트는 다음 코드를 실행하는 데 걸리는 시간을 측정하기만 합니다.
for (var i = 0; i < 1000000; i++)
document.body.innerHTML;
성능 테스트는 HTML 사양에서 복사한 큰 본문을 사용합니다.
마찬가지로 CSS 속성 액세스 테스트는 다음 코드의 시간을 측정합니다.
var spanStyle = span.style;
for (var i = 0; i < 1000000; i++) {
spanStyle.invalidFontWeight;
spanStyle.invalidColor;
spanStyle.invalidBackgroundColor;
spanStyle.invalidDisplay;
}
다행히도 켄타로 하라에 따르면 다른 중요한 DOM 속성과 메서드의 성능을 더욱 개선할 수 있다고 합니다.
덤벼 봐!
하라켄님과 다른 팀원들에게 감사드립니다.