PageSpeed ​​Insights 99/100 из-за Google Analytics - Как я могу кешировать GA?

Я стремлюсь достичь 100/100 на PageSpeed, и я почти на месте. Я пытаюсь найти хорошее решение для кеширования Google Analytics.

Вот сообщение, которое я получаю:

Использование кэширования в браузере Установка даты истечения срока действия или максимального срока действия в заголовках HTTP для статических ресурсов заставляет браузер загружать ранее загруженные ресурсы с локального диска, а не по сети. Используйте кэширование в браузере для следующих кэшируемых ресурсов: http://www.google-analytics.com/analytics.js (2 часа)

Единственное решение, которое я нашел, было с 2012 года, и я не думаю, что это хорошее решение. По сути, вы копируете код GA и размещаете его самостоятельно. Затем вы запускаете задание cron для повторной проверки Google один раз в день, чтобы получить последний код GA и заменить его.

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

Что еще я могу сделать, чтобы достичь 100/100, используя Google Analytics?

Спасибо.

19 ответов

Решение

Ну, если Google изменяет вам, вы можете обмануть Google назад:

Это пользовательский агент для 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”

Вы можете вставить условие, чтобы избежать предоставления сценария аналитики PageSpeed:

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

Очевидно, что никаких реальных улучшений это не принесет, но если ваша единственная задача - набрать 100/100 баллов, это сработает.

Существует подмножество js-библиотеки Google Analytics под названием ga-lite, которое вы можете кэшировать по своему усмотрению.

Библиотека использует открытый REST API Google Analytics для отправки данных отслеживания пользователей в Google. Вы можете прочитать больше в блоге о ga-lite.

Отказ от ответственности: я являюсь автором этой библиотеки. Я боролся с этой конкретной проблемой, и лучший результат, который я нашел, заключался в реализации этого решения.

Вот действительно простое решение, использующее JS для базового отслеживания GA, которое также будет работать для краевых кэшей / прокси (это было преобразовано из комментария):

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

Примечание. Это скрипт GA по умолчанию. Вы можете иметь другие ga() звонки, и если так, вам нужно будет всегда проверять пользовательский агент перед вызовом ga()в противном случае может произойти ошибка.

Я бы не беспокоился об этом. Не размещайте его на своем собственном сервере, похоже, что это проблема с Google, но она хороша. Размещение файла на вашем собственном сервере создаст много новых проблем.

Они, вероятно, нуждаются в том, чтобы файл вызывался каждый раз вместо того, чтобы получать его из кэша клиента, поскольку таким образом вы не будете считать посещения.

Если у вас возникли проблемы с этим, запустите URL-адрес Google Insights на самой странице Google Insights, посмейтесь, расслабьтесь и продолжайте свою работу.

В документах Google они определили pagespeed фильтр, который будет загружать скрипт асинхронно:

ModPagespeedEnableFilters make_google_analytics_async

Вы можете найти документацию здесь: https://developers.google.com/speed/pagespeed/module/filter-make-google-analytics-async

Одна вещь, на которую стоит обратить внимание, это то, что фильтр считается высоким риском. Из документов:

Фильтр make_google_analytics_async является экспериментальным и не подвергался обширным испытаниям в реальных условиях. Один случай, когда перезапись может привести к ошибкам, - это то, что фильтр пропускает вызовы методов Google Analytics, которые возвращают значения. Если такие методы найдены, перезапись пропускается. Однако методы дисквалификации будут пропущены, если они предшествуют загрузке, имеют такие атрибуты, как "onclick", или если они находятся во внешних ресурсах. Эти случаи, как ожидается, будут редкими.

Храните localy analytics.js, но это не рекомендуется Google: https://support.google.com/analytics/answer/1032389?hl=en

это не рекомендуется, потому что Google может обновлять сценарии, когда они хотят, так что просто сделайте сценарий, который загружает аналитический javascript каждую неделю, и у вас не будет проблем!

Кстати, это решение предотвращает блокировку скриптов Google Analytics рекламным блоком.

Вы можете попробовать разместить analytics.js локально и обновить его содержимое с помощью сценария кэширования или вручную.

Файл js обновляется только несколько раз в год, и если вам не нужны какие-либо новые функции отслеживания, обновите его вручную.

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

varvy.com ( 100/100 Google page speed speed) загружает код Google Analitycs, только если пользователь прокручивает страницу:

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

Вы можете использовать прокси-скрипт Google Analytics через собственный сервер, сохранять его локально и автоматически обновлять файл каждый час, чтобы всегда быть последней версией от Google.

Я сделал это на нескольких сайтах сейчас, и все работает нормально.

Маршрут прокси-сервера Google Analytics в стеке NodeJS / MEAN

Вот как я реализовал это в своем блоге, который построен со стеком 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);
    }
});

Метод действия Google Analytics Proxy в ASP.NET MVC

Так я реализовал это на других сайтах, созданных с помощью 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);
        }
    }
}

Это CompressAttribute, используемый MVC ProxyController для сжатия 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);
        }
    }
}

Обновлен скрипт Google Analytics

На стороне клиента я добавляю путь аналитики с текущей датой до часа, чтобы браузер не использовал кэшированную версию более часа назад.

<!-- 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>

Для 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";
    }

Затем измените путь https://www.google-analytics.com/analytics.js на https://yoursite.com/analytics.js

PHP

Добавьте это в ваш код HTML или 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

Это прекрасно работает с 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 уже сказал: " Очевидно, что никаких реальных улучшений не произойдет, но если ваша единственная задача - набрать 100/100 баллов, это сработает".

Чтобы решить эту проблему, вам нужно будет загрузить файл локально и запустить задание cron, чтобы продолжить обновление. Примечание: это не делает ваш сайт быстрее, поэтому лучше просто игнорировать его.

Однако в демонстрационных целях следуйте этому руководству: http://diywpblog.com/leverage-browser-cache-optimize-google-analytics/

В 2020 Page Speed ​​Insights пользовательскими агентами являются: "Chrome-Lighthouse" для мобильных устройств и "Google Page Speed ​​Insights" для настольных компьютеров.

<?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; ?>

Попробуйте это просто вставить, прежде чем

<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>

Пожалуйста, измените xx-xxxxxxx-x на ваш код, пожалуйста, проверьте реализацию здесь http://www.gee.web.id/2016/11/how-to-leverage-browser-caching-for-google-analitycs.html

Google предостерегает от использования локальных копий сценариев аналитики. Однако, если вы делаете это, вы, вероятно, захотите использовать локальные копии плагинов и сценарий отладки.

Вторая проблема, связанная с агрессивным кэшированием, заключается в том, что вы будете получать хиты с кэшированных страниц, которые могли быть изменены или удалены с сайта.

Откройте файл https://www.google-analytics.com/analytics.js на новой вкладке, скопируйте весь код.

Теперь создайте папку в своем веб-каталоге, переименуйте ее в google-analytics.

Создайте текстовый файл в той же папке и вставьте весь код, который вы скопировали выше.

Переименуйте файл ga-local.js

Теперь измените URL-адрес, чтобы вызывать локально размещенный файл сценария Analytics в вашем коде Google Analytics. Это будет выглядеть примерно так: https://domain.xyz/google-analytics/ga.js

Наконец, поместите НОВЫЙ код Google Analytics в нижний колонтитул вашей веб-страницы.

Тебе хорошо идти. Теперь проверьте ваш сайт Google PageSpeed ​​Insights. Это не будет отображать предупреждение для использования кэширования браузера Google Analytics. И единственная проблема, связанная с этим решением, заключается в регулярном обновлении сценария Analytics вручную.

Это может сделать свое дело:)

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

Вы можете настроить дистрибутив облачного фронта, который имеет www.google-analytics.com в качестве исходного сервера, и установить более длинный заголовок срока действия в настройках дистрибутива облачного фронта. Затем измените этот домен в фрагменте Google. Это предотвращает загрузку на вашем собственном сервере и необходимость постоянно обновлять файл в задании cron.

Это настройка и забудьте. Так что вы можете добавить уведомление об оплате в cloudfront на случай, если кто-то "скопирует" ваш фрагмент кода и украдет вашу пропускную способность;-)

Изменить: я попробовал, и это не так просто, Cloudfront проходит через заголовок Cache-Control без простого способа удалить его

В зависимости от того, как вы используете данные Google Analytics, если вам нужна базовая информация (например, посещения, взаимодействия с пользовательским интерфейсом), вы можете вообще не включать analytics.js, но все же собирать данные в GA.

Один из вариантов может заключаться в том, чтобы вместо этого использовать протокол измерений в кэшированном сценарии. Google Analytics: обзор протокола измерений

Когда вы явно зададите метод транспорта для изображения, вы можете увидеть, как GA создает собственные маяки изображений.

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}

Вы можете создавать свои собственные запросы GET или POST с необходимой полезной нагрузкой.

Однако, если вам требуется более высокий уровень детализации, это, вероятно, не будет стоить ваших усилий.

Вы можете минимизировать все свои скрипты на странице, включая analytics.js с помощью:

Не забудьте минимизировать файлы перед использованием. В противном случае это займет больше времени на обработку.

Другие вопросы по тегам