Google Analytics - Migration en mode javascript asynchrone

Introduction

Un précédent article paru en novembre 2009 présente comment mesurer son audience Web avec Google Analytics avec les objectifs suivants :

  • être le moins intrusif possible dans le code des pages.
  • mesurer efficacement les téléchargements de documents PDFs, MS Word etc...
  • tracer les clics des internautes sur les liens externes au sein d'un site.

Voici le lien de cet ancien article : Mesurer son audience Web et exploiter efficacement Google Analytics

Depuis la technologie Google Analytics a évolué et propose une nouvelle version stable depuis avril 2010, notamment pour IE 6 et IE 7, de l'outil de mesure d'audience Google analytics ga.js. Cette nouvelle version est désormais en mode asynchrone dans le code Javascript.

L'utilisation de la version asynchrone du code Google Analytics ga.js est très fortement recommandée et conseillée pour un bon nombre de nouveautés Google, parmi ces nouveautés :

  • Statistiques analytiques du bouton Google +1.
  • Statistiques sur la vitesse moyenne de chargement des pages.
  • Interactions avec les réseaux sociaux Twitter etc...
  • Nouveautés dans les indexes personnalisés Google (Custom Search Engine) : auto complétion, ergonomie.

Cet article présente la migration à travers un cas pratique vers la version asynchrone de Google Analytics. La migration est assez simple et allège grandement le code par ailleurs.

Les recommandations de Google lors de la migration vers la version asynchrone de Google Analytics

Pour la conversion vers la version asynchrone de Google Analytics, Google propose la méthodologie suivante :

  • Sauvegarder l'ancien code traditionnel Google Analytics et toutes les personnalisations apportées.
  • Supprimer l'ancien code traditionnel.
  • Insérer la version asynchrone dans l'entête du document HTML (entre les balises <head> et </head>) avec l'identifiant de son compte Google Analytics UA-xxxxxx-x. L'un des avantages principaux de la version asynchrone est de pouvoir faire fonctionner Google Analytics avant que l'internaute ne quitte la page grâce à son nouveau positionnement dans l'entête de la page. Dans le code traditionnel en version synchrone, il était au contraire recommandé de placer le code Google Analytics en bas de page afin de ne pas bloquer le chargement.
  • Migrer toutes les personnalisations existant dans l'ancien code vers la version asynchrone.

Dans cet article il existe une personnalisation : la détection de la vitesse de chargement des pages avec la méthode _trackPageLoadTime() de l'objet pageTracker.

Code synchrone Google Analytics à migrer

L'ancien code synchrone Google Analytics est encapsulé dans le script Javascript fc_googleanalytics.js appelé dans l'entête du document HTML :

<head>
 ...
<script type="text/javascript" src="./js/fc_googleanalytics.js"></script>
 ...
</head>

fc_googleanalytics.js
var gaCode="UA-xxxxxx-x";

var v_src_ga = document.createElement('script');
v_src_ga.setAttribute("type","text/javascript");
var v_gaJsHost = (("https:" == document.location.protocol) ?  "https://ssl." : "http://www.");
v_src_ga.setAttribute("src",v_gaJsHost + "google-analytics.com/ga.js");
var v_script_first = document.getElementsByTagName('script')[0];
v_script_first.parentNode.insertBefore(v_src_ga,v_script_first);

function GAInit() {
            GAAnalytics(false,false);
}

function GAAnalytics(url,caption) {
      if (url) { window.open(url); } 
      try {
           var pageTracker = _gat._getTracker(gaCode);
           if (typeof(pageTracker)!="undefined") {
             if (! caption && ! url) {
                // pageTracker._initData(); deprecated
                pageTracker._trackPageview();
                pageTracker._trackPageLoadTime();
             }
             else {
                if (caption) {pageTracker._trackPageview(caption);}
                else {pageTracker._trackPageview(url);}
             }
           }
      }
      catch(err) {}    
}

/**
 * Evènement Listener Body OnLoad / Load
 * Lancement de GAInit
 */

if (window.addEventListener) {
    window.addEventListener('load', GAInit, false);
}
else if (window.attachEvent) {
    window.attachEvent('onload', GAInit);
}

Dans le code synchrone :

L'identifiant du compte Google Analytics UA-xxxxxx-x est stocké dans la variable gaCode.

var gaCode="UA-xxxxxx-x";

Le script ga.js est incorporé dynamiquement avec la méthode Javascript createElement.

var v_src_ga = document.createElement('script');
v_src_ga.setAttribute("type","text/javascript");
var v_gaJsHost = (("https:" == document.location.protocol) ?  "https://ssl." : "http://www.");
v_src_ga.setAttribute("src",v_gaJsHost + "google-analytics.com/ga.js");
var v_script_first = document.getElementsByTagName('script')[0];
v_script_first.parentNode.insertBefore(v_src_ga,v_script_first);

