Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

RSS iMasters

[Resolvido] Acelere o carregamento de páginas: técnicas incomuns

Recommended Posts

Este artigo dá continuidade à série que trata de técnicas não usuais para o aumento de velocidade de sites. Os outros artigos podem ser acessados aqui e aqui.

Introdução

Muitas daslongas tarefas que os scripts no lado do servidor executam são tarefas em que osscripts estão esperando por outro programa, hardware ou computador responder.

Por exemplo, quando seus scripts acessam um banco dedados, eles têm que estabelecer uma conexão e então executar as consultas nobanco. Na maior parte do tempo em que seu script está estabelecendoconexões e executando consultas, ele não está fazendo mais nada além deesperar pelo dado requerido ser enviado para o servidor do banco de dados epela resposta do servidor do banco. 

E se ao invés de apenas esperar pelo servidor dobanco de dados receber ou responder aos pedidos, o seu script pudesse fazeralgo em paralelo? Essa é a premissa da programação assíncrona.

Oque é programação assíncrona?

Imagine que vocêestá preparando o jantar. Digamos que você terá no jantar sopa de entrada,carne assada como prato principal e bolo de sobremesa.

Você pode preparar e cozinhar cada parte do seujantar uma a uma, mas como cada uma delas precisa que você utilize o forno, enquantouma está dentro dele, ao invés de ficar parado esperando, você podepreparar outra parte e colocá-la no forno ao mesmo tempo.

Você pode chamar essa prática de cozinhar várias partesdo seu jantar em paralelo de cozinha assíncrona. Parece mais lógico e eficientefazer isso, pois você pode terminar de preparar o seu jantar muito mais rápidose conseguir cozinhar várias partes do jantar em paralelo.

A programação assíncrona funciona da mesma maneira.Imagine que você tenha a página de um site feita de conteúdo recuperado de umbanco de dados que está executando várias consultas. Normalmente você executauma consulta, espera pela resposta, recupera os resultados em algumasvariáveis, e assim por diante. Só que no final você reúne todos os dados paragerar a página HTML final. Agora, imagine que ao invés de esperar pelosresultados, você pudesse começar imediatamente a nova consulta enquanto o bancode dados não devolve a resposta para a primeira consulta? Você poderia ganharbastante tempo, precisamente pelo mesmo motivo pelo qual você ganharia tempo secozinhasse várias partes do seu jantar ao mesmo tempo.

Implementandoa programação assíncrona na prática

Nas linguagens de programação de baixo nível, você precisausar chamados para o sistema operacional subjacente para saber quando o seuprograma está esperando por algum evento para, quando isso acontecer, vocêacionar a ação apropriada. Se o seu programa estiver esperando por múltiplostipos de eventos, ele pode apurar periodicamente os diferentes recursos dosistema para checar se algum evento aconteceu.

Seria comochecar se as diferentes partes do seu jantar sendo preparadas no forno estãoprontas antes de seguir para os próximos passos da receita.

Em linguagens de programação de alto nível,geralmente existe uma maneira mais simples de implementar a programaçãoassíncrona. Geralmente você chama alguma função para registrar uma função callback. Ela é invocada quando algum evento ocorre. Vocêpode registrar várias funções callback, que são chamadas quando diferentestipos de eventos acontecem.

Implicitamente, existe algum event loop checando paraver se algum dos eventos nos quais seu programa está interessado aconteceram.Mas você não tem que tomar conta disso diretamente no seu programa. O ambientede execução executa o event loop e chama suas funções callback quandonecessário.

Programação assíncrona no JavaScript

Umexemplo de linguagem de programação de alto nível que fornece suporteintrínseco para a programação assíncrona é o JavaScript. No lado do browser,geralmente você define qual código é chamado quando diferentes tipos de eventosacontecem.

Você pode fazer isso, por exemplo, acionando osatributos ON das tags das páginas (ONCLICK, ONMOUSEOVER, ONCHANGE etc).

<div id="mydiv" onclick="alert('Click!');">Click me!</div>

Alternativamente, você pode chamar funções de certoselementos objetos da página para registrar um evento funções callback, comoaddEventListener.

<div id="mydiv">Click me!</div>

 

<script type="text/javascript"><!--

 

