Recentemente, passei alguns dias otimizando o desempenho de inicialização de um aplicativo web do Firefox OS. Ao analisar os dados do perfil e da linha do tempo, percebi que a “mensagem” DOMEvent estava provocando um atraso considerável – Essa “mensagem” é, na verdade, baseada na função setZeroTimeout do David Baron, que é usada algumas vezes ao longo da base de código. Então, eu tive a ideia de usar um Promise resolvido e verificar se ele mudaria alguma coisa, e fiquei impressionado com os ganhos de desempenho! Então, decidi pesquisar se alguém encontrou os mesmos resultados, mas não consegui achar nada e resolvi escrever este artigo.
O Promise.prototype.then chama o callback durante a fila microtask que acontece no final do loop de execução…
Promise.resolve().then(() => console.log('log: 1')); console.log('log: 2'); // > "log: 2" // > "log: 1"
Então, isso significa que o callback provavelmente acontecerá antes que qualquer paint/reflow/style possa ser desencadeado durante esse loop (a menos que você force um refluxo…), de modo que essa é a principal razão pela qual ele melhorou o desempenho do meu app, que basicamente empacotou todos os refluxos e a execução de código, reduzindo o trashing do layout e fazendo mais coisas em paralelo, além do fato de que ele executa muito mais rápido do que o window.postMessage.
Aqui está o código extremamente simples:
// insanely fast nextTick for browsers that support native Promises! var resolved = Promise.resolve(); module.exports = function nextTick(fn) { resolved.then(fn); };
Se você quiser comparar com outras soluções malucas, consulte este teste jsperf.
Eu não testei o uso de memória – teoricamente, vai causar mais coleta de lixo, uma vez que Promise#then retorna um novo objeto Promise em cada chamada; mas os ganhos de desempenho e a quantidade de chamadas nextTick que tenho (menos de 10 chamadas durante a inicialização) deveriam tornar isso irrelevante.
Eu não tenho certeza se é uma boa ideia ou não, mas sei que melhorou a inicialização do meu aplicativo e as coisas ainda funcionam, por isso é bom o suficiente para mim.
“A melhor maneira de obter a resposta certa na Internet não é fazer uma pergunta, é postar a resposta errada” – Lei de Cunningham
PS: Eu estou tentando fazer um carregamento complexo de app web abaixo de 1s em um dispositivo móvel low-end; em um navegador de desktop, a diferença de desempenho é insignificante na maioria dos casos. (Essa mudança só me economizou ~ 80ms).
PPS: Para entender o porquê, você pode precisar de uma função nextTick. consulte a documentação do Node.js.
***
Miller Medeiros faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: http://blog.millermedeiros.com/promise-nexttick/