web-dev-qa-db-fra.com

PageSpeed ​​Insights 99/100 à cause de Google Analytics - Comment puis-je mettre en cache GA?

Je suis en quête d'atteindre 100/100 sur PageSpeed ​​et j'y suis presque. J'essaie de trouver une bonne solution pour mettre en cache Google Analytics.

Voici le message que je reçois:

Exploiter la mise en cache du navigateur Définir une date d'expiration ou une durée maximale dans les en-têtes HTTP pour les ressources statiques indique au navigateur de charger les ressources précédemment téléchargées à partir du disque local plutôt que sur le réseau. Exploitez la mise en cache du navigateur pour les ressources suivantes pouvant être mises en cache: http://www.google-analytics.com/analytics.js (2 heures)

La seule solution que j'ai trouvée date de 2012 et je ne pense pas que ce soit une bonne solution. Essentiellement, vous copiez le code GA et vous l’hébergez vous-même. Vous exécutez ensuite une tâche cron pour revérifier Google une fois par jour afin de récupérer le dernier code GA et de le remplacer.

http://diywpblog.com/leverage-browser-cache-optimize-google-analytics/

Que puis-je faire pour atteindre 100/100 tout en utilisant également Google Analytics?

Je vous remercie.

237
sjmartin

Eh bien, si Google vous trompe, vous pouvez le tromper:

Ceci est l'agent utilisateur pour pageSpeed:

“Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.8 (KHTML, like Gecko; Google Page Speed Insights) Chrome/19.0.1084.36 Safari/536.8”

Vous pouvez insérer une condition pour éviter de servir le script d'analyse à PageSpeed:

<?php if (!isset($_SERVER['HTTP_USER_AGENT']) || stripos($_SERVER['HTTP_USER_AGENT'], 'Speed Insights') === false): ?>
// your analytics code here
<?php endif; ?>

Évidemment, cela n’apportera aucune amélioration réelle, mais si votre seule préoccupation est d’obtenir un score de 100/100, cela le fera.

234
NiloVelez

Il existe un sous-ensemble de la bibliothèque Google Analytics js appelé ga-lite que vous pouvez mettre en cache à votre guise.

La bibliothèque utilise l'API public REST de Google Analytics pour envoyer les données de suivi des utilisateurs à Google. Vous pouvez en lire plus de le blog sur ga-lite .

Disclaimer: Je suis l'auteur de cette bibliothèque. J'ai eu du mal avec ce problème spécifique et le meilleur résultat que j'ai trouvé était de mettre en œuvre cette solution.

37
jehna1

Voici une solution très simple utilisant JS, pour le suivi de base GA, qui fonctionnera également pour les caches/proxys Edge (converti à partir d'un commentaire):

if(navigator.userAgent.indexOf("Speed Insights") == -1) {
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).Push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-XXXXXXXXX-X', 'auto');
  ga('send', 'pageview');
}

Remarque: Il s'agit du script par défaut GA. Vous pouvez avoir d’autres appels ga() et, dans l’affirmative, vous devez toujours vérifier l’agent utilisateur avant d’appeler ga(), faute de quoi une erreur pourrait se produire.

19
Half Crazed

Je ne m'inquiéterais pas pour ça. Ne le mettez pas sur votre propre serveur, cela semble être un problème avec Google, mais il en vaut la peine. Mettre le fichier sur votre propre serveur va créer de nombreux nouveaux problèmes.

Ils ont probablement besoin que le fichier soit appelé à chaque fois plutôt que de le récupérer dans la mémoire cache du client, car vous ne comptabiliseriez pas les visites.

Si cela ne vous convient pas, lancez l'URL Google Insights sur Google Insights lui-même, riez, détendez-vous et continuez votre travail.

16
Leo Muller

Dans les documents Google, ils ont identifié un filtre pagespeed qui chargera le script de manière asynchrone:

ModPagespeedEnableFilters make_google_analytics_async

Vous pouvez trouver la documentation ici: https://developers.google.com/speed/pagespeed/module/filter-make-google-analytics-async

Une chose à souligner est que le filtre est considéré à haut risque. De la docs:

Le filtre make_google_analytics_async est expérimental et n'a pas fait l'objet de tests approfondis dans le monde réel. Un cas où une réécriture causerait des erreurs est si le filtre manque les appels aux méthodes Google Analytics qui renvoient des valeurs. Si de telles méthodes sont trouvées, la réécriture est ignorée. Cependant, les méthodes de disqualification seront oubliées si elles arrivent avant le chargement, si elles se trouvent dans des attributs tels que "onclick" ou si elles se trouvent dans des ressources externes. Ces cas devraient être rares.

10
Cameron Scott

Vous pouvez essayer d'héberger analytics.js localement et de mettre à jour son contenu à l'aide d'un script de mise en cache ou manuellement.

Le fichier js n'est mis à jour que quelques fois par an. Si vous n'avez pas besoin de nouvelles fonctions de suivi, mettez-le à jour manuellement.

https://developers.google.com/analytics/devguides/collection/analyticsjs/changelog

6
JJTalik

stockez localy analytics.js, mais cela n’est pas recommandé par Google: https://support.google.com/analytics/answer/1032389?hl=fr

il est déconseillé car Google peut mettre à jour le script quand il le souhaite. Il vous suffit donc de créer un script qui télécharge des analyses en javascript chaque semaine pour ne pas avoir de problème!

En passant, cette solution empêche Adblock de bloquer les scripts Google Analytics

6
Froggiz

varvy.com ( 100/100 Aperçu de la vitesse des pages Google ) charge le code Google Analytics uniquement si l'utilisateur fait défiler la page:

var fired = false;

