PageSpeed ​​Insights 99/100 debido a Google Analytics: ¿cómo puedo almacenar en caché GA?

243

Estoy en una búsqueda para alcanzar 100/100 en PageSpeed ​​y ya casi estoy allí. Estoy tratando de encontrar una buena solución para almacenar en caché Google Analytics.

Aquí está el mensaje que recibo:

Aproveche el almacenamiento en caché del navegador Establecer una fecha de caducidad o una antigüedad máxima en los encabezados HTTP para los recursos estáticos indica al navegador que cargue los recursos descargados previamente desde el disco local en lugar de hacerlo a través de la red. Aproveche el almacenamiento en caché del navegador para los siguientes recursos almacenables en caché: http://www.google-analytics.com/analytics.js (2 horas)

La única solución que encontré fue de 2012 y no creo que sea una buena solución. Esencialmente copia el código GA y lo aloja usted mismo. Luego ejecuta un trabajo cron para volver a verificar Google una vez al día para obtener el último código GA y reemplazarlo.

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

¿Qué más puedo hacer para llegar a 100/100 mientras también uso Google Analytics?

Gracias.

sjmartin
fuente
1
Utilicé el método cron, sin uso de cron (cargas y cachés onload. Puedo compartir el código php si lo desea). Y me arreglaron mi sugerencia de fijación de GA. Pero queda un pequeño problema: dejé el encabezado "Cache-Control: max-age = 604800". Que es mucho más alto que 5 minutos de caché.
Roman Losev
66
Sin embargo, ¿es realmente una buena idea? El almacenamiento en caché de este archivo en su servidor significa que el navegador tendrá que volver a descargarlo en lugar de volver a usar el que ya ha almacenado en la memoria caché visitando otros sitios usando Google Analytics. Por lo tanto, en realidad puede ralentizar un poco a sus visitantes.
s427
Posible duplicado del almacenamiento en caché del navegador
Joe

Respuestas:

240

Bueno, si Google te está engañando, puedes engañar a Google:

Este es el agente de usuario para 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”

Puede insertar un condicional para evitar publicar el script de análisis en PageSpeed:

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

Obviamente, no hará ninguna mejora real, pero si su única preocupación es obtener un puntaje de 100/100, esto lo hará.

NiloVelez
fuente
44
Inteligente ... lástima que uso el almacenamiento en caché de borde porque este script solo funcionará si las solicitudes llegan a su origen para cada solicitud :(
Amy Neville
49
Cárguelo a través de JS entonces :)if(navigator.userAgent.indexOf("Speed Insights") == -1) { /* analytics here */ }
Medio loco
1
@Jim Vea stackoverflow.com/questions/10734968/… - usaría este método dentro del { }en mi ejemplo, junto con cualquier otro JS que GA use (como ga('create', 'UA-XXXXX-Y', 'auto'); ga('send', 'pageview');o lo que sea)
Half Crazed
1
@ Jim He agregado una respuesta que cubre esto.
Medio loco el
66
Advertencia: esto ya no funciona. Page Speed ​​Insights con tecnología de Lighthouse utiliza un UserAgent predeterminado, que ya no se puede detectar.
David Vielhuber
39

Hay un subconjunto de la biblioteca js de Google Analytics llamado ga-lite que puede almacenar en caché como quiera.

La biblioteca utiliza la API REST pública de Google Analytics para enviar los datos de seguimiento del usuario a Google. Puedes leer más en la publicación del blog sobre ga-lite .

Descargo de responsabilidad: soy el autor de esta biblioteca. Luché con este problema específico y el mejor resultado que encontré fue implementar esta solución.

jehna1
fuente
21

Aquí hay una solución realmente simple usando JS, para el seguimiento básico de GA, que también funcionará para cachés / proxies de borde (esto se convirtió de un comentario):

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

Nota: Esta es la secuencia de comandos GA predeterminada. Es posible que tenga otras ga()llamadas y, de ser así, deberá verificar siempre el agente de usuario antes de llamar ga(), de lo contrario, podría producirse un error.

Medio enloquecido
fuente
2
Al reaccionar a la sección "Nota:", puede declarar gacomo ga = function(){};antes que el fragmento falle silenciosamente cuando se ejecuta, ga();así no tiene que verificar la existencia de esta función en todas partes de su código.
István Pálinkás
1
Cómo agregar esto en el script <script async src = " googletagmanager.com/gtag/js?id=UA-xx6600xx-1 " > </… >
Navnish Bhardwaj el
16

Yo no me preocuparía por eso. No lo pongas en tu propio servidor, parece que este es un problema con Google, pero es tan bueno como se pone. Poner el archivo en su propio servidor creará muchos problemas nuevos.