document.getElementById('mydiv').addEventListener(

'click',

function()

{

alert('Click!');

},

false);

 

// --></script>

Programação assíncrona do lado do servidor no JavaScript com Node.js

Os exemplosacima descrevem como funciona no lado do browser. Agora você deve estar seperguntando: uma vez que geralmente você apenas executa um conjunto claro deinstruções em scripts do lado do servidor e então seu script sai, faz sentidousar programação assíncrona em aplicações do lado do servidor?

Como mencionei acima, faz sentido se você precisarexecutar várias tarefas e puder executá-las em paralelo. No exemplo quemencionei sobre recuperar os resultados de consultas múltiplas, você poderiausar a programação assíncrona para terminar o trabalho mais depressa.

Uma abordagem de maior nível usando funções callback para eventos handle no lado do servidor seria ótimo. O JavaScript étradicionalmente usado no lado do browser, mas há anos existem soluçõesJavaScript para scripts desenvolvidos no lado do servidor, que usam o métodoevent callback handler para implementar a programação assíncrona.

Uma dessas soluções é o Node.js, que é um framework que roda no topo do mecanismo JavaScriptGoogle V8. V8 é o mesmo mecanismo JavaScript que vem com o Google Chrome. Ele é bastante rápido porque usa técnicas avançadas para compilarimplicitamente o JavaScript no código nativo da máquina correspondente a suaCPU.

Mas o V8 não precisa do Google Chrome. É ummecanismo JavaScript que pode ser incorporado em outros programas. O Node.js éum programa que incorpora o V8. O Node.js na verdade estende o V8 para fornecervários módulos JavaScript que executam operações que são mais comuns no lado doservidor de programação, como por exemplo arquivos de acesso, banco de dados ecomunicação através de rede.

Hoje em dia, o Node.js vem com tantos módulos quevocê pode implementar a maioria das tarefas que você implementaria em PHP paraaplicações do lado do servidor. Até certo nível, você pode ver o Node.js como oPHP para JavaScript. Quer dizer, você poderia desenvolver as mesmas aplicaçõesdo lado do servidor em JavaScript com o Node.js, como você pode fazer com o PHP.

A grande diferença entre o Node.js e o PHP é que como Node.js, por padrão, tudo é assíncrono. Isso significa que toda função doNode.js para cada programa que você tem que esperar, a função retorna imediatamente, e o Node.js irá invocar uma função callback passada pelo seuprograma quando a tarefa da função em questão terminar.

Por exemplo, se você quiser abrir um arquivo, ler ouescrever um arquivo, listar um diretório, consultar um DNS para resolver algunsendereços, enviar um pedido para um servidor remoto, abrir uma conexão com oservidor de um banco de dados, executar uma consulta de banco de dados etc,você sempre tem que passar uma função callback para lidar com o resultado dafunção.

 

Deixe-me mostrar a vocês um simples exemplo de códigousando o Node.js para listar o diretório atual.

var fs = require('fs');

 

fs.readdir(".", function(error, files)

{

if(error)

throw error;

for(var f in files)

console.log("Path: " + files[f]);

}

);

Se você quiserdar uma olhada em uma situação mais complexa e ver como ela é comparada com aprogramação assíncrona tradicionalmente feita em PHP, você pode checar essemódulo Node.js para executar a validação de um endereço de e-mail checando o destino do servidor SMTP. Essa é uma parte do e-mail adddres validation class que escrevi em PHP muitos anos atrás.

Programaçãoassíncrona no PHP

Diferentemente do Node.js, no PHP tudo é síncrono porpadrão. Isso significa que quando você chama qualquer função, o PHP sempreespera a função terminar seu trabalho e retornar seu resultado no final.

Atualmente o PHP não fornece nenhum tipo de suporteintrínseco para executar programação assíncrona usando callbacks. Existe algumsuporte para implementar a programação assíncrona em PHP usando a função stream_select. Essa função permite que os scripts PHP apurem arquivos abertosou conectores para conexões de rede para ver se ler ou escrever dados emarquivos é possível ou se a rede bloquearia. O PHP consegue dizer à função paraesperar por um certo período até que qualquer dado seja recebido ou tenhaterminado de ser enviado.