window.addEventListener("scroll", function(){
    if ((document.documentElement.scrollTop != 0 && fired === false) || (document.body.scrollTop != 0 && fired === false)) {

        (function(i,s,o,g,r,a,m{i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).Push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');

        ga('create', 'UA-XXXXXXXX-X', 'auto');
        ga('send', 'pageview');

        fired = true;
    }
}, true);
5
ar099968

Vous pouvez utiliser un proxy pour le script Google Analytics via votre propre serveur, l'enregistrer localement et le mettre à jour automatiquement toutes les heures pour vous assurer qu'il s'agit toujours de la version la plus récente de Google.

Je l'ai déjà fait sur quelques sites et tout fonctionne bien.

Itinéraire du proxy Google Analytics dans une pile NodeJS/MEAN

Voici comment je l'ai implémenté sur mon blog qui est construit avec la pile MEAN.

router.get('/analytics.js', function (req, res, next) {
    var fileUrl = 'http://www.google-analytics.com/analytics.js';
    var filePath = path.resolve('/content/analytics.js');

    // ensure file exists and is less than 1 hour old
    fs.stat(filePath, function (err, stats) {
        if (err) {
            // file doesn't exist so download and create it
            updateFileAndReturn();
        } else {
            // file exists so ensure it's not stale
            if (moment().diff(stats.mtime, 'minutes') > 60) {
                updateFileAndReturn();
            } else {
                returnFile();
            }
        }
    });

    // update file from remote url then send to client
    function updateFileAndReturn() {
        request(fileUrl, function (error, response, body) {
            fs.writeFileSync(filePath, body);
            returnFile();
        });
    }

    // send file to client
    function returnFile() {
        res.set('Cache-Control', 'public, max-age=' + oneWeekSeconds);
        res.sendFile(filePath);
    }
});

Méthode d'action du proxy Google Analytics dans ASP.NET MVC

Voici comment je l'ai implémenté sur d'autres sites construits avec ASP.NET MVC.

public class ProxyController : BaseController
{
    [Compress]
    public ActionResult GoogleAnalytics()
    {
        var fileUrl = "https://ssl.google-analytics.com/ga.js";
        var filePath = Server.MapPath("~/scripts/analytics.js");

        // ensure file exists 
        if (!System.IO.File.Exists(filePath))
            UpdateFile(fileUrl, filePath);

        // ensure file is less than 1 hour old
        var lastModified = System.IO.File.GetLastWriteTime(filePath);
        if((DateTime.Now - lastModified).TotalMinutes > 60)
            UpdateFile(fileUrl, filePath);

        // enable caching for 1 week for page speed score
        Response.AddHeader("Cache-Control", "max-age=604800");

        return JavaScript(System.IO.File.ReadAllText(filePath));
    }

    private void UpdateFile(string fileUrl, string filePath)
    {
        using (var response = WebRequest.Create(fileUrl).GetResponse())
        using (var dataStream = response.GetResponseStream())
        using (var reader = new StreamReader(dataStream))
        {
            var body = reader.ReadToEnd();
            System.IO.File.WriteAllText(filePath, body);
        }
    }
}

C'est le CompressAttribute utilisé par MVC ProxyController pour la compression Gzip.

public class CompressAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {

        var encodingsAccepted = filterContext.HttpContext.Request.Headers["Accept-Encoding"];
        if (string.IsNullOrEmpty(encodingsAccepted)) return;

        encodingsAccepted = encodingsAccepted.ToLowerInvariant();
        var response = filterContext.HttpContext.Response;

        if (encodingsAccepted.Contains("gzip"))
        {
            response.AppendHeader("Content-encoding", "gzip");
            response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
        }
        else if (encodingsAccepted.Contains("deflate"))
        {
            response.AppendHeader("Content-encoding", "deflate");
            response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
        }
    }
}

Script Google Analytics mis à jour

Du côté client, j'ajoute le chemin d'analyse avec la date actuelle jusqu'à l'heure afin que le navigateur n'utilise pas une version en cache de plus d'une heure.

<!-- analytics -->
<script>
    (function (i, s, o, g, r, a, m) {
        i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
            (i[r].q = i[r].q || []).Push(arguments)
        }, i[r].l = 1 * new Date(); a = s.createElement(o),
        m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
    })(window, document, 'script', '/analytics.js?d=' + new Date().toISOString().slice(0, 13), 'ga');
</script>
5
Jason

Pour Nginx:

location ~ /analytics.js {
        proxy_pass https://www.google-analytics.com;
        expires 31536000s;
        proxy_set_header Pragma "public";
        proxy_set_header Cache-Control "max-age=31536000, public";
    }

Puis changez le chemin https://www.google-analytics.com/analytics.js à https://yoursite.com/analytics.js

4
Savad KP

PHP

Ajoutez ceci dans votre code HTML ou PHP:

<?php if (!isset($_SERVER['HTTP_USER_AGENT']) || stripos($_SERVER['HTTP_USER_AGENT'], 'Speed Insights') === false): ?>
  <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).Push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

    ga('create', 'UA-PUT YOUR GOOGLE ANALYTICS ID HERE', 'auto');
    ga('send', 'pageview');
  </script>
<?php endif; ?>

JavaScript

Cela fonctionne bien avec JavaScript:

  <script>
  if(navigator.userAgent.indexOf("Speed Insights") == -1) {
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).Push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

    ga('create', 'UA-<PUT YOUR GOOGLE ANALYTICS ID HERE>', 'auto');
    ga('send', 'pageview');
  }
  </script>

NiloVelez déjà dit: Évidemment, cela n'apportera aucune amélioration réelle, mais si votre seul souci est d'obtenir un 100/100 points cela le fera.

4
Suriyaa

essayez ceci juste insérer avant

<script async='async' src='https://cdn.jsdelivr.net/ga-lite/latest/ga-lite.min.js'></script> <script>var galite=galite||{};galite.UA="xx-xxxxxxx-x";</script>

