2011-08-05 17 views
44

código Google Analytics async utiliza un patrón de diseño muy distinto para la ejecución de código JavaScript.¿Cuál es el nombre del patrón de diseño asincrónico de Google Analytics y dónde se usa?

El código depende de una biblioteca y no sabe si la biblioteca se ha cargado o no. Si la biblioteca no se cargó, simplemente pone en cola todos los comandos en un objeto Array. Cuando la biblioteca se carga, solo crea el objeto _gaq y ejecuta todos los comandos en la secuencia en la que se incluyó. Luego sobrescribe la función push para que los comandos futuros se ejecuten de inmediato.

La idea es hacer que los comandos se ejecuten muy rápido cuando se ponen en cola. El código solo se evalúa realmente más tarde cuando se carga la biblioteca.

También cargan la biblioteca con los parámetros async=true. Esto no causa casi ningún impacto en el tiempo real de carga de la página.

Los comandos se parecen a las versiones de sincronización de la misma, pero la primera cadena es un nombre de función y los siguientes parámetros son los parámetros de la función. También puede insertar funciones en esta matriz y las funciones se ejecutarán también en secuencia con un contexto nulo. Entonces, si necesita hacer algo sincrónico con la biblioteca, puede presionar una función para hacer esto dentro de _gaq.

Creo que esta es una solución muy inteligente pero nunca la había visto antes. ¿Alguien sabe el nombre de este patrón de diseño o dónde se usa además del código de seguimiento de Google Analytics?

Respuesta

41

Me he referido a él como "cola de función asíncrona", pero no es un nombre bastante pegadizo, y ciertamente no es el nombre formal del patrón de diseño.

Lo interesante es que, aunque no había visto este patrón en particular antes, desde que Google lo adoptó para Google Analytics, ha sido adoptado ampliamente por diferentes plataformas que buscan atrapar el jugo asincrónico (me viene a la mente Disqus).)

Este blog post es el examen más a fondo de la sintaxis asincrónico de Google Analytics que he leído, e incluye una explicación bastante detallada de la forma en la que se puede replicar el patrón:

A partir de la entrada en el blog:

var GoogleAnalyticsQueue = function() { 

    this.push = function() { 
     for (var i = 0; i < arguments.length; i++) try { 
      if (typeof arguments[i] === "function") arguments[i](); 
      else { 
       // get tracker function from arguments[i][0] 
       // get tracker function arguments from arguments[i].slice(1) 
       // call it! trackers[arguments[i][0]].apply(trackers, arguments[i].slice(1)); 
      } 
     } catch (e) {} 
    } 

    // more code here… 
}; 

// get the existing _gaq array 
var _old_gaq = window._gaq; 

// create a new _gaq object 
window._gaq = new GoogleAnalyticsQueue(); 

// execute all of the queued up events - apply() turns the array entries into individual arguments 
window._gaq.push.apply(window._gaq, _old_gaq); 

Asimismo, señala que, a pesar de que muchos navegadores no soportan el atributo async, el método de inyección utilizada hace que la carga de la escritura de forma asíncrona en la mayoría de los navegadores, e incluye una tabla de datos útiles:

enter image description here

3

Todo lo que está haciendo es empujar a los datos en una matriz global

var _qaq = _qaq || []; 
_qaq.push(stuff); 

Básicamente, le permite a la memoria intermedia de seguridad de datos para hacer frente a la biblioteca antes se ha cargado.

La razón principal de que este patrón no se use mucho es que otras bibliotecas generalmente necesitan los recursos para cargar antes de que puedan hacer algo. No tendría sentido comenzar a almacenar en búfer los comandos jQuery.

No es un patrón, simplemente almacena datos en el ámbito global y dice que es el trabajo de otro para procesar esto, no me importa cuando lo procesa.

Sin embargo, es una manera inteligente de lidiar con el hecho de que no sabe cuando algo está cargado o listo, la alternativa común es un bloque DOMReady.

+1

Si desea utilizar 'async = true' en el archivo jquery.js para reducir el tiempo de carga de la página, no hay manera de saber si terminó de cargarse o no cuando se ejecuta el código. ¿No sería agradable poner en cola comandos de jQuery como este o tal vez poner todo el código en una sola función y ponerla en cola para que se ejecute una vez que jQuery termine de cargarse? – Eduardo

+0

@eduardocereto seguro que lo haría. Sugiérele a jQuery que proporcionen una matriz global '_domReady' desde la que puedan leer las funciones dom ready. – Raynos

+1

no es un '_domReady', sería más como' _jQueryReady', ya que el dom no es necesariamente Ready. Con el indicador 'async = true', el archivo puede cargarse antes de que el DOM esté listo o después de que el DOM esté listo. El archivo js puede cargarse incluso después de que windows.onload incendios. – Eduardo

3

Una buena valoración crítica de javascript stratgies de carga está disponible aquí http://friendlybit.com/js/lazy-loading-asyncronous-javascript/

Y por lo que yo recuerdo, ga.js. sintaxis asíncrona ha sido inspirado por Steve Souders. Puede mirar ControlJS, uno de sus proyectos

+2

Se trata de la invocación del script real y de cómo no retrasar el evento de carga. Estoy más interesado aquí en cómo la cola que la función llama en una matriz simple. Ese es el diseño real que quería encontrar similares. – Eduardo

+0

Steve dice directamente en sus publicaciones que los cargadores Google Analytics fueron el resultado de su trabajo con ellos. Eres acertado. –

1

En 2014 Ilya Grigorik escribió una publicación titulada Script-injected "async scripts" considered harmful. Esa publicación se vincula a esta pregunta y utiliza la frase "cola de función asíncrona" como el nombre del patrón de diseño utilizado por Google Analytics.

La función de cola asíncrona difiere de los patrones de diseño más recientes como Fetch Injection, que no requieren ni necesitan una cola definida globalmente. Aquí está un ejemplo de Fetch inyección implementado en el Fetch Inject module y se utiliza para descargar de forma asíncrona los recursos en un documento:

enter image description here

Aviso el Fetch patrón de diseño de inyección es capaz de CSS de carga, además de JavaScript en paralelo, lo que elimina el bloqueo comportamiento de CSSOM y la descarga de la Fuente Web, lo que reduce en gran medida la latencia percibida. El orden de ejecución de scripts se conserva completamente utilizando una API fácil de entender, lo que simplifica la administración de la carga de grupos complejos de recursos con un control programático total.

Cuestiones relacionadas