Maior desempenho do DOM - O WebKit's innerHTML é 240% mais rápido

Estamos muito felizes em ver que algumas operações comuns do DOM dispararam em velocidade. As alterações foram feitas no nível do WebKit, impulsionando o desempenho do Safari (JavaScriptCore) e do Chrome (V8).

O engenheiro do Chrome Kentaro Hara fez sete otimizações de código no WebKit. Confira os resultados abaixo, que mostram como o acesso ao JavaScript DOM se tornou mais rápido:

Resumo de melhorias de desempenho do DOM

Abaixo, Kentaro Hara dá detalhes sobre alguns dos patches que ele fez. Os links são para bugs do WebKit com casos de teste, para que você possa experimentar os testes por conta própria. As alterações foram feitas entre o WebKit r109829 e r111133: o Chrome 17 não as inclui, mas o Chrome 19.

Melhoria da performance de div.innerHTML e div.outerHTML em 2,4 vezes (V8, JavaScriptCore)

Comportamento anterior no WebKit:

  • Crie uma string para cada tag.
  • Anexe uma string criada a Vector<string>, analisando a árvore DOM.
  • Após a análise, aloque uma string com o tamanho que é a soma de todas as strings na Vector<string>.
  • Concatenar todas as strings em Vector<string> e as retornar como innerHTML.

Novo comportamento no WebKit: 1. Aloque uma string, como "S". 1. Concatenar uma string de cada tag a S, fazendo uma análise incremental da árvore do DOM. 1. Retorne S como innerHTML.

Resumindo, em vez de criar muitas strings e depois concatenar-as, o patch cria uma string e, em seguida, simplesmente anexa strings de maneira incremental.

Melhorar o desempenho de div.innerText e div.outerText no Chromium/Mac em quatro vezes (V8/Mac)

O patch mudou o tamanho do buffer inicial para criar innerText. A alteração do tamanho do buffer inicial de 2^16 para 2^15 melhorou o desempenho do Chromium/Mac em 4x. Essa diferença depende do sistema maloco subjacente.

Melhoria de 35%no desempenho dos acessos às propriedades do CSS no JavaScriptCore

Uma string de propriedade CSS (por exemplo, .fontWeight, .backgroundColor) é convertida em um ID de número inteiro no WebKit. Essa conversão é intensa. O patch armazena em cache os resultados da conversão em um mapa (ou seja, uma string de propriedade => um ID de número inteiro). Assim, a conversão não vai ser realizada várias vezes.

Como funcionam os testes?

Elas medem o tempo dos acessos à propriedade. No caso do innerHTML (o teste de desempenho em bugs.webkit.org/show_bug.cgi?id=81214), o teste apenas mede o tempo de execução deste código:

for (var i = 0; i < 1000000; i++)
    document.body.innerHTML;

O teste de desempenho usa um corpo grande copiado da especificação HTML.

Da mesma forma, o teste de acesso à propriedade do CSS mede o tempo deste código:

var spanStyle = span.style;
for (var i = 0; i < 1000000; i++) {
    spanStyle.invalidFontWeight;
    spanStyle.invalidColor;
    spanStyle.invalidBackgroundColor;
    spanStyle.invalidDisplay;
}

A boa notícia é que Kentaro Hara acredita que mais melhorias de desempenho serão possíveis para outros atributos e métodos DOM importantes.

Vamos lá!

Parabéns a Haraken e ao restante da equipe.