Statistiques pour la page courante

Lorsque la page courante est finalement chargée, la fonction GAInit est automatiquement appelée grâce aux méthodes window.addEventListener (Firefox, Chrome..) ou window.attachEvent (Internet Explorer).

if (window.addEventListener) {
    window.addEventListener('load', GAInit, false);
}
else if (window.attachEvent) {
    window.attachEvent('onload', GAInit);
}

function GAInit() {
    GAAnalytics(false,false);
}

La fonction GAInit appelle la fonction GAAnalytics avec les paramètres url et caption définis à false.

Lorsque les paramètres url et caption sont définis à false dans la fonction GAAnalytics, les statistiques de la page courante sont déclenchées pour la page courante avec la méthode _trackPageView de l'objet _gat des APIs Google Analytics synchrones :

var pageTracker = _gat._getTracker(gaCode);
pageTracker._trackPageview();
pageTracker._trackPageLoadTime();

Statistiques pour les liens externes, les téléchargements etc...

Pour implémenter les statistiques Google Analytics lors de clics sur les liens externes, de téléchargements de documents PDFs etc..., la fonction GAAnalytics est appelée avec les paramètres url et/ou caption.

Exemple de détection d'un clic sur un document PDF déclenchant la fonction GAAnalytics :

<a href="../referentiel/docs/155_sy_ASE1502quickrefdiagnostictools.pdf"
    onclick="javascript:if (typeof(GAAnalytics) != 'undefined') 
               {GAAnalytics(this.href,'/referentiel/docs/155_sy_ASE1502quickrefdiagnostictools.pdf');} 
               else {window.open(this.href);}; return false;"
>ASE 15.0.2 - Guide pratique sur les outils de diagnostic et d'optimisation
</a>

Lorsque la fonction GAAnalytics est appelée avec les paramètres url et/ou caption renseignés, la méthode _trackPageView de l'objet _gat des APIs Google Analytics synchrones est déclenchée avec en paramètre l'adresse URL ou le libellé forcé (caption). Avec l'exemple ci-dessus, lors du clic sur le document PDF, le code suivant est exécuté :

var pageTracker = _gat._getTracker(gaCode);
pageTracker._trackPageview('/referentiel/docs/155_sy_ASE1502quickrefdiagnostictools.pdf');

Migration en asynchrone de l'appel du script ga.js des API Google Analytics

Ancien code synchrone de l'appel du script ga.js des API Google Analytics

Dans le script fc_googleanalytics.js, l'appel du script ga.js des API Google Analytics est réalisé dynamiquement en mode synchrone avec la méthode createElement Javascript.

fc_googleanalytics.js
var v_gaJsHost = (("https:" == document.location.protocol) ?  "https://ssl." : "http://www.");

var v_src_ga = document.createElement('script');
v_src_ga.setAttribute("type","text/javascript");
v_src_ga.setAttribute("src",v_gaJsHost + "google-analytics.com/ga.js");

var v_script_first = document.getElementsByTagName('script')[0];
v_script_first.parentNode.insertBefore(v_src_ga,v_script_first);

Dans l'arbre DOM du document HTML, le script ga.js est inséré avant le premier script Javascript avec la méthode insertBefore.

Nouveau code asynchrone de l'appel des API Google Analytics ga.js

Dans la version asynchrone, un nouvel objet Javascript s'appelant obligatoirement _gaq est d'abord créé en amont.

fc_googleanalytics.js
var _gaq = _gaq || [];

Cet objet _gaq contiendra des tableaux JSON (JavaScript Object Notation) avec la structure ['méthode','valeur',...], tableaux créés dans l'objet _gaq avec la méthode push.

L'identifiant du compte Google Analytics UA-xxxxx-x est d'ores et déjà donné dans l'objet _gaq avec la méthode _setAccount

fc_googleanalytics.js
var _gaq = _gaq || [];

var gaCode="UA-xxxxxx-x";
_gaq.push(['_setAccount',gaCode]);

L'appel du script ga.js des API Google Analytics est réalisé dynamiquement en mode asynchrone avec la méthode createElement Javascript. Par rapport à la version synchrone, la propriété async=true est ajouté à l'objet script créé dynamiquement :

fc_googleanalytics.js
var _gaq = _gaq || [];

var gaCode="UA-xxxxxx-x";
_gaq.push(['_setAccount',gaCode]);

var v_gaJsHost = (("https:" == document.location.protocol) ?  "https://ssl." : "http://www.");

