Utilizando API Web Workers para Processamento em
Segundo Plano
Ariovaldo Batista de Almeida Neto, Marcos Aberto Lopes da Silva
Instituto de Informática – Centro Universitário do Triângulo (UNITRI) Caixa Postal 309 – 38.411-106 – Uberlândia – MG – Brasil [email protected], [email protected]
Resumo. Atualmente um dos problemas recorrentes das aplicações web é a
demanda cada vez maior por processamento, sendo que o paralelismo sempre foi um problema ao se falar de JavaScript. Nesse contexto surge a API Web Worker, uma API que está sendo especificada pela W3C e WHATWG, cujo objetivo é melhorar a performance das aplicações com a execução de scripts em segundo plano, sem concorrer com os scripts da página principal. Este artigo fornecerá uma introdução à API Web Workers apresentando suas principais características, suas vantagens e desvantagens, tipos e a forma de utilização visando o ganho no desempenho das aplicações, melhorando a interação do usuário com a página quando há a necessidade de execução de tarefas longas e pesadas.
1. Introdução
Com a evolução das aplicações Web 2.0 os usuários finais têm esperado cada vez mais uma resposta mais rápidas destas aplicações. Com a API “Application Programming
Interface” é possível efetuar a execução de código JavaScript em segundo plano sem
bloquear o conteúdo do documento DOM “Document Object Model” a ser exibido para o usuário.
Atualmente a grande maioria das aplicações web são desenvolvidas utilizando o JavaScript que é uma linguagem leve, interpretada e baseada em objetos com funções de primeira classe, mais conhecida como a linguagem de script para páginas web, mas usada também em vários outros ambientes sem browser como node.js ou Apache CouchDB [Marcelo Camargo, 2015].
Em comparação com outras linguagens o JavaScript sofre historicamente com uma limitação importante: todo o seu processo de execução se mantém dentro de um seguimento único e sequencial.
Com a introdução da API Web Worker será possível melhorar a interatividade do usuário com as aplicações visando o ganho no desempenho, com isso melhorando a experiência do usuário final.
O objetivo do intitulado artigo é fornecer uma introdução à API, apresentando suas principais características e tipos, ressaltando a melhora na performance das aplicações web, da melhora na interação do usuário com a aplicação quando há a necessidade de execução de tarefas longas.
2. A API Web Workers
A API ainda está sendo especificada pela W3C “World Wide Web Consortium” e
WHATWG “Web Hypertext Application Technology Working Group”, antes da sua
chegada não era possível executar vários scripts ao mesmo tempo em uma página web porque o JavaScript é uma linguagem single-thread, que originalmente foi implementada como parte dos navegadores para que os scripts sejam executados do lado do cliente sem a necessidade deste passar pelo servidor, realizando a comunicação assíncrona e alterando o conteúdo do documento exibido [WHATWG, 2015].
Além disso, os navegadores não forneciam mecanismos para permitir que um código embutido em uma página HTML “HyperText Markup Language” pudesse separar a execução de tarefas mais complexas em threads separadas da thread principal. Como o script executa na página concorrendo com a resposta a eventos, toda vez que uma operação ocupar muito tempo de processamento, esta irá bloquear fazendo com que a página trave e dê um alerta para usuário "O script não responde" [Tonsig, 2012].
A figura 1 representa a mensagem exibida pelos navegadores quando um algoritmo que requer um auto custo de processamento é executado. Essa mensagem é padrão entre os navegadores, o usuário tem a opção de continuar com o processamento do script ou para a exceção, sempre que o usuário opta por continuar com a execução a página ficará travada até o final do processamento.
Figura 1. "O script não responde”.
Antes da evolução do HTML para a versão 5.0 a alternativa disponível para execução de tarefas sem o bloqueio de eventos de interação do usuário com a interface do navegador, era separar fragmentos do código JavaScript do original que estava sendo executado pela página isolando-os em uma thread ou em um processo separado do processo principal, que é responsável por tratar eventos de interface, sendo possível executar blocos de código separados do ciclo de execução principal caso houvesse as extensões instaladas no navegador.
Uma das primeiras extensões que incluía suporte a execução de fragmentos de código JavaScript paralelos foi o Google Gears, introduzindo o conceito de
WorkerPools, porém ele foi descontinuado em 2010 devido aos novos benefícios dos
conceitos apresentados pelo HTML5 [RICHARDS, 2010].
A WHATWG inspirado no Google Gears veio trabalhando na especificação de uma API que provê suporte a concorrência nativa no interpretador JavaScript do navegador, permitindo que blocos de código sejam executados paralelamente por uma aplicação web.
Com a evolução dos navegadores e do HTML para a versão 5, surgiram também novos recursos, sendo um deles a API Web Worker que está sendo especificada pela WHATWG e definido pelo W3C como um script em JavaScript que é executado em segundo plano a partir de uma página HTML independentemente dos outros scripts que estão sendo executados na página principal [Bidelman, 2013].
A API define um modelo de ambiente de execução totalmente isolado diferentemente do modelo de threads disponibilizado por outras linguagens de programação como por exemplo o Java.
Um worker não pode compartilhar nenhum objeto com outros workers e nem com a entidade que o criou, isso elimina os problemas de concorrência, de “paralelismo” e a necessidade de sincronismo ao acesso de atributos de objetos. O worker não tem acesso ao DOM e não pode manipular a interface gráfica, é limitado a executar um script e fornecer o retorno enviando mensagens assíncronas que são enfileiradas e tratadas quando o receptor não estiver ocupado [WHATWG, 2015].
2.1. O Funcionamento da API
Com a evolução tecnológica e com o aumento do poder de processamento das máquinas dos usuários é comum que essas máquinas tenham um processador multi-core, permitindo usar o modelo de programação multit-thread fornecida pela API.
A figura 2 ilustra a distribuição de tarefas entre os workers com os processadores multi-core.
Figura 2. API web worker multi-threaded – [Jorge Chamorro, 2015]
A grande vantagem dos workers é a capacidade de utilizar CPUs multi-core de forma mais eficaz, possibilitando a realização de atividades mais complexas que necessitam de maior tempo de execução.
Como previsto pela WHATWG os workers são relativamente pesados e normalmente possuem uma longa duração em sua execução, tendo um alto custo no arranque de processamento, e um alto custo de memória por cada instância criada [Jorge Chamorro, 2013].
A figura 3 ilustra a utilização de CPUs multi-core quando um worker é executado, e claramente possível perceber que o worker aumenta consideravelmente o percentual de utilização do processador.
Figura 3. Antes e depois da execução da API
2.2. Tipos de Web Workers
Atualmente é discutido pelo W3C e WHATWG dois tipos de workers, o dedicado “Dedicated Workers” e o compartilhado “Shared Workers”, sendo que a diferença básica é que um worker dedicado só pode ser acessado pelo código que o criou, enquanto worker compartilhado pode ser acessado por qualquer script [Bidelman, 2013].
Os workers dedicados são os que irão atender a maior parcela das necessidades das aplicações web, visto que, na maioria das aplicações web cada página executa um
script específico.
Porém, por vezes implementa-se um worker compartilhado que será utilizado por mais de uma página, por exemplo, um script para renderizar os pixels de imagens. E este somente deixará de executar em segundo plano quando todas as páginas que o construiram sejam fechadas.
Os workers compartilhados são um pouco mais complexos que os workers dedicados e são conhecidos como Shared Worker, podendo ser utilizados por diversos scripts que estão sendo executados em diferentes janelas, iframes, desde que eles estejam no mesmo domínio.
2.3. Suporte aos Navegadores
A maioria dos navegadores suportam a API como visto na Figura 4 e 5, sendo que o suporte já é muito amplo mesmo em navegadores móveis. Infelizmente, o Internet
Explorer fornece um suporte parcial a API, não sendo suportado pelas versões mais
A figura 4 ilustra as versões de navegadores web e mobiles que suportam os workers dedicados, os de cor clara são os suportados pelos navegadores e as em escuro os não suportados.
Figura 4. Suporte aos workers dedicados – [Caniuse, 2015].
A figura 5 ilustra o suporte aos workers compartilhados em diferentes navegadores. O suporte dos navegadores são mais restritos para os workers compartilhados e também não é suportado por nenhum navegador mobile.
Figura 5. Suporte aos workers compartilhados – [Caniuse, 2015].
Para garantir que um worker não seja executado em navegador que não possui o suporte a API, deverá ser feita uma validação para garantir que o worker não será executado evitando problemas de compatibilidade e na execução da aplicação. A figura 6 ilustra o fragmento de código efetua a verificação de compatibilidade do navegador.
1 2 3 4 5 6 if(typeof(Worker) !== "undefined") { //Sim! Tem suporte ao web workers! //Código...
} else {
//Desculpe! Não tem suporte ao web workers. }
2.4. Casos de uso da API
Os web workers são úteis para executar código javascript em background, ou seja, em uma thread separada, assim, a thread pode fazer qualquer processamento sem bloquear a interface do usuário, e a UI continua rápida e fluída. Sem os web workers, todos os scripts de uma aplicação web ficam na mesma thread, e quando você faz uma operação longa o browser pode ficar sem responder, porque está processando o código anterior [WHATWG, 2015].
Abaixo alguns casos de uso dos web workers: Cache de dados para uso posterior; Processamento multi-thread;
Code highlighting ou formatação de texto em tempo real; Corretor ortográfico;
Analisar dados de vídeo ou áudio;
I/O em background ou polling de serviços;
Processar arrays grandes ou respostas JSON complexas; Aplicar filtros de imagem no canvas;
Atualizar várias linhas em um banco de dados local; 3. Propriedades da API
O Worker é basicamente um arquivo JavaScript(.js) e para criá-lo basta passar o nome do arquivo como parâmetro para seu construtor, a partir disto, se o arquivo for encontrado o navegador faz seu download assíncrono à página e ele só é iniciado quando for completamente carregado e pré-executado.
Quando uma mensagem é enviada da página para o worker, o objeto da mensagem é copiado, ou seja, não é compartilhado, o objeto que está sendo usado na execução do código JavaScript não é o mesmo que está na página [Bidelman, 2013].
A tabela 1 lista os métodos e atributos que são acessados pela API e como a especificação ainda está sendo escrita, a quantidade de métodos e atributos acessíveis tende a aumentar.
Tabela 1. Atributos e Métodos acessados pelos Workers – [Microsoft, 2015].
Método Descrição
void close(); Encerra o thread de trabalho.
void importScripts(urls); Importa uma lista separada por vírgulas de arquivos JavaScript adicionais.
void postMessage(data); Envia uma mensagem para ou a partir do thread de trabalho.
void clearInterval(handle); Cancela um tempo limite identificado pelo identificador. long setInterval(handler, timeout value,
arguments); Agenda um tempo limite para ser executadorepetidamente após o número de milissegundos especificado. Agora é possível passar argumentos
adicionais diretamente para o manipulador. Se o manipulador for um DOMString, será compilado como JavaScript. Retorna um identificador para o tempo limite. Limpa com clearInterval.
long setTimeout(handler, timeoutvalue, arguments);
Agenda um tempo limite para ser executado após o número de milissegundos especificado. Agora é possível passar argumentos adicionais diretamente para o manipulador. Se o manipulador for um DOMString, será compilado como JavaScript. Retorna um identificador para o tempo limite. Limpa com clearTimeout.
onerror Ocorreu um erro de tempo de execução.Ocorreu um erro de tempo de execução.
onmessage Dados de mensagem recebidos.Dados de mensagem recebidos.
Atributos Tipos Descrição
location WorkerLocation Representa uma URL absoluta, incluindo os componentes protocol, host, port, hostname, pathname, search e hash.
navigator WorkerNavigator Representa a identidade e o estado onLine do cliente do agente do usuário.
self WorkerGlobalScope O escopo do trabalho, que inclui os objetos WorkerLocation e WorkerNavigator.
Além dos métodos, funções e atributos citados na tabela 1, os workers possuem algumas restrições, como:
Não pode acessar elementos DOM a partir da página web;
Não podem acessar variáveis globais e funções de JavaScript na página web; Não podem chamar as funções alert() ou confirm();
Não podem acessar janelas;
Não podem ler ou modificar o documento HTML;
Essas limitações podem parecer constrangedoras ou interpretadas como uma limitação grave da API, no entanto, a grande vantagem é que as aplicações deixarão de ter os problemas comuns como: bloqueio da página, start da mensagem “o script não responde” e etc. Como proposto, com a utilização da API, as aplicações web deixarão de ter esses problemas permitindo que as aplicações tenham um aumento de performance tornando a navegabilidade mais interessante e atrativa para usuário.
A figura 7 ilustra claramente as diferenças citadas do acesso e das limitações de um script em uma página web com o script utilizando as técnicas de implementação
propostas pela API, como representado abaixo, a principal diferença é que a API não tem acesso ao Document conhecido como DOM.
Figura 7. Acesso ao DOM – [Bildeman, 2013]
3.1. Troca de mensagens
A API define um modelo de troca de mensagens de texto, um worker pode disparar uma mensagem enviando um texto para ser tratado pela entidade que o criou. A entidade que o criou também pode se comunicar com o worker pelo mesmo método, enviando uma mensagem textual.
O worker fica aguardando o recebimento de uma mensagem e caso esteja ocupado no seu script de inicialização ou tratando outra mensagem, as novas mensagens são enfileiradas e aguardam até que o worker possa processá-las.
Figura 8. Troca de mensagens entre página e worker – [Code Compiled, 2014] O fragmento de código representado na figura 9 cria um worker, e o associa uma função a um tratador de mensagens e envia uma mensagem para o worker.
1 2 3 4 5
var worker = new Worker("worker.js"); worker.onmessage = fun ction (evento){ //código aqui
}
worker.postMessage("mensagem");
Figura 9. Exemplo de instância e comunicação com um Worker
Este modelo de concorrência é limitado visto que não provê um mecanismo para checagem de novas mensagens enquanto uma mensagem está sendo tratada. A presença de um mecanismo destes permitiria a reentrância no ciclo de checagem de mensagens.
Para solucionar este impecílio, pode ser utilizado um misto de funções temporizadas dentro do worker, assim a recepção de mensagens não será bloqueada por estar ocupada tratando apenas uma mensagem, mas sim executando pequenos fragmentos em intervalos de tempo pequenos.
No intervalo que o worker permanece ocioso, entre uma execução da função temporizada e outra, pode tratar as mensagens enfileiradas permitindo a comunicação com o worker mesmo quando ele ainda não completou o tratamento completo de uma mensagem anteriormente recebida, que está aguardando um novo sinal para prosseguir.
3.2. Tratativa de Erros
Caso ocorra algum erro durante a execução do worker o evento ErrorEvent é acionado, a API contém três propriedades úteis para debugar os erros facilitando a correção:
filename- o nome do script do worker que causou o erro, lineno- o número da linha em
que o erro ocorreu e message- uma descrição significativa do erro.
A figura 10 ilustra um exemplo de configuração de um manipulador de evento, especificamente o onerror, essa propriedade é responsável por imprimir as propriedades do erro facilitando a sua identificação [Bidelman, 2013].
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9
<output id="error" style="color: red;"></output> <output id="result"></output>
<script>
function onError(e) {
document.getElementById('error').textContent = [
'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message].join('');
}
function onMsg(e) {
document.getElementById('result').textContent = e.data; }
var worker = new Worker('workerWithError.js'); worker.addEventListener('message', onMsg, false); worker.addEventListener('error', onError, false);
worker.postMessage(); // Start worker without a message. </script>
4. Estudo de Caso
Nessa sessão será analisado o estudo de caso da API através dos levantamentos bibliográficos efetuados e resultados obtidos, será desenvolvido uma pequena aplicação demonstrando o processamento multi-thread.
Essa aplicação irá identificar a quantidade de números primos entre dois números, o inicial e o final, além dos valores de entrada será possível efetuar a escolha de quantas threads serão executadas.
O código foi dividido em duas partes; index.html, onde foi concentrada a parte principal do desenvolvimento contendo o HTML da página, os scripts de criação das barras que mostram o progresso do processamento e o script que será interpretado no
onload da página; a outra parte foi nomeada de primo.js e onde foram desenvolvidas o
worker e função para validar a quantidade de números primos entre os dois valores informados.
4.1. Ambiente de Estudo
Para a realização dos testes foram utilizadas as seguintes ferramentas de trabalho: Hardware: Processador Intel(R) Core(TM) i5-4200U CPU @ 1.60GHz, 6 GB de
memória RAM e disco rígido de 1 TB. Sistema Operacional: Windows 7, 64 bits. Tecnologia: HTML, JavaScript.
IDE - Integrated Development Environment (Ambiente de Desenvolvimento Integrado): Adobe Dreamweaver CC 2015.
Navegador: Mozilla Firefox.
4.2. O Desenvolvimento da Aplicação
A figura 11 representa o script que será executado no onload da página index.html, esse script irá gravar nas variáveis de início e fim “rangeStart” e “rangeEnd”, os valores que o script irá percorrer para encontrar os números primos.
Quando o usuário clicar no botão calcular será disparado o evento $(“#”).click() que irá ler as variáveis de entrada e chamará duas function: a primeira
“createProgressBars()” que irá criar as barras de progresso que irão exibir a exceção
das threads; a segunda será “createWorkers()” que criará os workers para encontrar os números primos de acordo com a quantidade de threads escolhidas.
1 2 3 4 5 6 $(document).ready(function () { $('#qtdTrhead').text($("#dop").val()) $("#btnCalcular").click(function (e) { e.preventDefault();
var rangeStart = parseInt($("#range_ini").val()); var rangeEnd = parseInt($("#range_fim").val());
7 8 9 1 0 1 1 $("#btnCalcular").attr("disabled", "disabled"); var thread = parseInt($("#dop").val());
criaBarra(thread);
criaWorkers(thread, rangeStart, rangeEnd); });});
Figura 11. Código que será interpretado no onload da página.
A figura 12 representa o código que irá criar barras de progresso conhecidas como “progressBars” que irão representar a execução das threads.
1 2 3 4 5 6 8 9 1 0 1 1 1 2 function criaBarra(thread) { $("#resultado_div").hide(); $("#progress_reports").empty(); $("#progress_reports").append("Utilizando " + thread + " thread.<br/>");
for (var i = 0; i < thread; ++i) {
$("#progress_reports").append("<progress id='barra_" + i + "' max='100' /><br/>");
$("#barra_" + i)[0].value = "0"; }
$("#progress_div").show()}
Figura 12. Criação das Progress Bars.
O código abaixo será responsável por criar o worker, se o arquivo especificado existir, o navegador gerará uma nova sequência do worker, que será transferida por download assíncrono.
O worker só é iniciado quando o arquivo tiver sido transferido completamente e executado. Se o caminho para o worker retornar um 404, o worker tem falha silenciosa. Se o arquivo especificado existir, o navegador gerará uma nova sequência do worker, que será transferida por download assíncrono [Bidelman, 2013].
1 2
3 var worker = new Worker("primo.js");
Figura 13. Chamada de um script externo.
A comunicação entre um worker e sua página de origem é feita por um modelo de evento e pelo método postMessage(). Dependendo do navegador/versão, o
postMessage() pode aceitar uma string de texto ou um objeto JSON como seu único
argumento.
As versões mais recentes dos navegadores modernos suportam a transmissão de um objeto JSON “JavaScript Object Notation”. Como ilustrado na figura 14, a função é responsável por criar o objeto worker recebendo 3 parâmetros de entrada: a quantidade de threads que serão executadas, o valor inicial e final para que a função verifique a quantidade de números primos entre os dois valores.
1 2 3
function criaWorkers(thread, start, end) { var range = end - start;
4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 var count = 0; var done = 0;
for (var i = 0; i < thread; ++i) { var worker = new Worker("primo.js"); worker.onmessage = function(event) { if (event.data.type === 'DONE') { $("#barra_" + event.data.idx)[0].value = 100; ++done; count += event.data.count; if (done == thread) { //$("#progress_div").hide(); $("#numero_primo").text(count); $("#resultado_div").show(); $("#btnCalcular").removeAttr("disabled"); }
}else if (event.data.type === 'PROGRESS') {
$("#barra_" + event.data.idx)[0].value = event.data.value; }
};
var init = {
start: start + i*chunk, end: start + (i+1)*chunk, idx: i
};
worker.postMessage(init); }
}
Figura 14. Script principal.
As mensagens transmitidas entre a página principal e os workers são copiadas, e não são compartilhadas. Na figura 15 a propriedade "msg" da mensagem JSON está acessível em ambos os locais.
O objeto está sendo transmitido diretamente para o worker ainda que esteja em execução em um espaço separado, específico. O que acontece é que o objeto está sendo serializado enquanto é entregue para o worker e, subsequentemente, desserializado na outra terminação [Bidelman, 2013].
A página e o worker não compartilham a mesma instância, portanto o resultado final é uma duplicata criada em cada transmissão. A maioria dos navegadores
implementa este recurso pela codificação / decodificação JSON automática do valor em uma das terminações [Bidelman, 2013].
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4
self.onmessage = function (event) { var ini = event.data.start; var fim = event.data.end; var tam = fim - ini; var count = 0;
for (var i = ini; i < fim; ++i) { if (ePrimo(i)){ ++count}; if (i % 1000 === 0) {
self.postMessage(type: 'PROGRESS', value: 100.0*((i-ini)/tam),idx: event.data.idx});
} }
self.postMessage({ type: 'DONE', count: count, idx: event.data.idx });
};
Figura 15. Script responsável por receber e enviar a mensagens.
A figura 16 ilustra a função que é chamada pelo worker para verificar se o número que está sendo informado é primo, se sim, o script retorna verdadeiro, isso irá incrementar o contador, caso seja falso, o contador não será incrementado.
1 2 3 4 5 6 7 function ePrimo(n) { if (n == 2) return true; for (var i = 2; i < n; ++i) { if (n % i == 0) return false; }
return true; }
Figura 16. Script que verifica o número primo.
Todo o código utilizado para o desenvolvimento da aplicação pode ser encontrado em um repositório no endereço: http://www.a2softwares.com.br/workers/. Após efetuado as implementações da API e aplicado todas as técnicas descritas no intitulado artigo, foi desenvolvida uma aplicação web conforme ilustrado pela figura 17.
Figura 17. Página principal da aplicação.
4.3. Dificuldades e Comparações
Em resumo, quando a aplicação é executada utilizando a API, é possível notar que a execução do algoritmo demora um pouco mais para iniciar, de qualquer forma, essa demora no arranque foi previsto pela WHATWG em sua especificação.
Em comparação e sem a utilização da API, a aplicação demorou 2,9 segundos para encontrar os números primos entre os valores 2 e 7000, nota-se também que o navegador travou durante a execução.
Utilizando a API, foi feito um teste com os mesmos valores e somente com uma
thread a aplicação levou cerca de 1,5 segundos para efetuar os mesmos cálculos, nota-se
um ganho de dois segundos no desempenho.
Quando a aplicação é executada com os mesmos valores e com oito threads, a execução demorou cerca de 1,2 segundos, com isso observa-se que quando há um aumento na quantidade de threads a execução fica cerca de 0,3 segundo mais rápida. Os valores de tempo para a execução são variáveis, quanto maior o processamento da máquina do usuário, mas rápida será a execução das threads.
A grande vantagem dos workers é a capacidade de utilizar CPUs multi-core de forma mais eficaz, possibilitando a realização de atividades mais complexas que necessitam de maior tempo de execução evitando que a página venha a ser bloqueada para o usuário.
5. Conclusão
A API web workers oferece inúmeras possibilidades aos desenvolvedores tornando mais interessante o desenvolvimento de aplicações web proporcionando uma melhora significativa no desempenho da página tornando a navegação mais agradável para o usuário final.
O uso da API é simples e de fácil programação, apesar de não oferecer a mesma funcionalidade das threads nas linguagens de programação tradicionais como por exemplo no Java, isto significa a API poderá ser utilizada somente em situações específicas como, por exemplo, nos algoritmos que requerem um auto custo de processamento e são de longa duração.
Como a especificação ainda está sendo escrita é difícil saber o que esperar para o futuro, mas já estão sendo especificadas os dois novos tipos de workers: A background
number-crunching e Worker used for background I/O. Uma nova técnica para delegação
de atividades chamada de Delegation que será responsável por dividir melhor as atividades entres os workers e subworkers.
O intitulado artigo, demonstra a real necessidade de utilização da API em aplicações que requerem um auto custo de processamento e na execução de scripts de longa duração, ao mesmo tempo a API fornece uma ampla gama de recursos divergentes para vários problemas encontrados ao se desenvolver aplicação que requer auto custo de processamento, podendo assim dar várias opções ao desenvolvedor.
Atualmente as empresas têm adotado ferramentas para aumentar a qualidade dos softwares visando a melhora do desempenho e na interatividade do usuário. Espera-se com este trabalho que o estudo deste e de outros recursos que já estão sendo especificadas sejam conduzidos para buscar uma melhoria continua no processo de desenvolvimento de aplicações web.
6. Referências Bibliográficas
Agraj Mangal. Getting Started with Web Workers. Disponível em: <http://code.tutsplus.com/tutorials/getting-started-with-web-workers--net-27667/>. Acesso em: 22 out. 2015.
Bildeman, E. The Basics of Web Workers. Disponível em: <http://www.html5rocks.com/en/tutorials/workers/basics/>. Acesso em: 18 out. 2015 Jorge Chamorro. Lightweight Web Worker API implementation with native
threads. Disponível em: <https://www.npmjs.com/package/webworker-threads/>.
Acessado em: 15 nov. 2015.
Marcelo Camargo. JavaScript. Disponível em: <https://developer.mozilla.org/pt-BR/docs/Web/JavaScript>. Acessado em: 15 nov. 2015.
RICHARDS, GREGOR; LEBRESNE, Sylvain; VITEK, Brian; JAN, Burg. An
Analysis of the Dynamic Behavior of JavaScript Programs. p.1, 2010.
Tonsig, S. L. Aplicações na Nuvem: Como construir com HTML5 JAVASCRIPT
CSS PHP E MYSQL. Rio de Janeiro, RJ: Editora Ciência Moderna Ltda.
W3C (Org.). Visão geral do HTML5. Disponível em: <http://www.w3c.br/cursos/html5/conteudo/capitulo1.html>. Acesso em: 18 out. 2015.
WHATWG (Org.). Web Workers. Disponível em:
WHATWG (Org.). The canvas element - HTML5. Disponível em: