Mostrando postagens com marcador JavaScript. Mostrar todas as postagens
Mostrando postagens com marcador JavaScript. Mostrar todas as postagens

domingo, 22 de junho de 2014

[HTML 5] Web Workers

Essa vai de uma das questões do simulado para o exame 70-480 da Microsoft (HTML 5, JavaScript e CSS3).

A API Web Worker permite executar scripts em background (em uma thread separada da thread principal), sem bloquear a execução da página. A API é implementada no objeto Worker.

Você deve, antes de mais nada, instanciar o objeto Worker usando a palavra chave "new", atribuindo a instância resultante a uma variável, conforme o exemplo:

var worker = new Worker("ArquivoComScriptParaExecutar.js");

O parâmetro do construtor é o arquivo JavaScript que contém o script que será executado em background. Tipicamente são tarefas de longa duração, que poderiam bloquear a execução da página principal por algum tempo. O código do script pode informar o término da execução pelo envio de uma mensagem para o seu chamador, através da função postMessage.

Posteriormente, é necessário associar um event handler ao evento onmessage do objeto Worker. Isto permite à thread principal ser notificada do final da execução do script em background. Para manipular o evento com uma função anônima faça o seguinte:

worker.onmessage = function(e) {window.alert(e.data);};

O parâmetro para a função anônima é um event object. Este objeto contém uma propriedade data, que é o dado enviado como parâmetro pela função postMessage. Esta propriedade pode ser tanto uma string quanto um JSON (JavaScript Object Notation).

O script em background inicial quando o evento onmessage é invocado pelo objeto Web Worker e com o seguinte código, força-se a execução da função anônima no script em background:

worker.postMessage("");

A função AddEventListener permite a você associar um event handler a um evento. O primeiro parâmetro da função deve especificar o nome de um evento, não o nome do script em background. O segundo parâmetro deve especificar uma função de callback ou uma função anônima.

A função close do objeto Worker termina a thread avulsa e é chamada no script em background.

Exemplo:

Script em background (Workers.js):

onmessage = function(e){
  setTimeout(function()
  { 
    postMessage("Terminou a execução em background!");
  }, 5000);
}

Página (chamaWorker.html):

<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
<script>
 var worker = new Worker("Worker.js");
 worker.onmessage = function(e)
 {
   window.alert(e.data); 
 };
 worker.postMessage("");
</script>
</body>
</html>

domingo, 13 de janeiro de 2013

[JSF] Enviar requisição com Ajax

Referência: The Java EE 6 Tutorial Sending an Ajax Request.

Como prometido no post anterior Usando Ajax com JSF vou continuar nos estudos do The Java EE 6 Tutorial, agora mostrando como enviar requisições com Ajax.

O Java EE 6 Tutorial mostra quatro formas para enviar requisições Ajax, são elas:

Usando o atributo event da tag f:ajax

O atributo event define que evento d o DOM irá disparar a ação ajax. Alguns valores possíveis são click, keyup, mouseover, focus e blur.

Se um valor não for especificado para este atributo, ele irá assumir o evento default do componente pai da tag f:ajax correspondente.

Componentes ActionSource, como commandButton, commandLink e inputText tem o valor do atributo action como alvo de seus eventos default.

Exemplo:

<h:commandButton id="submit" value="Submit"> 
    <f:ajax event="click" />
</h:commandButton>
<h:outputText id="result" value="#{userNumberBean.response}" />


Note que estes eventos JSF, apesar de serem baseados em JavaScript, são diferentes dos eventos do DOM que possuem o prefixo "on".

Usando o atributo execute da tag f:ajax

Define o componente ou componentes que serão executados no servidor. O componente é identificado pelo seu atributo id e você pode especificar mais de um componente executável, separando-os com um espaço em branco.

Ao ser executado, o componente participa de todas as fases do ciclo de vida da requisição, exceto da fase Render Response.

O valor do atributo execute também pode ser uma palavra chave como @all, @none, @this@form, explicados no post anterior Usando Ajax com JSF, referindo-se ao componente com que a tag f:ajax está aninhada.

A seguir, um exemplo mostrando como especificar que um inputText de id userNo seja executado no click de um commandButton de forma assíncrona:

<h:inputText id="userNo" 
             title="Type a number from 0 to 10:"
             value="#{userNumberBean.userNumber}">
    ...
</h:inputText>
<h:commandButton id="submit" value="Submit"> 
    <f:ajax event="click" execute="userNo" />
</h:commandButton>

Usando o atributo immediate

Se seu valor estiver configurado para true, seus eventos serão propagados durante a fase Apply Request Values. O valor default é false. Conheça o ciclo de vida JSF para complementar entendimentos.

Usando o atributo listener

Utilizado para referenciar um método do lado do servidor a ser executado por uma ação Ajax do lado do cliente. No seguinte exemplo o atributo listener da tag f:ajax chama um método em um bean quando o evento correspondente é disparado, observe:

<f:ajax listener="#{mybean.someaction}" render="somecomponent" />


Beleza?!

Agora você já pode sofisticar as interações com usuário em sua camada de apresentação JSF.

No próximo post vamos falar de CDI. Até lá!

quinta-feira, 3 de janeiro de 2013

[JSF] Usando Ajax com JSF.

The Java EE 6 Tutorial, Part II The Web Tier, Cap. 11 Using Ajax with JavaServer Faces Technology.

Visão Geral sobre Ajax.

Ajax refere-se a JavaScript e XML, tecnologias que são amplamento usadas para criar conteúdo web dinâmico e assíncrono. O foco deste tutorial está em usar JavaScript em funcionalidades baseadas em Ajax em aplicações web JSF.

JavaScript é uma linguagem orientada a objetos que permite adicionar funcionalidades à camada de apresentação para interações assíncronas com o cliente, onde é originalmente executada (também há JavaScript Side Server).

Quando uma função JavaScript envia uma requisição assíncrona para o servidor, o servidor envia de volta uma resposta usada para atualizar o DOM (Document Object Model) da página.

A resposta do servidor não precisa ser, necessariamente, em XML, também pode ser em JSON (formato de dados JavaScript).

Ajax permite atualização assíncrona e parcial da camada de apresentação, ou seja, funcionalidades Ajax podem trocar informações com o servidor sem a necessidade de submeter ou atualizar a página inteira (refresh).

Usando Ajax com JSF.

Funcionalidades Ajax podem ser adicionadas a aplicações JSF de uma das duas maneiras seguintes:
  • Programando a funcionaliade Ajax em JavaScript diretamente na página.
  • Usando uma biblioteca com funcionalidades Ajax embutidas.
A plataforma JEE 6 suporta Ajax por uma biblioteca JavaScript embutida. Logo, os componentes UI JSF respondem a funcionalidades Ajax. Você também pode carregar esta biblioteca JavaScript e usar diretamente seus métodos dentro dos Managed Beans.

A tag JSF específica para Ajax é f:ajax e seus atributos serão explicados a seguir.

Atributo Tipo Descrição
disabled javax.el.ValueExpression retorna um Boolean Se true o comportamento Ajax não deve ser renderizado, se false, o comportamento Ajax deve ser renderizado, o default é false.
event javax.el.ValueExpression retorna uma String Uma String que identifica o tipo de evento em que a ação Ajax será aplicada. Se especificado, deve ser um dos eventos suportados pelo componente. Se não especificado, o evento default (o evento que dispara a requisição Ajax) é determinado para o componente. O evento dafult é action para componentes ActionSource e valueChange para componentes EditableValueHolder.
execute javax.el.ValueExpression retorna um Object Uma Collection que identifica uma lista de componentes para ser executada no servidor. Se uma literal é especificada, deve ser uma String delimitada por espaços de identificadores de componentes e/ou uma das palavras chave. Se uma ValueExpression é especificada, deve referenciar uma propriedade que retorna uma Collection de String objetos. Se não especificada, o valor default é @this.
immediate javax.el.ValueExpression retorna um Boolean Um Boolean que indica se a entrada é para ser processada antes do ciclo de vida.
listener javax.el.MethodExpression O nome do método listener que será chamado quando um AjaxBehaviorEvent for disparado.
onevent javax.el.ValueExpression retorna uma String O nome da função JavaScript que irá manipular os UI events.
onerror javax.el.ValueExpression retorna uma String O nome da função JavaScript que irá manipular os erros.
render javax.el.ValueExpression retorna um Object Uma Collection que identifica uma lista de componentes a serem renderizados. Se uma literal é especificada deve ser uma String delimitada por espaços de identificadores de componentes e/ou de palavras-chave. Se uma ValueExpression é especificada, deve referenciar uma propriedade que retorna uma Collection de objetos String. Se não especificada, o valor default é @none.

Palavra-chave Descrição
@all Todos os componentes identificados
@form Os componentes do formulário
@none Nenhum componentes identificado
@this O elemento que disparou a requisição

Exemplo de uso da tag f:ajax

<h:inputText value="">
   <f:ajax />
</h:inputText>

Note que quando você usa a tag f:ajax em uma página Facelets, a biblioteca JavaScript que suporta Ajax que já vem no J2EE 6 é carregada implicitamente. Este recurso também pode ser carregado explicitamente, veja mais detalhes em Loading JavaScript as a Resource no The Java EE 6 Tutorial.

No próximo post veremos como enviar uma requisição Ajax e receber uma resposta. Até lá.

terça-feira, 30 de outubro de 2012

[JavaScript] Onde colocar o script?

Salve salve. Conforme prometido, segue o post (que já estava preparado, mas faz de conta que não), sobre onde colocar o bloco <script> na sua página.

Alguns podem estar se perguntando, mas que importância tem a localização do bloco <script>. Respondo: Muita!

É verdade. Muita coisa pode melhorar ou piorar quanto a performance de execução da sua página a depender da localização do seu javascript, acredite.

Para entender melhor, vamos falar um pouco sobre carga e execução da página.

Como você já sabe, sua página HTML é interpretada e executada pelo seu navegador (sério!?). Ocorre que - regra geral - ao encontrar blocos <script> a execução de HTML é interrompida para que o script seja carregado, interpretado e executado e só então a execução do HTML continua.

Como o processo que executa a página é o mesmo (HTML e JavaScript) - regra geral - não dá pra fazer as duas coisas ao mesmo tempo.

Ainda existe o problema de você carregar um script de manipulação de um elemento DOM antes da declaração do elemento em HTML. O resultado disto é que seu script não poderá manipular o objeto, pois ele ainda não existe, não foi interpretado e muito menos executado pelo browser.

Neste momento, é irrelevante se o código está declarado dentro da tag <script> ou em um arquivo externo .js referenciado no atributo src daquela tag. A página vai ter que esperar até que o código seja baixado, lido e executado.

A especificação do HTML 4 indica que <script> deve ficar em <head> ou <body> e pode aparecer várias vezes dentro destes dois elementos.

Tradicionalmente, as tags <script> são utilizadas para carregar arquivos .js e são posicionadas no <head> junto com tags <link> que carregam arquivos .css.

Pense no seguinte: O HTML só vai começar a ser renderizado, após todos os scripts referenciados serem baixados e executados. Se você permitisse que todo o conteúdo HTML fosse carregado antes dos scripts, talvez pudesse melhorar a percepção de performance da página. Lembre-se que os navegadores não começam a mostrar nada na página (fica em branco) até que cheguem na tag <body>. Se os scripts forem pesados, o delay da página em branco será maior e consequentemente a percepção de lentidão vai aumentar. Observe um exemplo hipotético de página com 3 scripts referenciados em seu <head> e o tempo de carga/execução de cada um deles:

  • arquivo1.js (500ms).
  • arquivo2.js (350ms).
  • arquivo3.js (400ms).

Movendo estas referências para o final da página, você irá ganhar mais de 1s no início da exibição do documento, o suficiente para melhorar a percepção de performance.

IE 8+, Firefox 3.5+, Safari 4+ e Chrome 2+ já permitem o download paralelo dos recursos externos, incluindo outros scripts. Mesmo assim, o download dos scripts irá concorrer com o download de outros recursos visuais da página e o cliclo de vida irá interromper a execução da página até que todos os scripts do <head> sejam executados.

Conclusão: Colocar os scripts mais próximos do rodapé da página, antes de </body>, pode melhorar a performance, este é o posicionamento recomendado, respeitando a ordem de dependência dos scripts. Ah! Muito importante: Mantenha os blocos <script> agrupados e compactados. Várias técnicas de compactação e agrupamento de scripts estão disponíveis, dentre elas a minificaçao e a concatenação de scripts por uma ferramenta de build como o Yahoo combo handler, que permite que você referencia mais de um script em uma mesma tag <script>, mas estes são assuntos para serem explorados em outra oportunidade.

Espero que estes conhecimentos lhe sejam úteis de alguma forma.

Forte abraço,

