O que é Page Visibility – Palestra do SampaJS

Pelo segundo ano consecutivo o SampaJS aconteceu quando eu estava viajando e não pude participar. O Daniel Filho falou sobre Page Visibility, uma API bacana que permite melhorar ainda mais a interação com o usuário verificando se sua página está ativa no navegador do usuário.

Page Visibility

 

E se você quer saber mais sobre Page Visibility vale a pena ver a documentação na W3C.

Javascript – o método call() e apply()

Todas as funções do javascript possuem alguns métodos como toString(), call() e apply(). Antes de explicar o método function.call() vou exemplificar o funcionamento das funções e escopos, que acredito que isso facilite o entendimento.

Exemplo de código:

var url = 'andafter.org';
function f(){
    console.log(this);
    console.log(this.url);
}
f();

Nesse código eu seto uma variável global url, e quando chamo a função f dou um log em "this" (é a window), então quando chamo this.url o retorno é a variável instanciada fora da função.

O método call()

O método function.call() permite você dizer em qual escopo (essa é a nomenclatura certa? comentem suas opiniões) uma função deve ser executada.

Voltando ao exemplo de código anterior:

var url = 'andafter.org';
var site = { url : 'odesenvolvedor.com.br' };
function f(){
    console.log(this.url);
}
f.call(site);

O function.call() define o que será o "this" dentro da função, e este deve ser passado como parâmetro para o método call.

 

Método call com parâmetros

No exemplo anterior não fizemos uso de parâmetros, apenas do "this". Mas o método call pode receber a partir do segundo parâmeto (o primeiro sempre será o escopo que será atribuído ao this) os parâmetros que serão passados para a função.

var url = 'andafter.org';
var site = { url : 'odesenvolvedor.com.br' };
function f(p1, p2){
    console.log(this.url + ' - ' + p1 + ' - ' + p2);
}
f('aprendendo javascript', 'no andafter!');
f.call(site, 'estudando códigos', 'no desenvolvedor');

O método function.apply()

O método function.apply() tem o mesmo funcionamento do function.call() com uma diferença na forma dos parâmetros, o segundo parâmetro sempre deverá ser um array, contendo todos os parâmetros que serão enviados para a função.

O primeiro parâmetro continua sendo o escopo onde sua função será executada.

var url = 'andafter.org';
var site = { url : 'odesenvolvedor.com.br' };
function f(p1, p2){
    console.log(this.url + ' - ' + p1 + ' ' + p2);
}
f('aprendendo javascript', 'no andafter!');
f.apply(site, ['estudando códigos', 'no desenvolvedor']);

Agora você já sabe como definir em qual escopo uma função será executada, e também tem um facilitador para funções que chamam funções.

Este é um post introdutório para alguns códigos mais complexos que virão, quase todos resultados das minhas pesquisas de performance de javascript e desenvolvimento de bibliotecas como o jQuery Lazy Load.

Nova versão do jQuery Lazy Load

Conversando com o Rafael Cavalcante sexta ele me lembrou que eu ainda devia melhorias para aplicar no jQuery Lazy Load Plugin.

Comecei sexta e testei hoje, está tudo no Github.

jQuery Lazy Load Changelog

  • Melhoria de performance
  • Não precisa mais de classe para trabalhar

Changelog detalhado:

Devido as preocupações com performance de javascript mudei um pouco forma como o plugin trabalha.

Com o uso do grep no lugar do each, o jQuery Lazy Load está agora removendo do seu array  todas as imagens que já for carregadas. Elas não são percorridas repetidamente (como acontecia na versão 0.5) e a performance melhorou bastante por conta disso.

Também por conta desta nova forma de trabalhar com o array não é mais necessário o uso de classe (a classe era utilizada para verificar se uma imagem já havia sido carregada). Como preciso manipular menos o DOM também houve ganho de performance por conta disso.

 

Como usar o jQuery Lazy Load

Baixa a última versão do plugin no Github.

Chamando os scripts

Chame o jQuery e o jQuery Lazy Load plugin na sua página.

Preparando as imagens

As imagens que utilizarão o lazy load devem ter a tag data-src com o valor da url da imagem que deverá ser carregada no conteúdo.

Uma dica é chamar o src das imagens para uma imagem transparente e sempre estipular a largura e altura da imagem no próprio HTML, assim sua página vai renderizar mais rápido pois você irá reduzir o reflow do browser.

Outra dica é através de CSS colocar uma imagem de loader como background das imagens que utilizarão o plugin de lazy load, assim se as imagens demorarem para carregar seu usuário terá uma experiência melhor e saberá que algo está acontecendo.

 

Iniciando o Lazy Load

Por último, é só iniciar o plugin com o seletor das imagens que irão utilizar o plugin:

$(function() {
$('.lazy').lazyLoad();
});

 

Pronto, agora seus usuários só carregarão imagens quando necessário.

Javascript: como alterar o intervalo de um timeout?

Estou estudando NodeJS (veja como instalar o NodeJS no Ubuntu) e meu interesse por javascript aumentou com isso – comecei projetos para estudar desenvolvimento de games em javascript.  Nesses estudos percebi que o  setInterval e setTimeout são grandes ferramentas para a criação de scripts complexos, mas que são pouco explorados normalmente. 

Como alterar o interval no Javascript?

Supondo que você instanciou uma função para ser executada 10 segundos depois que o usuário entrar na página (setTimeout). Mas caso o usuário clique no botão Y esta função tem que ter um novo delay, novamente de 10 segundos.

Não encontrei uma maneira de alterar um timeout ou interval em andamento, então a lógica é cancelar o timer que está em funcionamento e setar um novo timer, com o intervalo desejado.

Vamos por partes, cancelando a função já instanciada.

 

Como cancelar um setTimeout em javascript

Nosso código:

var agendamento = setTimeout(function(){
 console.log('ação agendada!');
}, 1000);

/* Cancela o agendamento */
clearTimeout(agendamento);

Simples assim! 

Alterando o intervalo com ação do usuário

var agendamento = setTimeout(function(){
 console.log('ação agendada!');
}, 1000);

$('a.cancela').click(function(){
 clearTimeout(agendamento);
 var agendamento = setTimeout(function(){
  console.log('ação agendada!');
 }, 1000);
});

 

Poderia melhorar o código transformando a criação do agendamento em uma função, mas optei por deixar o mais legível para facilitar o entendimento.

Tem alguma forma diferente de fazer isso? Deixe um comentário!

O que é browser reflow?

Com o crescimento da banda larga e a evolução da web como um todo, a preocupação de performance deixou de ser exclusividades dos desenvolvedores back-end e se tornou uma grande preocupação de front-end.

Essas preocupações me levaram a melhorar muito meu código javascript (vejas estas dicas de performance em javascript) e aqui no iG comecei a estudar melhor a forma que os navegadores trabalham a fim de melhorar a performance desde a parte do HTML.

O que é browser reflow?

O "browser reflow" é uma tarefa do navegador que calcula o posicionamento e dimensão de todos os elementos da sua página. O navegador percorre toda a árvore DOM mesclando a estrutura do HTML com o CSS (externou ou inline) que fica na "style structure", isso forma a Render Tree, que é o que nós visualizamos.

A cada reflow, todos os elementos tem o tamanho e reposição calculadas, por isso que um excesso de reflow causa mais processamento e consequentemente páginas com uma renderização mais demorada.

Para entender melhor o que é um reflow, assista o vídeo de como o navegador renderiza o HTML, neste mesmo post.

O que é um repaint?

Repaint é quando acontece uma alteração visual no elemento (cor, background) que não altera suas dimensões (margem, padding, largura ou altura). O repaint é menos custoso em termos de processamento.

 

Minimzando o browser reflow

Agora que você já sabe o que é reflow e sabe o impacto na performance da exibição da página, a redução do desse processamento se torna mais importante para saber como fazer páginas rápidas.

O Google tem um vídeo bacana (em inglês) com algumas dicas para minimizar o reflow:

Dicas para manter suas páginas mais rápidas

  • Minimize o browser reflow
  • Reduza o HTML desnecessário do DOM e tente manter a árvore o mais "raza" possível. Quando uma alteração é feita em algum elemento ele causa efeitos em toda a árvode DOM, quando menos profunda ela for mais rápido será o reflow e qualquer outra manipulação no DOM.
  • Minimize o CSS e remova CSS que não é utilizado – o CSS é "interpretado" para formação da render tree, e o CSS "sobrando" sem dúvida vai tornar a render tree mais lenta, refletindo diretamente na experiência do usuário ao navegar nas suas páginas.
  • Para fazer animações e layouts mais complexos, sempre que possível faça isso fora do "reflow", para isso utilize posição absoluta ou fixed.
  • Evite seletores de CSS complexos, quanto mais profundo e complexo for um seletor mais custoso em performance será para mondar a render tree da página.

 

Como o browser renderiza sua página?

Para exemplificar melhor os assuntos que tratamos, abaixo tem um vídeo da Mozzilla, que mostra como o browser trabalha para renderizar uma página.

Não deixe de ver a apresentação sobre performance em javascript, outro fator muito importante quando falamos de performance no front-end.

Vamos fazer uma web mais rápida? 🙂

Referências:

Googl e code

Tableless