rel="canonical" ou redirect 301?

Pra quem não entendeu o motivo da questão no título deste texto, uma breve explicação: as duas opções são formas válidas para se definir qual é a versão "original" em casos de conteúdo duplicado.

Mas se são duas formas diferentes de se chegar ao mesmo resultado, qual delas escolher? Há vantagens e desvantagens? Há casos em que só uma delas se aplica? São essas perguntas que eu tentarei responder aqui neste texto. :D

Entendendo o problema do conteúdo duplicado

Para entender onde e como aplicar corretamente as soluções acima, é importante entender qual é o real problema com conteúdo duplicado. Para entender isso, vamos precisar de um exemplo: a página inicial desse blog encontra-se em http://blog.klaus.pro.br/ - mas nada impede que alguém faça um link para ela assim: http://blog.klaus.pro.br/?home. Note que ambos os endereços funcionam perfeitamente.

No caso acima, os dois endereços exibem a (mesma) página inicial deste blog. Agora pense como um robô indexador, será que os dois endereços mostram o mesmo conteúdo porque alguém quer me enganar, dando a impressão de que há mais conteúdo do que realmente há no site, ou simplesmente os dois endereços são considerados a mesma página pelo sistema do site em questão. E se os dois endereços realmente apontam para uma mesma página, qual deles eu devo considerar como "principal" ou "original"?

Para resolver essa ambiguidade e, de quebra, definir qual é a página "original", as duas soluções acima podem ser empregadas.

Onde as duas soluções se aplicam

Quando você está resolvendo a questão de conteúdo duplicado apenas dentro do domínio de seu site, as duas soluções são aplicáveis. Ou seja, usar a meta tag canonical ou um redirecionamento 301 resolve perfeitamente a questão, levando-se em conta a restrição de domínio acima.

Desta forma, para resolver o problema citado no começo deste texto usando a meta tag canonical bastaria eu colocar isso na página incial do meu blog:

<link rel="canonical" href="http://blog.klaus.pro.br/" />

Onde apenas a meta tag canonical se aplica

Nota: Este exemplo foi retirado deste vídeo.

Se no seu site você possui uma versão "normal" da página e uma versão para impressão, muito provavelmente as páginas serão muito parecidas, a ponto de parecerem conteúdo duplicado para um indexador de conteúdo.

Se você colocar um redirecionamento 301 na página de impressão, nenhum usuário vai conseguir ver a página, o que definitivamente não é uma solução para o problema :) . Já com a meta canonical você pode informar sem problemas que a página "normal" é a versão "original" daquele conteúdo.

Onde apenas um redirecionamento 301 (ou 302) se aplica

A meta canonical não é válida (ou seja, ela é ignorada) quando a página referenciada encontra-se em outro domínio. Nesses casos, para indicar que o conteúdo original encontra-se em outro lugar, sua única opção é fazer um redirecionamento permanente ou temporário (301 ou 302, respectivamente) para o conteúdo "original".

Conclusão

Se você precisa resolver o problema de conteúdo duplicado em páginas de domínios diferentes, suas opções são os redirecionamentos 301 ou 302. Se ambas as páginas precisam ser acessíveis pois seu conteúdo é muito parecido mas não é igual, use a meta tag canonical.

É isso! :)

comentários (1)

O progresso dos novos navegadores

Este texto é baseado (uma nota mental pública e estruturada, digamos) na apresentação "Performance Improvements in Browsers" feita por "John Resig", que é ninguém menos que o pai da famosa biblioteca jQuery.

Abaixo está o vídeo com a apresentação feita (aproximadamente 1h) e na sequência algumas notas e comentários sobre os temas apresentados.

Abas separadas por processos

Este é um fato que certamente você deve conhecer. Você está lá navegando tranquilamente com uma dezena (ou mais =) de abas abertas... Daí que você resolve acessar um site com um Javascript mal escrito, com uma animação em que o Flash Player se revolta e lá foi, o navegador inteiro congela e não resta outra opção senão matar o processo. Claro que a maioria dos navegadores traz opções para restaurar a seção anterior mas não deixa de ser bastante incômodo.

A separação das abas por processos permitiria matar (encerrar) apenas a aba problemática, mantendo as outras abas isoladas. Isso por si só já seria uma grande vantagem da separação por abas mas ainda há uma segunda vantagem também bastante interessante! =)

Com a separação em diversos processos o sistema operacional pode gerenciar melhor o processamento, alocando mais recursos para as partes onde é realmente necessário, sem congelar as outras partes do navegador.

Vale notar que essa divisão em processos distintos causa um aumento do consumo do memória sim mas, como a quantidade de memória disponível nos PCs atuais (mesmo para os "PCs de prateleira") está deixando de ser um gargalo para o desempenho dos computadores, é de se esperar que os programas passem a fazer alocações maiores de memória. Mais ou menos como o princípio da lei da oferta e da demanda.

Linearização das instruções de funções

O termo em inglês acho que permite um entendimento melhor: "'function inlining". Essa é uma característica que, por exemplo, C++ possui. Usando essa propriedade o compilador pode trocar a chamada de uma função pelo corpo da função, fazendo com que a execução das instruções ocorra sem o overhead de chamar uma função.

Além disso, pelo código exibido nos slides parece que, diferentemente do C++, você não precisa dar uma dica para o compilador na hora de escrever a função indicando que a função é candidata ao "inlining".

Rede

Aqui vale destacar o aumento do número de downloads simultâneos para um mesmo domínio. Com o IE 7 ainda temos o limite de dois downloads mas, felizmente o IE 8 (beta) já tratá um limite três vezes maior, de seis downloads simultâneos para o mesmo domínio. A última versão dos demais navegadores já possui um valor de seis ou sete downloads.

Outro recurso bem legal, e este é uma boa ideia da Microsoft, é o atributo "defer" para a tag <script>. Esse atributo indica para o navegador que ele pode continuar a renderizar a página sem esperar o arquivo Javascript referenciado carregar. O atributo já funcionava no IE e vai funcionar nas novas versões do Firefox e Opera.

window.postMessage

O método window.postMessage me chamou a atenção. Com ele será possível a comunicação entre páginas de domínios distintos de forma bem simples. O princípio é o seguinte: a página remetente da mensagem irá tentar enviar a mensagem para, por exemplo, um iframe destinatário. Este iframe irá verificar se o remetente é alguém que ele conhece para então aceitar a mensagem e executar alguma ação.

A página que receberá as mensagens pode "ouvir" os eventos de mensagens usando o tradicional método addEventListener. Verificando a propriedade origin, a página receptora pode descobrir pelo domínio se a mensagem está vindo de um destinatário conhecido ou não.

Ajax entre domínios diferentes

Aquele sonho de fazer requisições Ajax entre os N domínios da sua aplicação está prestes a se realizar. :D

Adicionando um cabeçalho (header) na resposta da requisição Ajax é possível especificar uma origem (além do próprio domínio) de onde aquela requisição pode ser atendida com segurança. O nome deste cabeçalho é "Access-Control-Allow-Origin" e está melhor descrito nesta página.

document.querySelectorAll

Se você já usou a jQuery sabe como é prático encontrar os elementos da página usando a sintaxe de CSS. Melhor ainda se encontrar esses elementos usando a sintaxe de CSS seja possível de ser feito usando um método nativo do navegador. É isso que o método document.querySelectorAll permitirá. O melhor de tudo é que as próximas versões do IE, Firefox, Opera e Safari já trarão este método disponível.

Visual e CSS

Adoradas por 10 em cada 10 webdesigners, as bordas redondas vieram pra ficar. =) Apesar de os navegadores trazerem implementações com nomes diferentes, todas as implementações funcionam bem. Ou seja, juntando essas propriedades: -moz-border-radius, -webkit-border-radius, -khtml-border-radius e border-radius as bordas redondas saem com facilidade.

Sombras também estarão disponíveis. Nesta página há vários exemplos de uso da propriedade text-shadow.

Outro recurso que certamente vai ser muito usado (e provavelmente muito mal usado também ;) ) é a possibilidade de se usar fontes personalizadas na página. Por fontes personalizadas entenda fontes que não estão instaladas na sua máquina. Coisa que já era possível de se fazer no Flash, agora também com CSS.

Além disso, há uma série de animações que estarão disponíveis, por enquanto, para Firefox e Safari.

Desenho

O objeto Canvas permite a renderização de elementos numa superfície 2D usando retas, curvas, arcos e/ou círculos. No MDC tem um tutorial bem bacana sobre Canvas. Até me arrisquei a fazer uma "arte": =)