Mauricio da Silva Marinho.

[JavaScript] Scripts Dinâmicos

[JavaScript] Scripts Dinâmicos.

Com conhecimentos de DOM (Document Object Model) você pode criar praticamente qualquer parte do seu HTML dinamicamente, usando apenas JavaScript. O elemento <script> não é diferente. Referências podem ser recuperadas do DOM, modificadas, removidas ou até mesmo criadas. Um novo elemento <script> pode ser facilmente criado usando métodos do DOM da seguinte forma:

var script = document.createElement("script");
script.type = "text/javascript"; //desnecessario no HTML5
script.src = arquivo1.js;
document.getElementsByTagName("head")[0].appendChild(script);

Este novo elemento <script> carrega o arquivo arquivo1.js. O arquivo começa a ser transferido para o browser tão logo o elemento seja adicionado na página. Vale lembrar que a interpretação do HTML é interrompida cada vez que um elemento <script> é encontrado e retomada após a execução do código em <script>.

O interessante nesta técnica, é que o arquivo é transferido e executado sem bloquear outros processos na página, não importando onde o download tenha sido iniciado. Você pode colocar este código no <head> do documento sem afetar o resto da página.

OBS: Trataremos do melhor lugar para colocar o <script> no próximo post. Por enquanto, é mais seguro colocá-lo no <head> e não no <body>, especialmente se tratamos de um elemento <script> executado durante o carregamento da página. No IE, se o <script> estiver no <body> é possível receber um erro do tipo "operation aborted" se todo o conteúdo do <body> não estiver completamente carregado.

Quando um arquivo é carregado pela criação dinâmica de um nó <script> no DOM, o código transferido, geralmente, é executado imediatamente (ressalvas para o Firefox e Opera, que irão aguardar até que <script>'s anteriores sejam executados.

Isto funciona bem com scripts auto suficientes (sefl-executing), mas podem ser problemáticos se o código contém interfaces para serem usadas por outros scripts na página. Neste caso você precisa rastrear quando o código foi completamente carregado e está disponível para uso. Se não estiver utilizando JQuery, teremos que fazê-lo pelos eventos que podem ser disparados pelo <script>.

Firefox, Opera, Chrome e Safari 3+ disparam um load quando o src de um <script> for recuperado. Você pode programar uma notificação, atribuindo a este evento uma função anônima para ficar ouvindo-o:

var script = document.createElement("script");
script.type = "text/javascript";

//Firefox, Opera, Chrome, Safari 3+
script.onload = function(){
    alert("Script carregado!");
};

script.src = "arquivo1.js";
document.getElementsByTagName("head")[0].appendChild(script);

No IE, bom... no caso do IE, pra variar, é diferente. Este navegador suporta uma implementação alternativa que dispara um evento readystatechange. Existe uma propriedade readyState no <script> que é carregada várias vezes durante a transferência do arquivo referenciado em seu src. Existem cinco possíveis valores para esta propriedade, são eles:

  • uninitialized, que é o default.
  • loading, quando o download do arquivo começa.
  • loaded, quando o download do arquivo termina.
  • interactive, quando os dados já foram baixados mas ainda não estão completamente disponíveis.
  • complete, quando os dados baixados estão prontos para serem utilizados.

O IE mostra-se inconsistente com os valores loaded e complete. Por vezes ele irá atingir o estado loaded e vai parar, sem disparar o complete. Calma que ainda pode piorar: outras vezes ele vai atingir o complete sem passar pelo loaded.

Sendo assim, é preciso tratar os dois estados relevantes para o carregamento loaded e complete, removendo o event handler (a função anônima atribuída ao evento) quando qualquer um deles ocorrer, para evitar de tratarmos duas vezes a mesma coisa (Ê laiá):

var script = document.createElement("script);
script.type = "text/javascript";

//Internet Explorer
script.onreadystatechange = function(){
    if(script.readyState == "loaded" || script.readyState == "complete"){
        script.onreadystatechange = null; //remove o event handler
        alert("Script carregado, eu acho!");
    }
};

Espero que os conhecimentos deste post lhe sejam úteis. No próximo post veremos o melhor lugar para colocar nossos scripts na página. Forte abraço.

Fonte: High Performance Javascript (Build Faster Web Application Interfaces) - Kindle Version, Location 603. Adaptações e sarcasmos de Mauricio da Silva Marinho.