PageSpeed Insights 99/100 because of Google Analytics - How can I cache GA?

前端 未结 20 1673
無奈伤痛
無奈伤痛 2020-11-29 15:10

I\'m on a quest to reach 100/100 on PageSpeed and i\'m almost there. I\'m trying to find a good solution to cache Google Analytics.

Here is the message I get:

20条回答
  •  無奈伤痛
    2020-11-29 15:30

    You can proxy the google analytics script via your own server, save it locally and auto update the file every hour to make sure it's always latest version from google.

    I've done this on a couple of sites now and all is working fine.

    Google Analytics Proxy Route in NodeJS / MEAN Stack

    This is how I implemented it on my blog that's built with the MEAN stack.

    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 Action Method in ASP.NET MVC

    This is how I implemented it on other sites built with 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);
            }
        }
    }
    

    This is the CompressAttribute used by the MVC ProxyController for Gzip compression

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

    Updated Google Analytics Script

    On the client side I append the analytics path with the current date up to the hour so the browser won't use a cached version more than an hour old.

    
    
    

提交回复
热议问题