我正在追求达到100/100的PageSpeed,我几乎在那里。我试图找到一个很好的解决方案来缓存谷歌分析。

这是我得到的信息:

利用浏览器缓存 在静态资源的HTTP报头中设置过期日期或最大年龄指示浏览器从本地磁盘加载以前下载的资源,而不是通过网络。 利用浏览器缓存以下可缓存资源: http://www.google-analytics.com/analytics.js(2小时)

我找到的唯一解决方案是2012年的,我不认为这是一个好的解决方案。本质上,您复制GA代码并自己托管它。然后运行cron作业,每天重新检查谷歌一次,以获取最新的GA代码并替换它。

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

我还能做什么来达到100/100,同时也使用谷歌分析?

谢谢你!


当前回答

您可以通过自己的服务器代理谷歌分析脚本,将其保存在本地,并每小时自动更新文件,以确保它始终是谷歌的最新版本。

我已经在几个网站上做了这个,现在一切都很好。

谷歌NodeJS / MEAN Stack中的分析代理路由

这就是我如何在我的博客上实现它,它是用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);
    }
});

谷歌分析代理动作方法在ASP。NET MVC

这就是我如何在其他用ASP构建的网站上实现它的。净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);
        }
    }
}

这是MVC ProxyController用于Gzip压缩的CompressAttribute

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

更新谷歌分析脚本

在客户端,我将分析路径与当前日期附加到小时,这样浏览器就不会使用超过一小时前的缓存版本。

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

其他回答

我不会担心的。不要把它放在你自己的服务器上,听起来这是谷歌的一个问题,但它得到的很好。将文件放在您自己的服务器上将产生许多新问题。

他们可能需要每次都调用该文件,而不是从客户端的缓存中获取,因为这样就不会计算访问次数。

如果你觉得有问题,可以在谷歌insights上运行谷歌insights URL,笑一笑,放松一下,继续你的工作。

谷歌Analytics js库中有一个名为ga-lite的子集,你可以根据自己的需要进行缓存。

该库使用谷歌Analytics的公共REST API将用户跟踪数据发送到谷歌。你可以从博客文章中读到更多关于ga-lite的信息。

声明:我是这个库的作者。我为这个特定的问题而挣扎,我发现最好的结果就是实现这个解决方案。

存储local analysis .js,但谷歌不建议这样做: https://support.google.com/analytics/answer/1032389?hl=en

不建议,因为谷歌可以在他们想要的时候更新脚本,所以只要做一个脚本,每周下载分析javascript,你就不会有麻烦!

顺便说一下,这个解决方案防止adblock从阻塞谷歌分析脚本

要修复此问题,您必须在本地下载文件并运行cron作业以保持更新。注意:这不会让你的网站更快,所以最好忽略它。

但是,为了演示目的,请遵循以下指南: http://diywpblog.com/leverage-browser-cache-optimize-google-analytics/

您可以通过自己的服务器代理谷歌分析脚本,将其保存在本地,并每小时自动更新文件,以确保它始终是谷歌的最新版本。

我已经在几个网站上做了这个,现在一切都很好。

谷歌NodeJS / MEAN Stack中的分析代理路由

这就是我如何在我的博客上实现它,它是用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);
    }
});

谷歌分析代理动作方法在ASP。NET MVC

这就是我如何在其他用ASP构建的网站上实现它的。净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);
        }
    }
}

这是MVC ProxyController用于Gzip压缩的CompressAttribute

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

更新谷歌分析脚本

在客户端,我将分析路径与当前日期附加到小时,这样浏览器就不会使用超过一小时前的缓存版本。

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