Html5-boilerplate: Verwenden Sie localStorage für Google Analytics-Tracking, wenn verfügbar

Erstellt am 7. Okt. 2013  ·  30Kommentare  ·  Quelle: h5bp/html5-boilerplate

TL;DR:

(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');

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

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

Wir könnten Modernizer.localstorage verwenden, um nach Unterstützung für localStorage zu suchen und auf Cookies zurückzugreifen, falls diese nicht verfügbar sind. Obwohl ich nicht sicher bin, ob wir Modernizr als Abhängigkeit einschließen wollen.

Wieso den?
Weil Google sein Cookie nicht für jede einzelne Anfrage an Ihre Domain (oder ihre eigene) an Ihren Server senden muss.

new feature

Hilfreichster Kommentar

Aktualisieren:

Es verstößt nicht gegen TOS, localStorage zum Speichern der ClientID zu verwenden; es wird jetzt offiziell von Google unterstützt: https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id#using_localstorage_to_store_the_client_id

Hinweis: Wenn Sie (extrem) alte Browser (wie iOS5 und FF4) unterstützen müssen, kann ihr Beispiel-Snippet fehlschlagen (siehe: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage. js).

Alle 30 Kommentare

Obwohl ich nicht sicher bin, ob wir Modernizr als Abhängigkeit einschließen wollen.

Vielleicht wäre es am besten, es einfach in die Dokumentation aufzunehmen?

Pingen Sie auch @mathiasbynens.

Danke für die Optimierung des Ausschnitts, David. Als @alrra denke ich, dass wir gut darin sind, es zu den Dokumenten hinzuzufügen.

Der Kredit gehört nicht mir; Dies wurde mir von @elmerbulthuis mitgeteilt. Obwohl ich dies nicht wirklich als Optimierung des _snippet_ selbst betrachten würde, per se --- es ist eher eine Optimierung des Webs als Ganzes :-p.

Ich frage mich, wie viele Bytes global eingespart werden könnten, wenn jeder die localStorage -Lösung übernehmen würde.

Ich bin offensichtlich ein großer Fan dieser Lösung. Das einzige Problem bei der standardmäßigen Aufnahme in die Boilerplate ist das von @davidmurdoch erwähnte: Wir müssen zuerst einen Feature-Test für localStorage durchführen. Dies kann mit Modernizr oder durch Hinzufügen eines kleinen Stücks eigenständigen Codes erfolgen, aber in jedem Fall wird die Seitengröße leicht erhöht. Andererseits spart es auf Dauer viele Bytes, da keine Cookies in den Request-Headern für Ressourcen der betroffenen Domain gesendet werden.

Etwas wie das:

(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')}());

(Es verwendet den Funktionstest localStorage von http://mathiasbynens.be/notes/localstorage-pattern.)

Es scheint nach einigen kurzen Tests gut zu funktionieren. Ich werde eine PR erstellen, nachdem ich dies ausführlicher getestet habe. (Hilfe natürlich willkommen!)

FYI: Dies hat das Potenzial, etwa 33 Rohbytes (Header/Cookies werden nicht komprimiert) pro Roundtrip für jede Anfrage an die betroffenen Domains einzusparen.

Die aktuelle Inline-Feature-Detect-Lösung von @mathiasbynens ist 130 komprimierte Bytes∗ größer (offensichtlich wird dies für jede einzelne Seite anders sein, aber es gibt uns eine ungefähre Vorstellung). Also sollten wir wahrscheinlich sehen, ob wir das ein bisschen weiter runterspielen können.

Ich persönlich würde gerne das gzipped Diff auf 65 Bytes herunterrechnen und werde es bald selbst versuchen. :-)

_∗mit diesem Deflator: http://www.vervestudios.co/projects/compression-tests/snippet-deflator_

318 GZIPped Bytes (unsere aktuelle Version ist 248 GZIPped Bytes):

(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')}())

Dies ist nicht sehr gut getestet, also muss ich das noch tun. Aber es ist ein Anfang.

Und leider ist der localStorage -Test wahrscheinlich irgendwo in irgendeinem Browser kompromittiert, da ich setItem - und getItem -Aufrufe losgeworden bin und einige andere Golf-"Tricks" verwendet habe.

Das ist alles, was ich jetzt habe. :-)

Mir ist gerade aufgefallen, dass wir das Snippet selbst gezippt haben, was irgendwie sinnlos ist. Gzip-Ergebnisse hängen vom Rest des Dokuments ab (dh von der HTML-Quelle, wenn sie in ein Dokument eingebettet ist, oder vom Rest der JavaScript-Datei, wenn sie Teil eines Dokuments ist). Vielleicht ist das Vergleichen von gezippten Größen nur des Snippets nicht der beste Weg, dies zu messen?

Dein Ausschnitt sieht gut aus. Guter Fang, den Zeitstempel ga.l wiederzuverwenden, anstatt einen neuen zu generieren!

Und leider ist der localStorage -Test wahrscheinlich irgendwo in irgendeinem Browser kompromittiert, da ich setItem- und getItem-Aufrufe losgeworden bin und einige andere Golf-Tricks verwendet habe.

Wenn das der Fall ist, wäre es meiner Meinung nach ein Dealbreaker.

Wir können document.getElementsByTagName('script')[0] durch document.scripts[0] ersetzen, wenn die Unterstützung von Firefox < 9 kein Problem mehr ist.

@mathiasbynens GZIPping nur des Snippets wird die _mindestens_ Byte-Einsparungen durch die Komprimierung annähern. Es ist also nicht ganz ein strittiger Punkt. In fast allen Fällen erhöht sich das Komprimierungsverhältnis für das Snippet mit zunehmender Seitengröße.

Muss noch getestet werden! Ich habe die Aufrufe getItem und setItem wieder hinzugefügt und es geschafft, sie auf 309 Bytes zu reduzieren:

+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')}()
  • Ich verwende jetzt ein IIFE, das ein + -Zeichen verwendet, anstatt Klammern zu umschließen.
  • Ich verwende auch localStorage.clientId anstelle von localStorage.gaId , da clientId einige Bytes spart.
  • Die Verwendung this anstelle von window sparte 1 weiteres Byte (in Kombination mit dem Verschieben der GoogleAnalyticsObject -Zuweisung).
  • Das Ändern ga in ct (ct ist weiter verbreitet) sparte ein weiteres Byte (dies ist wahrscheinlich die Verwirrung nicht wert).
  • Den Funktionsaufruf loszuwerden und l für die localStorage -Prüfung wiederzuverwenden, indem es bei Erfolg 0 zugewiesen wurde, sparte eine Menge Bytes.

Auch dies erfordert viel mehr Tests.

@davidmurdoch Gibt es schon Neuigkeiten zu den Tests? Können wir dafür einen Testablauf aufschreiben, damit andere beim Testen helfen können?

Tut mir leid, dass ich MIA war, ich wurde auf ein sechsmonatiges Projekt mit hoher Priorität gesetzt und konnte nicht viel Zeit für etwas anderes aufwenden.

Der einfachste (und dümmste) Weg, dies zu testen, besteht darin, einfach Ihren Analysecode durch diesen neuen Code zu ersetzen und zu sehen, ob Sie irgendwelche seltsamen Schwankungen in Zahlen und Browserversionen erhalten. Ich habe das selbst gemacht und nichts gesehen, was herausragt. Allerdings habe ich sowieso nicht viele oldie Besucher.

Eine andere Möglichkeit wäre, dieses experimentelle Analyseskript in einen generierten Iframe zu laden (um das stabile Analyse-Snippet nicht zu beeinträchtigen) und _trackPageview von dort aus aufzurufen, natürlich unter einem anderen GA-Konto. Dann müssen Sie nur noch die Daten nach etwa einer Woche vergleichen.

Ich kann nicht versprechen, dass ich bald an einem Drop-in-Snippet zum Testen arbeiten kann; Wenn jemand anderes diese Ideen übernehmen möchte, während ich mich wieder verstecke, machen Sie bitte weiter. :-)

Ich habe gerade einen Test für http://drublic.github.io/css-modal/ gestartet. Ich hatte in den letzten Monaten 97.000 Seitenaufrufe, aber wild über den Browser verteilt.

Die Zahlen:

  1. Chrom 44,01 %
  2. Firefox 34,38 %
  3. Internet-Explorer 8,86 %
  4. Oper 5,26 %
  5. Safari 4,01 %
  6. Android-Browser 2,22 %

Warten wir es ab. Ich habe die "normalen" Statistiken parallel laufen lassen.

Abgesehen davon denke ich, dass der Code noch einige Updates für die Lesbarkeit benötigt (80 Zeichen pro Zeile und wo die Kennung einzufügen ist).

Ich werde in etwa einer Woche auf diesen Test zurückkommen.

Ich bin ein bisschen früh dran, aber meine Ergebnisse sind im Moment ziemlich stabil. Leider sehe ich große Unterschiede in der Anzahl der Besucher für beide Konten.

Die Standardimplementierung zeigt 2.964 eindeutige Besuche für den 13. bis 17. März.
Der lokale Speicher basiert auf 756 eindeutigen Besuchen für denselben Zeitraum.

Es kann drei mögliche Gründe geben:

  • Meine Implementierung des Ausschnitts ist beschädigt
  • Das Laden des Iframes wird von Browsern blockiert
  • Die lokale Speicherintegration des Snipped ist defekt

Derzeit sehe ich hier keine Fehler in meinem Code: http://drublic.github.io/css-modal/test-gau-localstorage.html (das ist der iframe, der in die Site integriert wurde).

Ich habe auch nicht erlebt, dass Iframes von Browsern oder Seiten blockiert werden. Hat jemand eine Idee, ob dies passieren könnte?

Was mich zu der Lösung führt, dass der lokale Speicher, den GUA ausgeschnitten hat, Fehler hat. Ich habe nicht untersucht, was die Probleme sein könnten.
Können wir eine nicht minimierte Variante für weitere Tests entwickeln und minimieren, nachdem wir eine funktionierende Lösung gefunden haben?

Ich würde mich auch dafür entscheiden, dies von HTML5BP v5.0 zu entschlüsseln und es mit 5.1 zu veröffentlichen, wenn wir eine Lösung finden. Was denkt ihr?

Ich würde mich auch dafür entscheiden, dies von HTML5BP v5.0 zu entschlüsseln und es mit 5.1 zu veröffentlichen

@drublic :+1: (Problem zum v5.1.0-Meilenstein hinzugefügt).

Wenn Ihre Nummern so falsch sind, müssen Sie wahrscheinlich eine Standard-Client-ID angeben, wenn Sie ga('create', mit storage:'none' anrufen.

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

Ich habe gerade über dieses Problem auf meiner Website hier gebloggt: Google Async Analytics mit LocalStorage und hier eine Testseite eingerichtet: http://davidmurdoch.com/google-async-analytics-using-localstorage-test/.

Bitte lesen, teilen und testen.

(Hinweis: Wenn Sie Tippfehler oder Fehler auf diesen Seiten finden, lassen Sie es mich auf Twitter @pxcoach wissen.

Hey, tut mir leid, dass ich ein bisschen zu spät zur Party komme. Ich arbeite im Google Analytics-Team und möchte etwas zu diesem Thema sagen und meine Gedanken darlegen.

Zunächst einmal halte ich es für keine gute Idee, dass das H5BP-Projekt ein Google Analytics-Tracking-Snippet empfiehlt, das sich funktional von dem offiziell empfohlenen unterscheidet. Die Leute werden wahrscheinlich annehmen, dass sie gleich sind, und wenn sie es tatsächlich nicht sind, wird es Verwirrung stiften. Wenn in der Google Analytics-Dokumentation behauptet wird, dass GA eine Funktion unterstützt, dies jedoch nicht der Fall ist, weil jemand ein anderes Snippet verwendet, führt dies wahrscheinlich zu einigen ziemlich schwer zu behebenden Problemen (insbesondere, wenn H5BP nicht deutlich macht, dass die Snippets unterschiedlich sind).

Wenn es etwas gibt, das GA besser machen könnte, würden wir uns gerne mit den Bedürfnissen der Community weiterentwickeln, anstatt davon abzuweichen. (Übrigens, zögern Sie nicht, mich bei allen GA-bezogenen Github-Problemen zu pingen oder auf CC zu setzen.)

Wie auch immer, hier ist das Hauptproblem mit localStorage und warum GA es nicht als Standardspeichermechanismus anbietet:

localStorage ist auf location.origin beschränkt, während Cookies auf eine Top-Level-Domain beschränkt werden können. Die Cookie-Speicherung ermöglicht analytics.js das Subdomain-Tracking von Anfang an, und dies wäre mit localStorage nicht möglich. Wenn Teile Ihrer Website HTTP und andere Teile HTTPS sind, würde dies außerdem fehlschlagen (und mit fehlschlagen meine ich, dass der Speicher nicht gemeinsam genutzt wird, sodass Sie die Client-ID verlieren würden und GA sie als separate Sitzung behandeln würde ). Obwohl dies für die meisten GA-Benutzer keine Bedenken sind, denke ich dennoch, dass es schlecht wäre, dieses vorgeschlagene Snippet aufgrund des gerade beschriebenen Funktionsverlusts als Drop-in-Ersatz anzubieten.

Abgesehen davon werden wir basierend auf diesem Problem und dem Blogbeitrag von @davidmurdoch versuchen, den Aufbau eines offiziell unterstützten localStorage-Mechanismus zu priorisieren. Derzeit unterstützt der Parameter storage nur die Optionen cookie und none , aber wir möchten eine dritte Option localStorage hinzufügen, damit Benutzer, die dies nicht tun Benötigen Sie Subdomain- oder Cross-Scheme-Tracking, können Sie sich anmelden. Ich weiß nicht, wann dies hinzugefügt wird, aber ich kann dieses Problem aktualisieren, wenn/falls dies der Fall ist.

Erscheint das jedem vernünftig?

@philipwalton Danke für den Kommentar!

Erscheint das jedem vernünftig?

Cc: @davidmurdoch , @mathiasbynens

Abgesehen davon werden wir basierend auf diesem Problem und dem Blogbeitrag von @davidmurdoch versuchen, den Aufbau eines offiziell unterstützten localStorage-Mechanismus zu priorisieren.

:+1:

Bitte aktualisieren Sie das Problem, wenn dies hinzugefügt wird. Danke!

@philipwalton :+1: Hervorragende Neuigkeiten! Sie müssen es jedoch nicht _versuchen_, um es zu bauen, wir haben es bereits getan! :-p (Ich scherze, ich scherze).

Ich werde meinen Blog-Beitrag mit diesen Neuigkeiten aktualisieren und ein GitHub-Repo mit dem inoffiziellen localStorage -Tracking-Code erstellen, wobei ich darauf achte, seine Mängel hervorzuheben. Danke!

:+1: aber es scheint auch so, als ob das Web der Zukunft eine Art von topLevelStorage braucht. Gut, dass die Option zur Verfügung gestellt wird. In Anbetracht dessen und wenn das Snippet eintrifft, was könnte die Präferenz für h5bp sein?

@jonathantneal , wir hatten globalStorage in Firefox, das Cross-Schema-, Port- und Subdomain-Speicherung durchführte. Firefox war der einzige, der es implementiert hat, und es wurde seitdem als veraltet markiert. :-(

@davidmurdoch Vielen Dank, dass Sie diese Ausgabe geöffnet und sich damit beschäftigt haben. Wir wissen das aufrichtig zu schätzen!

@philipwalton Nochmals vielen Dank für die Teilnahme an der Diskussion, und wie @mathiasbynens sagte , halten Sie uns bitte auf dem Laufenden!

und erstellen Sie ein GitHub-Repo mit dem inoffiziellen localStorage-Verfolgungscode, wobei Sie darauf achten, dessen Mängel hervorzuheben.

Das Repository von @davidmurdoch ist https://github.com/davidmurdoch/ga-localstorage(obwohl es noch nicht aktualisiert wurde).

Ich habe gerade das Skript "Google Analytics using localStorage" in npm veröffentlicht: https://www.npmjs.org/package/ga-localstorage

Das Repo https://github.com/davidmurdoch/ga-localstorage wurde ebenfalls mit dem Code aktualisiert.

Hallo, hast du diesen SO-Kommentar gelesen?

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

Mich würde interessieren, was ihr alle denkt.

@caesarsol Ich denke, das ist eine wirklich schlechte Idee. Wie ich in meinem Kommentar beschrieben habe, haben Cookies und localStorage nicht die gleichen Einschränkungen, daher ist es extrem riskant, sie für jedes einzelne Skript auszutauschen, das auf der Seite ausgeführt wird.

Hallo @philipwalton , danke für die Antwort, aber vielleicht habe ich es schlecht erklärt, ich bezog mich auf diesen Kommentar von SO-Benutzer _smhmic_:

Dies könnte gegen GA TOS verstoßen! Hier ist ein Zitat aus zweiter Hand eines GA-Teammitglieds aus diesem Artikel: „Die Verwendung von HTTP-Statusverwaltungsmechanismen“ (sprich: localStorage) „zur Weitergabe des Cookie-Status ist eine Umgehung unserer Datenschutzbestimmungen. Dies verstößt gegen die Nutzungsbedingungen von Google Analytics ". Meine Interpretation davon ist, dass GA Cookies und nicht localStorage verwendet, da mehr Benutzer mit dem Konzept von Cookies und deren Löschung vertraut sind; Daher ist die Verwendung von Cookies durch GA eine Datenschutzfunktion. – smhm

Die Verwendung von HTTP-Zustandsverwaltungsmechanismen" (sprich: localStorage) zur Weitergabe des Cookie-Zustands stellt eine Umgehung unserer Datenschutzmaßnahmen dar. Dies verstößt gegen die Nutzungsbedingungen von Google Analytics

Hmm, ich glaube nicht, dass das stimmt. Es gibt Deaktivierungsfunktionen, die GA bereitstellt (z. B. Chrome-Erweiterungen), die nicht darauf angewiesen sind, dass der Implementierer Cookies verwendet. Ich denke, der Punkt dieses Abschnitts der Nutzungsbedingungen ist, dass Sie keinen Mechanismus schaffen können, durch den jemand, der eine offizielle „Do Not Track“-Erweiterung verwendet, _immer noch_ verfolgt wird.

Ich kann es weiter untersuchen und ich werde diesen Thread aktualisieren, wenn sich meine Annahmen als falsch herausstellen.

Aktualisieren:

Es verstößt nicht gegen TOS, localStorage zum Speichern der ClientID zu verwenden; es wird jetzt offiziell von Google unterstützt: https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id#using_localstorage_to_store_the_client_id

Hinweis: Wenn Sie (extrem) alte Browser (wie iOS5 und FF4) unterstützen müssen, kann ihr Beispiel-Snippet fehlschlagen (siehe: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage. js).

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen