Html5-boilerplate: Utiliser localStorage pour le suivi Google Analytics lorsqu'il est disponible

Créé le 7 oct. 2013  ·  30Commentaires  ·  Source: h5bp/html5-boilerplate

TL ; RD :

(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
e=o.createElement(i);r=o.getElementsByTagName(i)[0];
e.src='//www.google-analytics.com/analytics.js';
r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
ga('create','UA-XXXXX-X',{'storage': 'none','clientId':localStorage.getItem('gaClientId')});
ga(function(t){localStorage.setItem('gaClientId',t.get('clientId'));});
ga('send','pageview');

La source:
http://stackoverflow.com/questions/4502128/convert-google-analytics-cookies-to-local-session-storage/19207035?noredirect=1#19207035

Documents Google Analytics :
https://developers.google.com/analytics/devguides/collection/analyticsjs/domains#disableCookies

Nous pourrions utiliser Modernizer.localstorage pour vérifier la prise en charge de localStorage et revenir aux cookies s'ils ne sont pas disponibles. Bien que je ne sois pas sûr si nous voulons verrouiller Modernizr en tant que dépendance.

Pourquoi?
Parce que Google n'a pas besoin d'envoyer son cookie à votre serveur pour chaque requête vers votre domaine (ou le leur, d'ailleurs).

new feature

Commentaire le plus utile

Mettre à jour:

Il n'est pas contre TOS d'utiliser localStorage pour stocker le ClientID ; il est désormais officiellement pris en charge par Google : https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id#using_localstorage_to_store_the_client_id

Remarque : si vous devez prendre en charge des navigateurs (extrêmement) anciens (comme iOS5 et FF4), leur extrait d'exemple peut échouer (voir : https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage. js).

Tous les 30 commentaires

Bien que je ne sois pas sûr si nous voulons verrouiller Modernizr en tant que dépendance.

Peut-être serait-il préférable de simplement l'ajouter à la doc?

Envoyez également un ping à @mathiasbynens.

Merci d'avoir optimisé la capture, David. En tant que @alrra , je pense que nous sommes bons pour l'ajouter à la documentation.

Le crédit ne m'appartient pas; cela a été porté à mon attention par @elmerbulthuis. Bien que je ne considère pas vraiment cela comme une optimisation du _snippet_ lui-même, en soi --- il s'agit plutôt d'une optimisation du Web dans son ensemble :-p.

Je me demande combien d'octets pourraient être économisés, globalement, si tout le monde adoptait la solution localStorage .

Je suis évidemment un grand fan de cette solution. Le seul problème avec son inclusion par défaut dans le passe-partout est celui mentionné par @davidmurdoch : nous devons d'abord tester les fonctionnalités pour localStorage . Cela peut être fait en utilisant Modernizr ou en ajoutant un petit morceau de code autonome, mais dans tous les cas, cela augmentera légèrement la taille de la page. Là encore, cela économisera de nombreux octets à long terme, car aucun cookie ne sera envoyé dans les en-têtes de requête pour les ressources du domaine concerné.

Quelque chose comme ça:

(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
e=o.createElement(i);r=o.getElementsByTagName(i)[0];
e.src='//www.google-analytics.com/analytics.js';
r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
(function(){var a=(function(){var c=new Date,b;try{
localStorage.setItem(c,c);b=localStorage.getItem(c)==c;
localStorage.removeItem(c);return b&&localStorage}catch(d){}}());
ga('create','UA-XXXXX-X',a?{storage:'none',clientId:a.gaId}:{});
ga(function(b){a.gaId=b.get('clientId')});ga('send','pageview')}());

(Il utilise le test de fonctionnalité localStorage extrait de http://mathiasbynens.be/notes/localstorage-pattern.)

Il semble bien fonctionner après quelques tests rapides. Je créerai un PR après avoir testé cela plus en détail. (Aide bienvenue, bien sûr !)

Pour info : cela a le potentiel d'économiser environ 33 octets bruts (les en-têtes/cookies ne sont pas compressés) par aller-retour pour chaque requête vers les domaines concernés.

La solution actuelle de détection de fonctionnalités en ligne de @ mathiasbynens est supérieure de 130 octets compressés (ce sera évidemment différent pour chaque page unique, mais cela nous donne une idée approximative). Donc, nous devrions probablement voir si nous pouvons réduire cela un peu plus.

Personnellement, j'aimerais voir le diff gzippé jusqu'à 65 octets et je vais essayer moi-même bientôt. :-)

_∗en utilisant ce déflateur : http://www.vervestudios.co/projects/compression-tests/snippet-deflator_

318 octets GZIPpés (notre version actuelle est de 248 octets GZIPpés) :

(function(l,e){GoogleAnalyticsObject='ga',(window.ga||(ga=function(l,e){(ga.q=ga.q||[]).push(arguments)})).l=+new Date,l=document.createElement('script'),l.src='//www.google-analytics.com/analytics.js',(e=document.getElementsByTagName('script')[0]).parentNode.insertBefore(l,e);ga('create','UA-XXXXX-X',(function(l,e){try{l=(localStorage[ga.l]=ga.l)==ga.l;localStorage.removeItem(ga.l);return l}catch(l){}}())?{storage:'none',clientId:localStorage.clientId}:{});ga(function(l,e){localStorage.clientId=l.get('clientId')});ga('send','pageview')}())

Ce n'est pas très bien testé, donc je vais quand même devoir le faire. Mais c'est un début.

Et malheureusement, le test localStorage est probablement compromis quelque part dans un navigateur, car je me suis débarrassé des appels setItem et getItem et j'ai utilisé d'autres "astuces" de golf.

C'est tout ce que j'ai pour l'instant. :-)

Il m'est venu à l'esprit que nous avions gzipé l'extrait lui-même, ce qui est un peu inutile. Les résultats de Gzip dépendent du reste du document (c'est-à-dire de la source HTML si elle est intégrée dans un document, ou du reste du fichier JavaScript s'il en fait partie). Peut-être que comparer les tailles gzippées de l'extrait de code n'est pas la meilleure façon de mesurer cela ?

Votre extrait a l'air sympa. Bonne prise en réutilisant l'horodatage ga.l au lieu d'en générer un nouveau !

Et malheureusement, le test localStorage est probablement compromis quelque part dans un navigateur, car je me suis débarrassé des appels setItem et getItem et j'ai utilisé d'autres "astuces" de golf.

Si tel est le cas, ce serait un dealbreaker IMHO.

Nous pouvons remplacer document.getElementsByTagName('script')[0] par document.scripts[0] lorsque la prise en charge de Firefox < 9 n'est plus un problème.

@mathiasbynens GZIPping juste l'extrait de code se rapprochera des économies d'octets _minimum_ de la compression. Ce n'est donc pas tout à fait un point discutable. Dans presque tous les cas, le taux de compression de l'extrait de code augmentera à mesure que la taille de la page augmente.

Encore faut-il tester ! J'ai ajouté les appels getItem et setItem et j'ai réussi à le réduire à 309 octets :

+function(l,e){(ct=this[GoogleAnalyticsObject='ct']||function(l,e){(ct.q=ct.q||[]).push(arguments)}).l=+new Date,l=document.createElement('script'),l.src='//www.google-analytics.com/analytics.js',(e=document.getElementsByTagName('script')[0]).parentNode.insertBefore(l,e);try{localStorage.setItem(ct.l,ct.l),l=localStorage.getItem(ct.l)-ct.l,localStorage.removeItem(ct.l)}catch(l){};ct('create','UA-XXXXX-X',l?{}:{clientId:localStorage.clientId,storage:'none'}),ct(function(l,e){localStorage.clientId=l.get('clientId')}),ct('send','pageview')}()
  • J'utilise maintenant un IIFE qui utilise un signe + au lieu d'envelopper des parenthèses.
  • J'utilise également localStorage.clientId au lieu de localStorage.gaId car clientId économise quelques octets.
  • L'utilisation this au lieu de window a enregistré 1 octet de plus (en combinaison avec le déplacement de l'affectation GoogleAnalyticsObject ).
  • Changer ga en ct (ct est plus répandu) a sauvé un octet de plus (cela ne vaut probablement pas la confusion).
  • Se débarrasser de l'appel de fonction et réutiliser l pour la vérification localStorage en l'attribuant à 0 en cas de succès a permis d'économiser un tas d'octets.

Encore une fois, cela nécessite beaucoup plus de tests.

@davidmurdoch Des mises à jour sur les tests pour le moment ? Pouvons-nous écrire un flux de test pour cela afin que d'autres puissent aider à tester ?

Désolé, j'ai été MIA, j'ai été mis sur un projet prioritaire de 6 mois et je n'ai pas pu consacrer beaucoup de temps à autre chose.

Le moyen le plus simple (et le plus stupide) de tester cela consiste simplement à remplacer votre code d'analyse par ce nouveau code et à voir si vous obtenez des fluctuations étranges dans les nombres et les versions des navigateurs. Je l'ai fait moi-même et je n'ai rien vu qui ressorte. Cependant, je n'ai pas beaucoup de visiteurs oldie toute façon.

Une autre façon serait de charger ce script d'analyse expérimental dans un iframe généré (afin de ne pas interférer avec l'extrait d'analyse stable) et d'appeler _trackPageview partir de là, sous un autre compte GA, bien sûr. Ensuite, il vous suffit de comparer les données après environ une semaine.

Je ne peux pas promettre que je peux travailler sur un extrait de code pour le tester de sitôt ; si quelqu'un d'autre veut s'approprier ces idées pendant que je retourne dans la clandestinité, allez-y. :-)

Je viens de commencer un test pour http://drublic.github.io/css-modal/. J'ai eu 97 000 pages vues le mois dernier, mais elles se sont largement répandues dans le navigateur.

Les nombres:

  1. Chrome 44,01 %
  2. Firefox 34,38%
  3. Internet Explorer 8,86 %
  4. Opéra 5,26%
  5. Safari 4,01%
  6. Navigateur Android 2,22 %

Attendons voir. J'ai obtenu les statistiques "normales" en cours d'exécution en parallèle.

En dehors de cela, je pense que le code a besoin de quelques mises à jour supplémentaires pour la lisibilité (80 caractères par ligne et où insérer l'identifiant).

Je reviendrai sur ce test dans une semaine environ.

Je suis un peu en avance mais mes conclusions sont assez stables pour le moment. Malheureusement, je vois une grande différence dans le nombre de visiteurs pour les deux comptes.

La mise en œuvre par défaut affiche 2 964 visites uniques du 13 au 17 mars.
La base de stockage local affiche 756 visites uniques pour la même période.

Il peut y avoir trois raisons possibles :

  • mon implémentation du snipped est corrompue
  • le chargement de l'iframe est bloqué par les navigateurs
  • l'intégration du stockage local du snippé est rompue

Actuellement je ne vois aucune erreur dans mon code ici : http://drublic.github.io/css-modal/test-gau-localstorage.html (qui est l'iframe qui a été intégré dans le site).

De plus, je n'ai pas rencontré d'iframes bloqués par des navigateurs ou des pages. Quelqu'un at-il une idée si cela pourrait arriver?

Ce qui m'amène à la solution selon laquelle le stockage local GUA coupé a des bogues. Je n'ai pas examiné quels pourraient être les problèmes.
Pouvons-nous développer une variante non minifée pour des tests supplémentaires et minimiser après avoir trouvé une solution de travail ?

De plus, j'opterais pour le décodage de HTML5BP v5.0 et le publierais avec 5.1 si nous trouvons une solution. Qu'en pensez-vous?

De plus, j'opterais pour le descoping de HTML5BP v5.0 et le publierais avec 5.1

@drublic :+1: (problème ajouté au jalon v5.1.0 ).

Si vos numéros sont si éloignés, c'est probablement parce que vous devez fournir un clientId par défaut lorsque vous appelez ga('create', w/ storage:'none' .

https://developers.google.com/analytics/devguides/collection/analyticsjs/domains#disableCookies

Je viens de bloguer sur ce problème sur mon site, ici : Google Async Analytics utilisant LocalStorage et de configurer une page de test ici : http://davidmurdoch.com/google-async-analytics-using-localstorage-test/.

Merci de lire, partager et tester.

(Remarque : si vous trouvez des fautes de frappe ou des erreurs sur ces pages, faites-le moi savoir sur Twitter @pxcoach .

Hé, désolé d'arriver un peu en retard à la fête. Je travaille dans l'équipe Google Analytics, et je voulais commenter et donner mon avis sur cette question.

Tout d'abord, je ne pense pas que ce soit une bonne idée pour le projet H5BP de recommander un extrait de suivi Google Analytics fonctionnellement différent de celui officiellement recommandé. Les gens supposeront probablement qu'ils sont identiques, et s'ils ne le sont pas, cela créera de la confusion. Si la documentation de Google Analytics affirme que GA prend en charge certaines fonctionnalités et que ce n'est pas parce que quelqu'un utilise un extrait différent, cela entraînera probablement des problèmes assez difficiles à déboguer (surtout si H5BP ne montre pas clairement que les extraits sont différents).

S'il y a quelque chose que GA pourrait faire mieux, nous aimerions évoluer avec les besoins de la communauté plutôt que de nous en écarter. (BTW, n'hésitez pas à m'envoyer un ping ou à me mettre en copie sur tout problème Github lié à GA.)

Quoi qu'il en soit, voici le principal problème avec localStorage et pourquoi GA ne l'offre pas comme mécanisme de stockage par défaut :

localStorage est limité à location.origin alors que les cookies peuvent être limités à un domaine de premier niveau. Le stockage des cookies permet à analytics.js d'effectuer un suivi de sous-domaine prêt à l'emploi, ce qui ne serait pas possible avec localStorage. De plus, si des parties de votre site sont HTTP et d'autres parties sont HTTPS, cela échouerait également (et par échec, je veux dire que le stockage n'est pas partagé, donc vous perdriez l'ID client et GA le traiterait comme une session distincte ). S'il est vrai que ce ne sont pas des préoccupations pour la plupart des utilisateurs GA, je pense toujours qu'il serait mauvais d'offrir cet extrait de code proposé en remplacement en raison de la perte de fonctionnalités que je viens de décrire.

Cela étant dit, sur la base de ce problème et du billet de blog de @davidmurdoch , nous allons essayer de donner la priorité à la construction d'un mécanisme localStorage officiellement pris en charge. Actuellement, le paramètre storage ne prend en charge que les options cookie et none , mais nous aimerions ajouter une troisième option localStorage , afin que les utilisateurs qui ne le font pas besoin d'un sous-domaine ou d'un suivi inter-schémas peut s'inscrire. Je ne sais pas quand cela sera ajouté, mais je peux mettre à jour ce problème quand/si c'est le cas.

Cela semble-t-il raisonnable à tout le monde ?

@philipwalton Merci pour le commentaire!

Cela semble-t-il raisonnable à tout le monde ?

Cc : @davidmurdoch , @mathiasbynens

Cela étant dit, sur la base de ce problème et du billet de blog de @davidmurdoch , nous allons essayer de donner la priorité à la construction d'un mécanisme localStorage officiellement pris en charge.

:+1:

Veuillez mettre à jour le problème lorsque cela sera ajouté. Merci!

@philipwalton , :+1 : Excellente nouvelle ! Cependant, vous n'avez pas besoin d'essayer de le construire, nous l'avons déjà fait ! :-p (je plaisante, je plaisante).

Je vais continuer et mettre à jour mon article de blog avec cette nouvelle et créer un référentiel GitHub avec le code de suivi non officiel localStorage , en veillant à souligner ses lacunes. Merci!

:+1: mais il semble également que le futur Web ait besoin d'une sorte de topLevelStorage . Heureux que l'option soit disponible. Dans cet esprit, et lorsque l'extrait de code arrive, quelle pourrait être la préférence pour h5bp ?

@jonathantneal , nous avions globalStorage dans Firefox, qui faisait du stockage croisé, des ports et des sous-domaines. Firefox était le seul à l'implémenter, et il a depuis été marqué obsolète. :-(

@davidmurdoch Merci beaucoup d'avoir ouvert ce numéro et de l'avoir approfondi, nous l'apprécions sincèrement !

@philipwalton Merci encore d'avoir rejoint la discussion, et comme l'a dit @mathiasbynens , tenez-nous au courant !

et créez un référentiel GitHub avec le code de suivi localStorage non officiel, en veillant à souligner ses lacunes.

Le référentiel de @davidmurdoch est https://github.com/davidmurdoch/ga-localstorage(bien qu'il ne soit pas encore mis à jour).

Je viens de publier le script "Google Analytics using localStorage" sur npm : https://www.npmjs.org/package/ga-localstorage

Le référentiel https://github.com/davidmurdoch/ga-localstorage a également été mis à jour avec le code.

Bonjour, avez-vous lu ce commentaire SO?

http://stackoverflow.com/questions/4502128/convert-google-analytics-cookies-to-local-session-storage/19207035#comment -44767913

Je serais curieux de savoir ce que vous en pensez tous.

@caesarsol Je pense que c'est une très mauvaise idée. Comme je l'ai décrit dans mon commentaire , les cookies et localStorage n'ont pas les mêmes restrictions, donc les échanger pour chaque script qui s'exécute sur la page est extrêmement risqué.

bonjour @philipwalton , merci pour la réponse mais peut-être que j'ai mal expliqué, je faisais référence à ce commentaire de l'utilisateur SO _smhmic_ :

Cela pourrait violer GA TOS ! Voici une citation de seconde main d'un membre de l'équipe GA, tirée de cet article : "Utiliser les mécanismes de gestion d'état HTTP" (lire : localStorage) "pour propager l'état des cookies est un contournement de nos garanties de confidentialité. Cela viole les conditions d'utilisation de Google Analytics ". Mon interprétation de ceci est que GA utilise des cookies et non localStorage parce que plus d'utilisateurs connaissent le concept de cookies et comment les effacer ; ainsi, l'utilisation des cookies par GA est une fonctionnalité de confidentialité. – smhmic

L'utilisation de mécanismes de gestion d'état HTTP" (lire : localStorage) pour propager l'état des cookies constitue un contournement de nos mesures de protection de la vie privée. Cela enfreint les conditions d'utilisation de Google Analytics.

Hummm, je ne pense pas que ce soit vrai. Il existe des fonctionnalités de désactivation fournies par GA (par exemple, les extensions Chrome) qui ne dépendent pas de l'utilisation de cookies par l'implémenteur. Je pense que le point de cette section du TOS est que vous ne pouvez pas créer un mécanisme par lequel quelqu'un qui utilise une extension officielle "ne pas suivre" sera _toujours_ suivi.

Je peux l'examiner plus en détail et je mettrai à jour ce fil si mes hypothèses se révèlent fausses.

Mettre à jour:

Il n'est pas contre TOS d'utiliser localStorage pour stocker le ClientID ; il est désormais officiellement pris en charge par Google : https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id#using_localstorage_to_store_the_client_id

Remarque : si vous devez prendre en charge des navigateurs (extrêmement) anciens (comme iOS5 et FF4), leur extrait d'exemple peut échouer (voir : https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage. js).

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

necolas picture necolas  ·  44Commentaires

coliff picture coliff  ·  12Commentaires

coliff picture coliff  ·  14Commentaires

neilcreagh picture neilcreagh  ·  28Commentaires

greenchili picture greenchili  ·  20Commentaires