Veuillez remplacer xx-xxxxxxx-x par votre code. Veuillez vérifier la mise en œuvre ici http://www.gee.web.id/2016/11/how-to-leverage-browser-caching-for-google- analitycs.html

1
Gee

Ouvrez le fichier https://www.google-analytics.com/analytics.js dans un nouvel onglet, copiez tout le code.

Maintenant, créez un dossier dans votre répertoire Web, renommez-le en google-analytics.

Créez un fichier texte dans le même dossier et collez tout le code que vous avez copié ci-dessus.

Renommez le fichier ga-local.js

Modifiez maintenant l'URL pour appeler votre fichier de script d'analyse hébergé localement dans votre code Google Analytics. Cela ressemblera à ceci: https://domain.xyz/google-analytics/ga.js

Enfin, placez votre NOUVEAU code Google Analytics dans le pied de page de votre page Web.

Tu es prêt. Maintenant, vérifiez votre site Web de Google PageSpeed ​​Insights. L'avertissement relatif à la mise en cache du navigateur dans Google Analytics ne s'affiche pas. Et le seul problème avec cette solution est de mettre à jour régulièrement le script Analytics manuellement.

0
FormaL

Google met en garde contre l'utilisation de copies locales des scripts analtics. Cependant, si vous le faites, vous voudrez probablement utiliser des copies locales des plugins et du script de débogage.

Un deuxième souci avec la mise en cache agressive est que vous obtiendrez des hits de pages mises en cache - qui peuvent avoir changé ou ont été supprimés du site.

0
Oren Bochman

Vous pouvez configurer une distribution cloudfront ayant www.google-analytics.com comme serveur d'origine et définir un en-tête d'expiration plus long dans les paramètres de distribution cloudfront. Puis modifiez ce domaine dans l'extrait de Google. Cela empêche la charge sur votre propre serveur et la nécessité de continuer à mettre à jour le fichier dans un travail cron.

Ceci est la configuration et oublie. Donc, vous voudrez peut-être ajouter une alerte de facturation à Cloudfront au cas où quelqu'un "copie" votre extrait de code et vole votre bande passante ;-)

Edit: j'ai essayé et ce n'est pas si facile, Cloudfront passe par l'en-tête Cache-Control sans moyen de le supprimer facilement

0
Jan M

Pour résoudre ce problème, vous devez télécharger le fichier localement et exécuter un travail cron pour continuer à mettre à jour. Remarque: cela ne rend pas votre site Web plus rapide, il est donc préférable de l'ignorer.

Cependant, à des fins de démonstration, suivez ce guide: http://diywpblog.com/leverage-browser-cache-optimize-google-analytics/

0
Mo Beigi

Cela peut faire l'affaire :)

<script>
  $.ajax({
  type: "GET",
  url: "https://www.google-analytics.com/analytics.js",
  success: function(){},
  dataType: "script",
  cache: true
  });
</script>
0
Nuno Sarmento

En fonction de votre utilisation des données Google Analytics, si vous souhaitez des informations de base (telles que des visites, des interactions de l'interface utilisateur), vous pouvez éventuellement ne pas inclure analytics.js, mais collecter des données dans GA.

Une option peut être d'utiliser à la place le protocole de mesure dans un script en cache. Google Analytics: Présentation du protocole de mesure

Lorsque vous définissez explicitement la méthode de transport sur image, vous pouvez voir comment GA construit ses propres balises d'image.

ga('set', 'transport', 'image');

https://www.google-analytics.com/r/collect
  ?v={protocol-version}
  &tid={tracking-id}
  &cid={client-id}
  &t={hit-type}
  &dl={location}

Vous pouvez créer vos propres demandes GET ou POST avec la charge utile requise.

Cependant, si vous avez besoin d'un niveau de détail supérieur, vos efforts ne seront probablement pas rentables.

0
Jonathan