Probablemente necesiten que se llame al archivo cada vez en lugar de obtenerlo del caché del cliente, ya que de esa manera no se contarían las visitas.

Si tiene un problema para sentirse bien con eso, ejecute la URL de Google Insights en Google Insights, ríase, relájese y continúe con su trabajo.

Leo Muller
fuente
68
Quiere saber cómo puede llegar a 100, no si 99 está bien.
Erick Engelhardt
44
Esta respuesta no es cierta, donde el archivo Analytics.js se descarga no afecta si las pistas analíticas o no. El problema de alojar su propio archivo de análisis es que siempre tiene que actualizar manualmente a la última versión (algunas veces al año).
Matthew Dolman
1
Gracias Matthew por señalar eso. Aparentemente me equivoqué, lo cual es bueno, pero aún así no creo que sea una buena idea alojar este archivo en su propio servidor porque puedo imaginar que creará muchos problemas nuevos. La pregunta OP fue cómo llegar al 100 en la velocidad de la página y mi respuesta es no preocuparme por llegar a ese 100. Esa puede ser una respuesta realmente molesta, pero ese soy yo.
Leo Muller
3
Una buena respuesta para las personas que se perdieron al pensar que 99 no es lo suficientemente buena. mejor dedica tu tiempo a problemas reales.
linqu
@ErickEngelhardt Tienes razón, pero si las personas hacen una pregunta donde crees que no están apuntando a la mejor meta, debes avisarles qué solución podría servirles mejor.
observador
10

En los documentos de Google, han identificado un pagespeedfiltro que cargará el script de forma asincrónica:

ModPagespeedEnableFilters make_google_analytics_async

Puede encontrar la documentación aquí: https://developers.google.com/speed/pagespeed/module/filter-make-google-analytics-async

Una cosa a destacar es que el filtro se considera de alto riesgo. De los documentos:

El filtro make_google_analytics_async es experimental y no ha tenido pruebas exhaustivas en el mundo real. Un caso en el que una reescritura causaría errores es si el filtro pierde llamadas a métodos de Google Analytics que devuelven valores. Si se encuentran dichos métodos, se omite la reescritura. Sin embargo, los métodos de descalificación se perderán si vienen antes de la carga, están en atributos como "onclick" o si están en recursos externos. Se espera que esos casos sean raros.

Cameron Scott
fuente
7

varvy.com ( información de velocidad de la página de Google 100/100 ) carga el código de Google Analitycs solo si el usuario hace un desplazamiento de la página:

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);
ar099968
fuente
77
¿Qué pasa si el visitante no se desplaza sino que simplemente hace clic en un enlace? No se lo contará en análisis.
Ross Ivantsiv
@RossIvantsiv puedes manejar también el clic!
ar099968
6

tienda localy analytics.js, pero google no lo recomienda: https://support.google.com/analytics/answer/1032389?hl=en

no se recomienda porque Google puede actualizar la secuencia de comandos cuando lo desee, así que solo haga una secuencia de comandos que descargue JavaScript de análisis cada semana y no tendrá problemas.

Por cierto, esta solución evita que adblock bloquee los scripts de google analytics

Froggiz
fuente
No omite Adblock por completo (todavía bloquea las llamadas ajax), pero al menos obtienes sesiones y visitas a la página
NiloVelez
5

Puede usar el proxy del script de Google Analytics a través de su propio servidor, guardarlo localmente y actualizar automáticamente el archivo cada hora para asegurarse de que siempre sea la última versión de Google.

He hecho esto en un par de sitios ahora y todo funciona bien.

Ruta del proxy de Google Analytics en NodeJS / MEAN Stack

Así es como lo implementé en mi blog que está construido con la pila 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étodo de acción de proxy de Google Analytics en ASP.NET MVC

Así es como lo implementé en otros sitios creados con 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);
        }
    }
}

Este es el atributo CompressAttribute utilizado por MVC ProxyController para la compresión 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 actualizado de Google Analytics

En el lado del cliente, agrego la ruta de análisis con la fecha actual hasta la hora para que el navegador no use una versión en caché de más de una hora de antigüedad.

<!-- 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>
Jason
fuente
4

PHP

Agregue esto en su código HTML o 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

Esto funciona bien con 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 ya dijo: Obviamente, no hará ninguna mejora real, pero si su única preocupación es obtener un puntaje de 100/100, lo hará.

Suriyaa
fuente
0

Google advierte contra el uso de copias locales de los scripts de análisis. Sin embargo, si lo está haciendo, probablemente quiera usar copias locales de los complementos y el script de depuración.

Una segunda preocupación con el almacenamiento en caché agresivo es que recibirá visitas de páginas en caché, que pueden haber cambiado o se han eliminado del sitio.

Oren Bochman
fuente
0