var v_src_ga = document.createElement('script');
v_src_ga.setAttribute("type","text/javascript");
v_src_ga.setAttribute("src",v_gaJsHost + "google-analytics.com/ga.js");
v_src_ga.setAttribute("async","true");

var v_script_first = document.getElementsByTagName('script')[0];
v_script_first.parentNode.insertBefore(v_src_ga,v_script_first);

Migration en asynchrone des statistiques Google Analytics de la page courante

Dans l'ancien code synchrone, lorsque la page est chargée, la fonction GAInit est automatiquement appelée, fonction qui dans la cinématique déclenche par la suite la méthode _pageTrackView sans paramètre de l'objet _gat des APIs Google synchrones.

Avec les API asynchrones de Google Analytics, il n'est plus nécessaire d'attendre la fin du chargement de la page, la méthode _trackPageview est directement ajoutée dans l'objet _gaq et ceci peut être fait en amont du script.

fc_googleanalytics.js
var _gaq = _gaq || [];

var gaCode="UA-xxxxxx-x";
_gaq.push(['_setAccount',gaCode]);

_gaq.push(['_trackPageView']);
 ...

L'appel automatique de la fonction GAInit après le chargement de la page et la fonction GAInit deviennent obsolètes dans la méthode asynchrone.

Migration en asynchrone des statistiques Google Analytics pour les clics sur les liens externes, les téléchargements de documents PDFs...

Pour la gestion des clics sur les liens externes, les téléchargements de documents PDFs, etc... la fonction GAAnalytics est simplifiée et conservée. Au lieu d'appeler la méthode _trackPageView de l'objet _gat des APIs Google synchrones en donnant en paramètre une adresse URL ou un libellé, un objet ['_trackPageView','URL ou libellé'] est tout simplement inséré dans l'objet _gaq.

function GAAnalytics(url,caption) {
      if (url) { window.open(url); } 
          try {
              if (caption) { _gaq.push(['_trackPageview',caption]); }
              else if (url) { _gaq.push(['_trackPageview',url]); }
          }
          catch(err) {}    
}

Migration en asynchrone des personnalisations

La détection du temps de chargement de la page avec la méthode _trackPageLoadTime de l'objet _gat est une personnalisation implémentée dans le code synchrone original :

var pageTracker = _gat._getTracker(gaCode);
pageTracker._trackPageview();
pageTracker._trackPageLoadTime();

Comme pour la détection de la page, cette personnalisation peut être implémentée en amont en insérant un objet ['_trackPageLoadTime'] dans l'objet _gaq :

fc_googleanalytics.js
var _gaq = _gaq || [];

var gaCode="UA-xxxxxx-x";
_gaq.push(['_setAccount',gaCode]);
_gaq.push(['_trackPageview']);

_gaq.push(['_trackPageLoadTime']);
 ...

La quasi majorité des personnalisations est migrée vers le mode asynchrone des APIs Google Analytics en insérant un tableau ['méthode','paramètre 1','paramètre 2',...] dans l'objet _gaq au lieu d'appeler _gat.methode('paramètre 1','paramètre 2',....).

Conclusion

Outre les recommandations d'utiliser la version asynchrone des APIs Google Analytics pour la compatibilité avec les autres nouveautés Google (bouton Google +1, réseaux sociaux...), la version asynchrone permet d'éliminer la détection de la fin du chargement de la page.

La migration est également particulièrement simple, dans leur grande majorité, les méthodes sont migrées vers la version asynchrone selon le schéma ci-dessous :

Code synchrone Code asynchrone
var pageTracker = _gat._getTracker('UA-XXXXXX-X');
pageTracker.methode('parametre 1','parametre 2',...)
_gaq.push(['methode','parametre 1','parametre 2',...]);

Nouveau code final Google Analytics - Mode asynchrone

fc_googleanalytics.js
var _gaq = _gaq || [];

var gaCode="UA-xxxxxx-x";
_gaq.push(['_setAccount',gaCode]);

_gaq.push(['_trackPageview']);
_gaq.push(['_trackPageLoadTime']);

var v_src_ga = document.createElement('script');
v_src_ga.setAttribute("type","text/javascript");
v_src_ga.setAttribute("async","true");
var v_gaJsHost = (("https:" == document.location.protocol) ?  "https://ssl." : "http://www.");

v_src_ga.setAttribute("src",v_gaJsHost + "google-analytics.com/ga.js");

var v_script_first = document.getElementsByTagName('script')[0];
v_script_first.parentNode.insertBefore(v_src_ga,v_script_first);


function GAAnalytics(url,caption) {
      if (url) { window.open(url); } 
      try {
              if (caption) { _gaq.push(['_trackPageview',caption]); }
              else if (url) { _gaq.push(['_trackPageview',url]); }
          }
      catch(err) {}    
}