Leverage browser caching for Google Analytics (.js)

GoogleAnalytics IIS

As many may know about tools like Google's PageSpeed Insights or Pingdom Website Speed Test, almost as many know about Google Analytics and how it prevents users from getting a score of 100 on these tests. Even though this might be frustrating it doesn’t mean your site will be slow because of Google Analytics as the script will most likely be cached from a visit on another website, so technically there is nothing to “fix”.

GoogleAnalytics SpeedTest

But if you still want to get that score of 100 or just want to see how it is possible to do that there are solutions for this. All solutions might not be good or optimal, but they solve the “problem”.

Creating a reverse proxy

My personal favorite of these solutions is to add the Google Analytics script behind a reverse proxy on your server and modify the caching headers. This will allow you to serve the Google Analytics script from your server and with your caching rules at the same time you keep the script automatically updated.

This solution might differ depending on your hosting environment, but I will show you how to set this up on a site hosted on IIS.

First you need to have Url Rewrite and Application Request Routing installed for your IIS, both can be found and installed through the Web Platform Installer in IIS.

The next step is to set up the reverse proxy rule in your web.config for Google Analytics. This will allow you to access the .js through a local path like “/google/analytics.js”.

<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Google Analytics" patternSyntax="ExactMatch" stopProcessing="true">
                    <match url="google/analytics.js" />
                    <action type="Rewrite" url="https://www.google-analytics.com/analytics.js" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

If you modify your page to load Google Analytics from the new URL, you will still get an error for caching on .js. What you must do here is to modify the headers of the .js loaded through your reverse proxy.

The header you will have to modify is Cache-Control and remove the header Expires. Why you have to remove the Expires header is that it is a set date, and not a number for how long it can be cached in seconds like in Cache-Control. Of course this depends on your solution, but some reverse proxies are limited when it comes to working with dates.

The configuration below sets the Cache-Control to 7 days, in seconds, (which seem to be the lowest acceptable by the tools) instead of the default 2 hours.

<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Google Analytics" patternSyntax="ExactMatch" stopProcessing="true">
                    <match url="google/analytics.js" />
                    <action type="Rewrite" url="https://www.google-analytics.com/analytics.js" />
                </rule>
            </rules>
            <outboundRules>
                <rule name="GoogleAnalytics - Expires">
                    <match serverVariable="RESPONSE_Expires" pattern="^.*" />
                    <action type="Rewrite" value="" />
                    <conditions>
                        <add input="{REQUEST_URI}" pattern="google/analytics.js" />
                    </conditions>
                </rule>
                <rule name="GoogleAnalytics - Cache-Control">
                    <match serverVariable="RESPONSE_Cache-Control" pattern="^.*" />
                    <action type="Rewrite" value="public, max-age=604800" />
                    <conditions>
                        <add input="{REQUEST_URI}" pattern="google/analytics.js" />
                    </conditions>
                </rule>
            </outboundRules>
        </rewrite>
    </system.webServer>
</configuration>

After this you need to add "Expires" and "Cache-Control" to the server variables in the URL Rewrite GUI in the IIS Manager. If you run the PageSpeed Insights test again, you should now get a better result as the image below.

GoogleAnalytics SpeedTest 100

Alternatives

If the reverse proxy solution does not work for you, there are other solutions like the two examples below.

Download a local copy of ga.js and serve it from your server, together with a script to download maybe once or twice a day as the script needs to be kept updated in case of any changes.

Add the code for Google Analytics behind an if-statement to check for the User-Agent of PageSpeed Insights, and ignore to add the script if this statement is true. User-Agent (as of writing): Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko; Google Page Speed Insights) Chrome/27.0.1453 Safari/537.36

Final word

As there is no really need to implement a solution for this “problem” I see no need to encourage you to do so, but if you are like me and just want to learn how to do things (like getting a score of 100) the above solutions might help you on your way.