design patterns - tag - ¿Cuál es el nombre del patrón de diseño asincrónico de Google Analytics y dónde se usa?
google tag manager tutorial (4)
En 2014, Ilya Grigorik escribió una publicación titulada " Guiones asíncronos", inyectados con scripts, considerados nocivos . 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 la Inyección de obtención , que no requieren ni necesitan una cola definida globalmente. Aquí hay un ejemplo de Fetch Injection implementado en el módulo Fetch Inject y utilizado para descargar recursos de forma asíncrona en un documento:
Observe que el patrón de diseño Fetch Injection es capaz de cargar CSS además de JavaScript en paralelo, eliminando el comportamiento de bloqueo 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.
El código asincrónico de Google Analytics utiliza un patrón de diseño muy distinto para la ejecución de código JavaScript.
El código depende de una biblioteca y no sabe si la biblioteca se cargó 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 están 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?
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 (Disqus viene a la mente).
Esta publicación de blog es el examen más profundo de la sintaxis asincrónica de Google Analytics que he leído, e incluye una explicación bastante detallada de cómo se puede replicar el patrón:
De la publicación del 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);
También señala que, aunque no hay muchos navegadores compatibles con el atributo async
, el método de inyección utilizado hace que el script se cargue de forma asíncrona en la mayoría de los navegadores e incluye un gráfico útil:
Todo lo que hace es presionar los datos en una matriz global
var _qaq = _qaq || [];
_qaq.push(stuff);
Básicamente, le permite almacenar datos antes de que se cargue la biblioteca.
La razón principal por la que este patrón no se usa mucho es que otras bibliotecas generalmente necesitan que se carguen los recursos 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 un ámbito global y dice que es el trabajo de alguien más 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.
Una buena descripción de las estrategias de carga de JavaScript está disponible aquí http://friendlybit.com/js/lazy-loading-asyncronous-javascript/
Y, por lo que recuerdo, la sintaxis de ga.js async ha sido inspirada por Steve Souders . Puedes ver ControlJS , uno de sus proyectos