Isso é claramente insuficiente para se ter uma programaçãoassíncrona plena no PHP. O Node.js tem suporte para implementar muitos outrostipos de operações assíncronas, como por exemplo a checagem de arquivo(listagem de arquivos e checagem de permissões etc...) e acesso a alguns tiposde bancos de dados assincronamente.

 

A limitação não é somente da linguagem PHP. São asextensões PHP que poderiam fornecer suporte assíncrono intrínseco, masatualmente elas não funcionam.

Uma solução alternativa para implementar aprogramação assíncrona no PHP é usar o Gearman. Para aqueles que não sãofamiliares com o Gearman, ele é um programa de middle-ware que age como um servidorque pode receber chamados para funções implementadas por programas trabalhadores que rodam nobackground.

Os programas trabalhadores podem ser escritos em PHPde forma que eles possam implementar quaisquer funcionalidades que vocêprecise. Programas trabalhadores podem rodar na mesma máquina ou até emmáquinas remotas. Você pode gostar de ler o artigo escrito por César Rodassobre como usar o Gearman com PHP paraaprender mais sobre o Gearman.

Um recurso útil do Gearman que pode habilitar aprogramação assíncrona no PHP é o suporte para chamados de trabalhosassincronamente. Isso significa que quando um trabalho é chamado, o script dachamada não tem que esperar pelo trabalho terminar. Coletando os resultados dostrabalhos assíncronos pode ser complicado, então essa solução não é ideal.

Outra solução é usar a extensão pcntl do PHP para deslocar novos processos e executar os scripts PHP emparalelo. Mesmo essa solução funcionando até certo ponto, ela custa caro emtermos de CPU e memória, que são necessários para os novos processos debifurcação.

Conclusão

Como você já deve saber, a programaçãoassíncrona, quando possível, não é algo atualmente natural de se fazer no PHP.Como mencionei acima, a limitação não é da linguagem em si. Algumas extensõesdo PHP precisariam evoluir para suportar a programação assíncrona de um modomais natural, como no Node.js.

O PHP tem suporte para closures na versão 5.3. Closuressão basicamente funções anônimas que podem ser usadas diretamente para definiruma função callback no chamado da função que tem um callback handler. Foi umgrande passo na evolução do PHP, pois elas deixam os callbacks baseados emprogramação assíncrona mais amigáveis para serem desenvolvidos em PHP.Antigamente você teria que sempre declarar funções nomeadas para usá-las comocallbacks.

Por outro lado, a programação assíncrona usandocallbacks que você vê no Node.js é complicada. Ela muda completamente a maneiracomo você pensava ao definir o fluxo de controle do seu código. Por exemplo, sevocê quiser executar um loop no qual o que você faz em cada iteração depende doresultado de um evento que aciona um chamado para uma função callback, issofica difícil de implementar para desenvolvedores que estão acostumados somentecom códigos sincronizados.

Existem algumas técnicas sobre como trabalhar emvolta dessas esquisitices da programação assíncrona, mas esse é um escopo quenão está a alcance deste artigo. Aqui está um texto que te dá uma ideia sobre lidar com osdesafios do fluxo de controle da programação assíncrona.

Vai demorar um pouco para você se acostumar com aprogramação assíncrona usando callbacks e se tornar produtivo desenvolvendosoftwares dessa maneira.

Em resumo, eu gostaria de dizer que irá levar umtempo para que a programação assíncrona se torne algo mais natural no PHP.Ainda existem alguns casos em que valeria a pena usá-la, mesmo com o suportelimitado do PHP. Tudo objetivando a otimização extrema da execução de tarefasque podem ser feitas em paralelo, da mesma maneira que preparar seu jantar nomenor tempo possível ao colocar no forno vários tipos de comida ao mesmo tempo.

?

Texto original disponível em http://www.phpclasses.org/blog/post/133-Accelerate-scripts-running-multiple-tasks-in-parallel-using-asynchronous-programming-Unusual-Site-Speedup-Techniques-Part-3.html

 

http://imasters.com.br/artigo/21906/php/acelere-o-carregamento-de-paginas-tecnicas-incomuns-de-aumento-de-velocidade-de-sites-parte-3

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.