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

Estamos muito felizes em ver que algumas operações comuns do DOM aumentaram muito a velocidade. As mudanças foram no nível do WebKit, aumentando 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 abaixo os resultados, que mostram o quanto o acesso ao DOM do JavaScript ficou mais rápido:

Resumo dos aprimoramentos 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 testar os testes. As mudanças foram feitas entre o WebKit r109829 e o r111133: o Chrome 17 não as inclui, mas o Chrome 19 sim.

Melhoria de 2,4x no desempenho de div.innerHTML e div.outerHTML (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 cujo tamanho seja a soma de todas as strings no Vector<string>.
  • Concatena todas as strings em Vector<string> e as retorna como innerHTML.

Novo comportamento no WebKit: 1. Aloque uma string, por exemplo, S. 1. Concatena uma string para cada tag com S, analisando a árvore DOM de forma incremental. 1. Retorne S como innerHTML.

Em resumo, em vez de criar e concatenar muitas strings, o patch cria uma string e simplesmente anexa strings de forma incremental.

Melhoria de 4x no desempenho de div.innerText e div.outerText no Chromium/Mac (V8/Mac)

O patch apenas mudou o tamanho inicial do buffer para criar innerText. A mudança do tamanho inicial do buffer de 2^16 para 2^15 melhorou a performance do Chromium/Mac em quatro vezes. Essa diferença depende do sistema malloc subjacente.

Melhoria de 35%na performance dos acessos de propriedades 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 é pesada. 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) para que a conversão não seja realizada várias vezes.

Como os testes funcionam?

Eles medem o tempo dos acessos de propriedade. No caso de innerHTML (o teste de desempenho em bugs.webkit.org/show_bug.cgi?id=81214), o teste apenas mede o tempo para executar o seguinte código:

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

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

Da mesma forma, o teste de acessos de propriedade CSS mede o tempo do seguinte 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 importantes do DOM.

Vamos lá!

Parabéns a Haraken e ao restante da equipe.