// <canvas id="draw-area" width="150" height="150"></canvas> no HTML
var canvas = document.getElementById( "draw-area" );
if( !canvas.getContext )
{
  return;
}
var context = canvas.getContext( "2d" );

context.beginPath();
var side = 150;
var offset = -4;
var i = 0;
while( true )
{
  if( i % 4 == 0 )
  {
    var x = offset + 4;
    context.lineTo( x, offset );
    offset = x;
    if( offset + 4 > 78 ) // hard-coded mesmo ;P
    {
      break;
    }
  }
  else if( i % 4 == 1 )
  {
    context.lineTo( offset, side - offset );
  }
  else if( i % 4 == 2 )
  {
    context.lineTo( side - offset, side - offset );
  }
  else if( i % 4 == 3 )
  {
    context.lineTo( side - offset, offset );
  }
  i++;
}
//context.closePath();
context.stroke();

Outro detalhe importante é que o Canvas permitirá também a inserção de vídeos dentro dele.

JSON nativo

Atualmente, ao receber uma string em JSON você precisa usar um eval para recuperar o objeto original. O eval é conhecidamente lento, até pelo fato de ser um método genérico, mas era a melhor saída para se ter acesso às informações contidas na string JSON mas, isso vai mudar!

Agora teremos métodos nativos para codificação e decodificação no formato JSON. A única dúvida que me restou é sobre o nome dos métodos. Nos slides os métodos se chamam encode e decode, já na página do MDC e no wiki do ECMAScript os métodos se chamam parse e stringify, respectivamente.

E por fim...

... fico na torcida pra que as novas versões desses navegadores tenham uma rápida adoção por parte dos usuários. :D

comentários (6)

Feedback positivo sim senhor

Hoje eu lia o livro "The Ruby Way" quando me deparei com a seguinte frase: "Perfection is achieved, not when there is nothing left to add, but when there is nothing left to take away", frase atribuída a Antoine de St. Exupery.

Refletindo um pouco sobre ela lembrei-me de um artigo que eu havia lido há alguns meses atrás, um artigo que falava sobre a importância do feedback positivo, numa associação entre jogos e programas de computador (ou sites).

Percebi que o artigo e a frase estavam, de alguma forma, conectados. Em termos de aplicações web, todos queremos uma aplicação Google-like: simples, clara e eficaz. E se você reparar bem, vai ver que as aplicações do Google (ou aquelas Google-like) possuem características que se encontram na frase ou no artigo acima.

Focando na importância do feedback positivo, veja esta parte: "Hearing the discovery fanfare makes you feel smart(...)". É essa sensação que um usuário espera sentir ao usar um site, uma aplicação web. Ele deseja se sentir no comando, ter poderes, sentir que a aplicação entende o que ele está fazendo.

A falta de feedback conduz ao desapontamento. Um clique para enviar um formulário e vai processar uma imagem? Informe que a imagem está sendo processada! Um clique para gerar o PDF do artigo (que ainda não está em cache)? Informe que o artigo está sendo preparado! Conseguiu preencher o cadastro completo? Uma enorme mensagem de sucesso!

Ao invés de simplesmente qualificar seu usuário como (l)user :) , avalie se não é a falta de feedback positivo que faz o usuário esquecer de seu site. :D

comentários (2)

Tooltips no Google Maps

Dizem por aí que a necessidade é a mãe da invenção e da criação e... eu, de fato, concordo com isso. :D

Há duas semanas atrás eu fazia uma aplicação que exibia vários marcadores sobre um mapa e percebi que seria útil exibir uma espécie de tooltip sobre esses marcadores. A opção de usar o atributo title estava disponível sim, mas eu queria mais, queria poder personalizar essas tooltips!

Aproveitando-me do fato que a API de Mapas do Google já possui uma série de métodos para tratar eventos do mouse, resolvi criar algo que permitisse exibir tooltips personalizadas sobre os marcadores no mapa. O resultado? MapTips.

O resultado ficou bem legal e simples. Até criei uma página que explica o funcionamento e tem exemplos de utilização.

Como talvez você já tenha notado, disponibilizei o código fonte no Google Code. Agora preciso criar mais algumas páginas de wiki e bug tracking. :)

comentários

« Textos anteriores