Como carregar "widgets" de sites externos sem carroçar sua página...

Não sei vocês, mas no meu caso, a maioria do tráfego do meu site vem "redes sociais" de blogs, como o tecnocrati, linkk, rec6, linkTo, stumbleUpon, etc... E manter os widgets desses caras sempre é útil! Quem vai votar no meu site depois de ter fechado a página original com o link? Acho que ninguém se daria esse trabalho.

Só tem um porém: Esses widgets são pedaços de javascript externo, que carregam arquivos e imagens do site de origem, e nem sempre carregam numa velocidade razoável. Resultado? Meu blog demorava milênios pra carregar.

Mas seus problemas se acabaram-se (ou quase).

Com o javascript delayator tabajara você agora já pode forçar os widgets a carregar apenas DEPOIS QUE TUDO já foi carregado :). E não se assuste, mas é uma gambiarra faminta! 🙂

Uso de iFrame

O primeiro passo pra isso é usar iFrame. Com um iFrame eu posso carregar um conteúdo qualquer num espaço separo que não vai impactar a carga do resto do meu site. Basicamente eu uso um iFrame inicialmente só pra reservar o espaço, e uso javascript para carregar o conteúdo. Um iframe fica mais ou menos assim:

<iframe src=""></iframe>

Que é um iFrame vazio. Depois a gente usa um javascriptzinho pra "encher" o cara. E é aí que vem a manha: O campo de "src" do iFrame pode ser preenchido com código javascript! Você pode gerar uma página inteira usando javascript e carregar ela no iframe, olha só:

<iframe id="myFrame" src="javascript:'XXXX'"></iframe>

E depois usar um script como o seguinte para preencher o iFrame:

<script language="JavaScript">
function getConteudo() {
    return "<h1>TESTE</h1>";
}

var frame = document.getElementById('myFrame');
frame.src = "javascript:'" + getConteudo() + "'";

</script>

Onde "getConteudo()" pode ser reescrita para retornar o que você bem entender. Claro que por enquanto não evitamos que a iFrame tenha o conteúdo carregado no momento em que o script for lido, e com isso só "adiamos" por algumas linhas a carga do nosso widget. O pulo do gato e forçar o javascript a só rodar DEPOIS do final da carga da página. Como? Simples, usando a propriedade de "onload" do HTML:

<head>
<script language="JavaScript">
function getConteudo() {
    return "<h1>TESTE</h1>";
}
function carregaiFrame() {
    var frame = document.getElementById('myFrame');
    frame.src = "javascript:'" + getConteudo() + "'";
}
</script>
<body onload="carregaiFrame()">

<iframe id="myFrame" src="javascript:'XXXX'"></iframe>

</body>

Agora sim! Nosso iFrame carrega o conteúdo que a gente quer, só depois que a página carregar. Mas ainda falta um problema...

"Mas, tio, desse jeito eu só tenho direito a um único iFrame?"

E é aí que vem o pulo do gato! Javascript é seu amigo, ele vai te ajudar. Se eu usar o javascript pra "guardar" o nome e o conteúdo de todos os frames numa lista, depois da página carregada eu só preciso percorrer a lista de iFrames e preencher cada um com o valor correto. Pra isso, precisamos de um scriptzinho logo abaixo de cada iFrame, só pra "contar" o que vai ser o conteúdo dele:

<iframe id="frame1" src="javascript:'XXXX'"></iframe>
<script>
frame_contents['frame1'] = '<script>document.write("teste1");</script>';
</script>

Vejam que pra ilustrar melhor eu usei um script javascript no exemplo. E vejam um detalhe importante: dentro da variável eu usei </script> ao invés de apenas </script>. Se não fizer isso, o browser fica doidão porque acha que você fechou o seu script antes da hora. Aí não...

Enfim, esse código sozinho não faz nada. A gente precisa agora "chamar" esse cara no nosso onLoad... Pra isso, vamos modificar o método carregaiFrame() pra dizer:

// nosso vetor precisa ser declarado, já que ele vai ser usado mais tarde:
var frame_contents = {};
function carregaiFrame() {
    for (name in frame_contents) {
        frame = document.getElementById(name);
        var src_value = "javascript:'" + frame_contents[name] + "'";
        frame.src = src_value;
    }
}

Tcharam! Temos um lindo código que carrega minhas iFrames somente APÓS a carga de toda a página, assim os elementos "lentos" podem ser todos carregados em iFrames desse tipo.

Problemas pendentes

Claro que nem tudo são flores... Sempre sobram um ou outro probleminha pendentes. No meu caso, o problema ficou por conta do rec6. Enquanto os outros widgets usam um link que abre em uma nova janela, o widget do rec6 tem um link normal, que abre na mesma janela. Assim, a página de login ou de votação abre pro sujeito dentro de um iFrame com tamanho pra caber apenas o widget. Impossível de usar, não é? Mas eu estou batalhando numa solução. Quem sabe um jeito de copiar o conteúdo do iFrame pra dentro de um div. Ainda tenho de testar o que vai dar certo.

Nesse meio tempo, deixo vocês brincarem com as dicas que acabei de dar. E lembrem-se: no Internet Explorer, pra tirar as bordas de um iFrame, não adianta usar CSS... (Mas essa dica quem for esperto pega direto do código fonte dessa página).