Piensa en asíncrono

Sin duda una de las mejoras del HTML5 es la posibilidad de cargar determinados elementos de forma asíncrona en la página. Y es que si tus usuarios utilizan navegadores de versiones superiores a Firefox 3.6, IE 10, Chrome 2, Safari 5, iOS 5 o Android 3 dispones de la posibilidad de hacerlo fácil:

<script async src="http://example.com/javascript.js"></script>

La carga de los scripts se puede hacer de muchas formas… la más sencilla, por ejemplo si es de un recurso propio, se puede hacer de esta forma:

<script>
  var resource = document.createElement('script');
  resource.src = "http://example.com/javascript.js";
  var script = document.getElementsByTagName('script')[0];
  script.parentNode.insertBefore(resource, script);
</script>

O también de esta forma… ambas son similares:

<script>
  (function(d, t) {
    var g = d.createElement(t),
    s = d.getElementsByTagName(t)[0];
    g.src = 'http://example.com/javascript.js';
    s.parentNode.insertBefore(g, s);
  }(document, 'script'));
</script>

Esta es una forma que permite la carga aunque no es del todo efectiva ya que no siempre se carga asíncronamente. Para ello, sobretodo si es de scripts externos se puede usar algo más así:

<script>
  (function(){
    var a = document.createElement('script');
    a.type = 'text/javascript';
    a.async = true;
    a.src = 'http://example.com/javascript.js';
    (document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(a);
  })();
</script>

Ahora que ya sabemos cargar los scripts de forma sencilla y asíncrona… ¿por qué no cargar algunos scripts “famosos” de forma sencilla y sin que afecte negativamente a tu sitio web?

El código de Facebook:

<div id="fb-root"></div>
<script>
  (function(d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s);
    js.id = id;
    js.src = "http://connect.facebook.net/es_ES/all.js#xfbml=1";
    fjs.parentNode.insertBefore(js, fjs);
  }(document, 'script', 'facebook-jssdk'));
</script>

El código de Twitter:

<a href="https://twitter.com/share" class="twitter-share-button">Twitear</a>
<script>
  !function(d,s,id) { 
    var js,fjs = d.getElementsByTagName(s)[0];
    if(!d.getElementById(id)) { 
      js = d.createElement(s);
      js.id = id;
      js.src = "http://platform.twitter.com/widgets.js";
      fjs.parentNode.insertBefore(js,fjs);
    }
  } (document,"script","twitter-wjs");
</script>

El código de Google+:

<g:plusone annotation="inline"></g:plusone>
<script type="text/javascript">
  (function() {
    var po = document.createElement('script');
    po.type = 'text/javascript';
    po.async = true;
    po.src = 'http://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(po, s);
  })();
</script>

Pero… ¿no sería más sencillo mantener un único código para todo? La solución es bastante sencilla, ya que al fin y al cabo en todos los casos se carga de la misma forma…

<script>
  (function(doc, script) {
    var js, fjs = doc.getElementsByTagName(script)[0], add = function(url, id) {
      if (doc.getElementById(id)) {
        return;
      }
      js = doc.createElement(script);
      js.src = url;
      id && (js.id = id);
      fjs.parentNode.insertBefore(js, fjs);
    };
    add('http://www.google-analytics.com/ga.js', 'ga');
    add('http://apis.google.com/js/plusone.js');
    add('http://connect.facebook.net/es_ES/all.js', 'facebook-jssdk');
    add('http://platform.twitter.com/widgets.js', 'twitter-wjs');
  } (document, 'script'));
</script>

¡Ahora a reprogramar!

Categorías Javier, WPO

7 comentarios en “Piensa en asíncrono”

  1. Genial artículo. La idea de meter los scripts de las redes sociales en uno me parece bastante buena, porque suelen dar mucho porsaco… Una duda, estoy usando Google Tag Manager para cargar estos scripts, ¿crees que habría mucha diferencia entre eso y la manera de cargar que expones aquí?

    Si no entiendo mal, Tag Manager carga asíncronamente también.

    Saludetes!

  2. Sí, Google Tag Manager está pensado para hacer algo similar… la diferencia es que en Tag Manager se carga todo el bloque de cada uno de ellos, lo que implica que la cantidad de código a cargar sigue siendo excesiva… Personalmente, excepto para publicidad, prefiero cargar las cosas “yo mismo”.

  3. Javier, pues gracias por la aclaración. Voy a implementarlo de esa forma, aunque mis conocimientos de Javascript tienden a cero, con lo que no me suelo complicar mucho, salvo en casos claro como este.

    Saludos

  4. Hola de nuevo,

    Javier, he probado la última parte del código, la que agrupa los tres botones sociales, y no me cargan los de Facebook. Si pongo el código normal sí que va. ¿Alguna idea?

    Y por cierto, tienes razón, lo de Tag Manager al final ha acabado por sacarme de quicio y estoy haciéndolo “yo mismo”.

    Gracias!

  5. Hola Javier..!! Funciona a la perfección, reduce flops y tiempo a la perfección.
    Gracias y salud..!!!
    Pd: al loro al utilizar async en el script general de la página que puede causar que no funcionen algunos elementos como banners en flash.. :)

Deja un comentario