Мы очень рады видеть, что некоторые общие операции DOM резко возросли в скорости. Изменения были на уровне WebKit, повысив производительность как для Safari (JavaScriptCore), так и для Chrome (V8).
Инженер Chrome Кентаро Хара выполнил семь оптимизаций кода в WebKit; ниже приведены результаты, которые показывают, насколько быстрее стал доступ к JavaScript DOM:
Резюме повышения производительности DOM
- Производительность
div.innerHTMLиdiv.outerHTMLулучшена в 2,4 раза (V8, JavaScriptCore) - Производительность
div.innerTextиdiv.outerTextв Chromium/Mac выросла в 4 раза (V8/Mac) - Доступ к свойствам CSS улучшен на 35% (JavaScriptCore)
- Производительность
div.classList,div.datasetиdiv.attributesулучшена до 10,9 раз (V8) - Производительность
div.firstElementChild,lastElementChild,previousElementSiblingиnextElementSiblingулучшена в 7,1 раза (V8) - Доступ к атрибутам DOM V8 улучшен на 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 .
Короче говоря, вместо создания множества строк и их последующего объединения, патч создает одну строку, а затем просто добавляет строки пошагово.
Улучшение производительности div.innerText и div.outerText в Chromium/Mac в 4 раза (V8/Mac)
Патч просто изменил начальный размер буфера для создания innerText . Изменение начального размера буфера с 2^16 на 2^15 улучшило производительность Chromium/Mac в 4 раза. Эта разница зависит от базовой системы malloc.
Повышение производительности доступа к свойствам CSS в JavaScriptCore на 35%
Строка свойства CSS (например, .fontWeight , .backgroundColor ) преобразуется в целочисленный идентификатор в WebKit. Это преобразование является тяжелым. Патч кэширует результаты преобразования в карте (т. е. строка свойства => целочисленный идентификатор), так что преобразование не будет выполняться несколько раз.
Как работают тесты?
Они измеряют время доступа к свойствам. В случае 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.
Давай!
Честь и хвала Харакену и остальной команде.