Um pequeno resumo da documentação da extensão
YSlow para o
Firefox, encontrado em inglês em:
Best Practices for Speeding Up Your Web Site
A extensão, que mede o desempenho de sites no Firefox, pode ser encontrada em:
Obs.: O original é bem mais detalhado e com muito mais informações, aqui trago apenas o que achei mais interessante ou importante.
80% do tempo gasto pelo visitante para baixar uma página é gasto no front-end (cliente) e somente 20 no back-end (servidor).
Desses 80%, a maioria é gasto baixando componentes: imagens, CSS, script JS, Flash etc.
Reduzindo o número de componentes do site reduzirá as requisições HTTP para renderizar a página no cliente. Esta é a chave de páginas rápidas.
Simplificar o design das páginas reduzirá o número de componentes.
Abaixo algumas técnicas para reduzir o número de requisições e ao mesmo tempo manter um design rico.
Usar CSS sprites reduz o número de requisições de imagens, ao invés de requisitar várias requisita-se somente uma e o CSS mapeia usando o background-image e background-position. Exemplo em:
RibaFS - Sprites em CSS
Combinar, quando possível todo o CSS em um único arquivo externo.
Mova o CSS para o topo da página, entre as tags <head> e </head> que a página será carregada mais rapidamente.
Já os scripts em JavaScript devem ser movidos para o final da página, para que a carga seja otimizada. É verdade que em algumas situações não dá para mover para o final da página, mas sempre que possível devemos fazê-lo.
O IE suporta expressões em CSS e para melhor desempenho evite estas expressões.
Sempre que possível tenha o CSS e o JavaScript em arquivos externos para melhor desempenho.
Otimize para reduzir o código do CSS e do JavaScript.
Remova caracteres desnecessários, linhas e trechos duplicados e otimize ao máximo seu código. Isso vale também para toda a construção do site, evitar tudo que seja desnecessário e otimizar o necessário.
Evite redirecionamentos.
Não tenha mais que 3 redirecionamentos na página. Exemplo: temos 3 banners cujas imagens vem de outras URLs. No caso o site só abrirá quando pegar as imagens dos outros sites. Estando tudo normal ele terá que fazer a requisição aos outros sites e imagine quando um deles está lento.
Use GET para as requisições de AJAX. São mais rápidas que usando POST.
Otimize ao máximo a página inicial, reduzindo a carga para que o visitante chegue.
Nas demais páginas poderá adicionar componentes que colocaria na inicial.
Minimizar o número de iframes.
Evite erro 404 (páginas não encontradas).
Use o serviço do servidor para redirecionar o usuário para uma página personalizada quando acontecer um erro 404.
Reduza o tamanho dos cookies.
Minimize acessos DOM.
Desenvolva manipuladores de eventos inteligentes.
Acontece de um evento somente ser disparado quando um outro o for e isso pode complicar. Mais detalhes no documento original.
Ao fazer link dos arquivos externos prefira <link...> ao invés de @import.
Evite filtros no CSS.
Otimize as imagens. Sempre antes de enviar as imagens para o servidor, reduza seu tamanho, como também reduza a quantidade de cores sempre que razoável.
Alguns serviços online que ajudam na otimização de imagens:
Otimize os sprites CSS.
As imagens ficando na horizontal ao invés da vertical carregam mais rapidamente.
Não altere as dimensões de imagens somente no HTML. Isso altera somente a visualização, mas seu tamanho permanece o mesmo. Altere seu tamanho offline e envie para o servidor ao invés.
Reduza o tamanho dos favicon.ico.
Mantenha o tamanho dos componentes sempre inferior a 25KB.
Lembre que esse valor é para o arquivo descompactado.
Mais informações no documento original em inglês:
Best Practices for Speeding Up Your Web Site
Página deste artigo:
Melhores práticas para um site mais rápido
PESSOAL, BOA TARDE!!! Por favor, ajudem-me a resolver um problema de lentidão AJAX no servidor WEB.
..........................................................................................................................................................
Uso a muito tempo Ubuntu (agora versão 10 64bits), apache2, php5, mysql5 e, desenvolvi um sistema com tecnologia Ajax x PHP e Mysql. Uso orientação a Objetos em PHP. A estrutura PHP está assim:
arquivo (classe) principal: chamarClass.php
---------------------------------------------------------------------------------------------------------------------------------------------------------------
<?php
session_start();
require_once 'cmdSql.php';
require_once 'pesquisaSql.php';
class chamarClass extends cmdSQL {
public $funcao;
public function __construct() {
$this->funcao = $_POST[funcao];
$this->funcao();
}
public function funcao() {
switch ($this->funcao) {
case 'pesqTurma':
//echo "teste1: ".$this->funcao; exit;
$pesquisaSql = new pesquisaSql();
//echo "teste3: ".$this->funcao; exit;
$this->sql = $pesquisaSql->pesqTurma();
//echo "teste2: ".$this->sql;exit;
$this->pesquisar();
break;
case 'pesqDiasSemana':
$pesquisaSql = new pesquisaSql();
$this->sql = $pesquisaSql->pesqDiasSemana();
$this->pesquisar();
break;
case 'pesqDisponibilidadeTurno':
$pesquisaSql = new pesquisaSql();
$this->sql = $pesquisaSql->pesqDisponibilidadeTurno();
$this->pesquisar();
break;
case 'pesqOutroTemaInteresse':
$pesquisaSql = new pesquisaSql();
$this->sql = $pesquisaSql->pesqOutroTemaInteresse();
$this->pesquisar();
break;
case 'pesqCargaHrDesejada':
$pesquisaSql = new pesquisaSql();
$this->sql = $pesquisaSql->pesqCargaHrDesejada();
$this->pesquisar();
break;
case 'pesqCursoRealizado':
$pesquisaSql = new pesquisaSql();
$this->sql = $pesquisaSql->pesqCursoRealizado();
$this->pesquisar();
break;
default:
echo "funcao indefinida";
session_destroy(); // DESTRUIR SESSÃO POIS PODE SER TENTARIVA DE CÓDIGO MALICIOSO
exit;
break;
}
if (is_array($this->retorno)
)$this->extraiArrayXml();
///echo $this->xml; exit;
if ($this->xml != ''
)echo $this->exibeXml();
}
}
$chamarClass = new chamarClass();
?>
------------------------------------------------------------------------------------------------------------------------------------------------
que extende a classe cmdSql: cmdSql.php
-----------------------------------------------------------------------------------------------------------------------------------------------
<?php
/* DEFINIÇÃO DESTA CLASSE: Receber as strings básicas Sql e executar (select / insert / update / delete)
* setar o resultado das instruções sql executadas no atributo 'retorno' e ...
* de uma classe extendida dessa se pode gerar a string xml e ...
* exibir o xml
*/
require_once("Banco.php");
class cmdSQL extends Banco {
public $retorno; //GUARDA O RETORNO DA INSTRUÇÃO SQL EXECUTADA
public $rs; // SETA O RECORDSET
public $sql;
public $xml;
//||||||||||||| COMANDOS DE SQL PARA OPERAÇÕES BÁSICAS |||||||||||||||||||||
//++++++++++++++++++++++++++ PESQUISAR ++++++++++++++++++++++++++
public function pesquisar() { // inicio do function PESQUISAR
//if ($sql)$this->sql = $sql;
try {
$this->conectar();
try // depende do resultado das instruções SQL a seguir
{
$this->rs = $this->con->prepare($this->sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$this->rs->execute(); //executa a instrução sql
$this->retorno[n_reg] = $this->rs->rowCount();
$this->retorno[n_cols] = $this->rs->columnCount();
//echo "teste0: ". $this->retorno[n_reg]; exit; //LINHA SÓ P/ TESTE;
if (($this->retorno[n_reg])>0) {
$this->retorno[res]=$this->rs->fetchAll(PDO::FETCH_ASSOC); //Retorna todas as linhas (registros) como um array
}
else {
//Mensagem alertando que não econtrou registros
$this->retorno[msg] .= "Registro(s) não encontrado(s).";
}
}
catch (Exception $e) {
$this->retorno[msg] .= "\nErro: Código: " . $e->getCode() . "Mensagem " . $e->getMessage();
}
} catch (Exception $exc) {
$this->retorno[msg] .= $this->msg." <hr> ".$exc->getTraceAsString();
}
return $this->retorno;
} // fim do function PESQUISAR
//++++++++++++++++++++++++++ INCLUIR ++++++++++++++++++++++++++
public function incluir() {
//$this->Banco = new Banco();
$this->conectar();
if (isset ($this->con)) {
try {
$this->rs = $this->con->prepare($this->sql);
$this->rs->execute();
$this->retorno[msg] = 'Registro salvo com sucesso!';
}
catch (Exception $e) {
$this->retorno[msg] = "Erro de inclusão: Código: " . $e->getCode() . "Mensagem " . $e->getMessage();
}
}
return $this->retorno;
}
//++++++++++++++++++++++++++ ALTERAR ++++++++++++++++++++++++++
public function alterar() {
//$this->Banco = new Banco();
$this->conectar();
if (isset($this->con)) {
try {
$this->rs = $this->con->prepare($this->sql);
$this->rs->execute();
$this->retorno[msg] = 'Registro alterado com sucesso!';
}
catch (Exception $e) {
$this->retorno[msg] = "Erro: Código: " . $e->getCode() . "Mensagem " . $e->getMessage();
}
}
//return $this->retorno;
}
//++++++++++++++++++++++++++ EXCLUIR ++++++++++++++++++++++++++
public function excluir() {
//$this->Banco = new Banco();
$this->conectar();
if(isset($this->con)) {
try {
$this->rs = $this->con->prepare($this->sql);
$this->rs->execute();
$this->retorno[msg] = 'Registro alterado com sucesso!';
}
catch (Exception $e) {
$this->retorno[msg] = "Erro: Código: " . $e->getCode() . "Mensagem " . $e->getMessage();
}
}
return $this->retorno;
}
public function extraiArrayXml() {
try {
if ($this->retorno[res]) {
foreach ($this->retorno[res] as $lin) {
foreach ($lin as $k=>$col) {
$linha .= "<".$k.">".utf8_encode($col)."</".$k.">";
}
}
$this->xml .= "<registros>".$linha."</registros>";
}
if ($this->retorno[n_reg]) $this->xml .= "<n_reg>".$this->retorno[n_reg]."</n_reg>";
if ($this->retorno[n_cols]) $this->xml .= " <msg> ".$this->retorno[n_cols]." </msg>";
if ($this->retorno[msg]) $this->xml .= " <msg> ".$this->retorno[msg]." </msg>";
} catch (Exception $exc) {
echo "Erro de extração da Array para XML.<hr>".$exc->getTraceAsString();
}
}
// %%%%%%%%%%%%%%%% EXIBE XML %%%%%%%%%%%%%%
public function exibeXml() {
try {
$this->xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><raiz>".$this->xml."</raiz>";
header("Content-type: application/xml");
return $this->xml;
} catch (Exception $exc) {
echo '<msg>Erro de montagem XML!!!<msg>'.$exc->getTraceAsString();
}
}
}
?>
------------------------------------------------------------------------------------------------------------------------------------------------------
que extende a classe Banco.php
-------------------------------------------------------------------------------------------------------------------------------------------------------
<?php
require_once("dC.php");
class Banco extends dC {
public $con;
public $msg;
public function __construct() {
}
public function conectar() {
$this->tipoBd();
if ($this->con) {
try {
$this->con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
$this->msg = "Erro de conexão com o banco de dados: Código: " . $e->getCode() . "Mensagem " . $e->getMessage() . "hora: " . date('H:i:s');
}
} else {
echo "Erro na definição PDO do banco de dados!";
exit;
}
}
public function tipoBd() {
try {
switch ($this->tipo) {
case 'mysql':
try {
$this->con = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->bd, $this->user, $this->pass);
} catch (Exception $exc) {
$this->msg = "Erro de coneção com o banco de dados MySql. " . $exc->getTraceAsString();
}
break;
case 'pgsql':
$this->con = new PDO("pgsql:dbname={" . $this->bd . "};user={" . $this->user . "}; password={" . $this->pass . "};host=" . $this->host);
break;
case 'oci8':
$tns = "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=" . $this->host . ")(PORT=1521)))(CONNECT_DATA=(SID=" . $this->bd . ")))";
$this->con = new PDO("oci:dbname=" . $tns, $this->user, $this->pass, array(PDO::ATTR_PERSISTENT => true));
break;
case 'mssql':
$this->con = new PDO("mssql:host={" . $this->host . "},1433;dbname={" . $this->bd . "}", $this->user, $this->pass);
break;
}
} catch (Exception $exc) {
echo $exc->getTraceAsString();
exit;
}
}
}
?>
------------------------------------------------------------------------------------------------------------------------------------------------------
que extende a classe dC.php
-------------------------------------------------------------------------------------------------------------------------------------------------------
<?php
class dC {
public $tipo = "mysql";
public $host = "localhost";
public $bd = "nomeDoBancoDeDados";
public $user = "usuario";
public $pass = "senha";
}
?>
------------------------------------------------------------------------------------------------------------------------------------------------------
A classe que monta as sstring sql é pesquisaSql.php
-------------------------------------------------------------------------------------------------------------------------------------------------------
<?php
session_start();
class pesquisaSql {
public $fim;
public $funcao;
public $limite;
public $ordem;
public $sessao;
public $todos;
public $id_turma;
public $desc_turma;
public function pesqTurma() {
$this->ordem = "GROUP BY t.id_turma ORDER BY t.desc_turma LIMIT 20";
if ($this->id_turma != '') {
$condicao .= " t.id_turma= " . $this->id_turma;
}
if ($this->desc_turma != '') {
if ($condicao)
$condicao .= " AND ";
$condicao .= " t.desc_turma= " . $this->desc_turma;
}
if ($condicao)
$condicao = " WHERE " . $condicao;
return "SELECT t.id_turma, t.desc_turma FROM turma t " . $condicao . " " . $this->ordem;
}
public function pesqDiasSemana() {
$this->ordem = "GROUP BY s.id_dia_semana ORDER BY s.desc_dia_semana LIMIT 20";
if ($this->id_dia_semana != '') {
$condicao .= " s.id_dia_semana= " . $this->id_dia_semana;
}
if ($this->desc_dia_semana != '') {
if ($condicao)
$condicao .= " AND ";
$condicao .= " t.desc_dia_semana= " . $this->desc_dia_semana;
}
if ($condicao)
$condicao = " WHERE " . $condicao;
return "SELECT s.id_dia_semana, s.desc_dia_semana FROM dia_semana s " . $condicao . " " . $this->ordem;
}
public function pesqDisponibilidadeTurno() {
$this->ordem = "GROUP BY d.id_disponibilidade ORDER BY d.desc_disponibilidade LIMIT 20";
if ($this->id_disponibilidade != '') {
$condicao .= " d.id_disponibilidade= " . $this->id_disponibilidade;
}
if ($this->desc_disponibilidade != '') {
if ($condicao)
$condicao .= " AND ";
$condicao .= " d.desc_disponibilidade= " . $this->desc_disponibilidade;
}
if ($condicao)
$condicao = " WHERE " . $condicao;
return "SELECT d.id_disponibilidade, d.desc_disponibilidade FROM disponibilidade_turno d " . $condicao . " " . $this->ordem;
}
// &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
public function pesqOutroTemaInteresse() {
$this->ordem = "GROUP BY ot.id_outro_tema ORDER BY ot.desc_outro_tema LIMIT 20";
if ($this->id_outro_tema != '') {
$condicao .= " d.id_outro_tema= " . $this->id_outro_tema;
}
if ($this->desc_outro_tema != '') {
if ($condicao)
$condicao .= " AND ";
$condicao .= " ot.desc_outro_tema= " . $this->desc_outro_tema;
}
if ($condicao)
$condicao = " WHERE " . $condicao;
return "SELECT ot.id_outro_tema, ot.desc_outro_tema FROM outro_tema_interesse ot " . $condicao . " " . $this->ordem;
}
// &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
public function pesqCargaHrDesejada() {
$this->ordem = "GROUP BY ch.id_carga_horaria ORDER BY ch.desc_carga_horaria LIMIT 20";
if ($this->id_carga_horaria != '') {
$condicao .= " ch.id_carga_horaria= " . $this->id_carga_horaria;
}
if ($this->desc_carga_horaria != '') {
if ($condicao)
$condicao .= " AND ";
$condicao .= " ch.desc_carga_horaria= " . $this->desc_carga_horaria;
}
if ($condicao)
$condicao = " WHERE " . $condicao;
return "SELECT ch.id_carga_horaria, ch.desc_carga_horaria FROM carga_horaria_desejada ch " . $condicao . " " . $this->ordem;
}
// &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
public function pesqCursoRealizado() {
$this->ordem = "GROUP BY cr.id_curso_realizado ORDER BY cr.desc_curso_realizado LIMIT 20";
if ($this->id_carga_horaria != '') {
$condicao .= " ch.id_carga_horaria= " . $this->id_carga_horaria;
}
if ($this->desc_curso_realizado != '') {
if ($condicao)
$condicao .= " AND ";
$condicao .= " cr.desc_curso_realizado= " . $this->desc_curso_realizado;
}
if ($condicao)
$condicao = " WHERE " . $condicao;
return "SELECT cr.id_curso_realizado, cr.desc_curso_realizado FROM curso_realizado cr " . $condicao . " " . $this->ordem;
}
}
?>