Para solucionar este problema, deberá descargar el archivo localmente y ejecutar un trabajo cron para seguir actualizando. Nota: esto no hace que su sitio web sea más rápido, por lo que es mejor ignorarlo.

Sin embargo, para fines de demostración, siga esta guía: http://diywpblog.com/leverage-browser-cache-optimize-google-analytics/

Mo Beigi
fuente
"Esto no hace que su sitio web sea más rápido", eso no es necesariamente cierto. Como en teoría, al comprimir un JS concatenado no crítico, un archivo con análisis incluido debería comprimirse un poco más pequeño que un archivo de análisis separado debido al diccionario compartido. Quizás más problemas de lo que vale.
Ray Foss
0

Esto puede hacer el truco :)

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

Dependiendo de su uso de los datos de Google Analytics, si desea información básica (como visitas, interacciones de UI), es posible que no pueda incluir analytics.js en absoluto, y aún así recopilar datos en GA.

Una opción puede ser usar el protocolo de medición en un script en caché. Google Analytics: Descripción general del protocolo de medición

Cuando establece el método de transporte explícitamente en imagen, puede ver cómo GA construye sus propias balizas de imagen.

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}

Puede crear sus propias solicitudes GET o POST con la carga útil requerida.

Sin embargo, si necesita un mayor nivel de detalle, probablemente no valdrá la pena.

Jonathan
fuente
¿Dónde está la conexión con Pagespeed?
Nico Haase
Al no cargar analytics.js, evita la penalización de velocidad de página.
Jonathan
Si. Y al omitir todo ese CSS, JS e imágenes de su página, se cargará aún más rápido. Saltarse Google Analytics no es una opción según el OP
Nico Haase
Excepto que los datos todavía se registran en Google Analytics, creo que mi respuesta es válida, y establecí claramente que, dependiendo del nivel de detalle requerido por Google Analytics, puede ser una opción que valga la pena considerar, lo que aún sería importante para registrar visitas, interacciones de UI y potencialmente otras métricas. . Si el OP está buscando optimizar para el 1% final, podría ser una optimización que vale la pena considerar.
Jonathan
@NicoHaase He editado mi comentario para poder aclarar mi punto. Interesado en oir tus pensamientos.
Jonathan
0

Puede configurar una distribución de Cloudfront que tenga www.google-analytics.com como su servidor de origen y establecer un encabezado de vencimiento más largo en la configuración de distribución de Cloudfront. Luego modifique ese dominio en el fragmento de Google. Esto evita la carga en su propio servidor y la necesidad de seguir actualizando el archivo en un trabajo cron.

Esto es configurar y olvidar. Por lo tanto, es posible que desee agregar una alerta de facturación a Cloudfront en caso de que alguien "copie" su fragmento y le robe el ancho de banda ;-)

Editar: lo intenté y no es tan fácil, Cloudfront pasa por el encabezado Cache-Control sin una forma fácil de eliminarlo

Jan M
fuente
0

Abra https://www.google-analytics.com/analytics.js archivo en una nueva pestaña, copie todo el código.

Ahora cree una carpeta en su directorio web, cámbiele el nombre a google-analytics.

Cree un archivo de texto en la misma carpeta y pegue todo el código que copió anteriormente.

Cambie el nombre del archivo ga-local.js

Ahora cambie la URL para llamar a su archivo de Script Analytics alojado localmente en su Código de Google Analytics. Se verá algo así, es decir https://domain.xyz/google-analytics/ga.js

Finalmente, coloque su NUEVO código de Google Analytics en el pie de página de su página web.

Tú eres bueno para irte. Ahora revise su sitio web de Google PageSpeed ​​Insights. No mostrará la advertencia para el apalancamiento del almacenamiento en caché de Google Analytics. Y el único problema con esta solución es actualizar periódicamente la secuencia de comandos Analytics.

Formal
fuente
0

En 2020, los agentes de usuario de Page Speed ​​Insights son: "Chrome-Lighthouse" para dispositivos móviles y "Google Page Speed ​​Insights" para computadoras de escritorio.

<?php if (!isset($_SERVER['HTTP_USER_AGENT']) || stripos($_SERVER['HTTP_USER_AGENT'], 'Chrome-Lighthouse') === false  || stripos($_SERVER['HTTP_USER_AGENT'], 'Google Page Speed Insights') === false): ?>
// your google analytics code and other external script you want to hide from PageSpeed Insights here
<?php endif; ?>
Eduard Dimitrov
fuente
-13

Puede minimizar todos sus scripts en la página, incluido el analytics.jsuso de:

Recuerde minimizar los archivos antes de usarlo. De lo contrario, consumirá más tiempo de procesamiento.

Erick Engelhardt
fuente
66
analytics.js ya está minimizado desde la fuente
João Pimentel Ferreira