Nerd alert: This post is only for crazy website performance freaks. Proceed at your own risk.

The holy grail for us crazy website performance freaks is to reach a perfect score of 100/100 in Google Page Speed without sacrificing important features of the website we’re building. One of those important features is Google Analytics. Gotta have Google Analytics, right?!

Let’s say that you’ve optimized your website to the perfect score of 100/100 and now decide to add Google Analytics. Too bad, your score is now 98/100. That’s because the ga.js JavaScript file loaded from Google’s servers doesn’t have a far-future expires HTTP header. To get the perfect score back, we need to fix this problem.

Getting back to 100/100

Here’s a solution that I use on one of my websites. It involves the addition of a single .ashx file to your web project. It’s isolated, safe to use and works.

The role of the .ashx file is to act as a proxy to the Google Analytics ga.js script file by downloading its content and serving it with a sufficient expires header. It caches the script file on the server, so it doesn’t have to download the ga.js file every time a visitor hits your website.

Step 1: Add an empty .ashx file (Generic Handler) to the root of you project and call it ga.ashx.

Step 2: Copy this code into the .ashx file you created in step 1.

Step 3: Modify the Google Analytics tracking script on your page to look like this:

    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-12345678-9']);

<script src="/ga.ashx" async="async" defer="defer"></script>

Voila! That’s it. You now have the perfect score back.

Optional step 4: Don’t like the .ashx extension? Then change it to .js by adding this to the web.config:

    <rule name="analytics">
      <match url="^ga.js" />
      <action type="Rewrite" url="ga.ashx" />

You need to add it to the <system.webServer> section of web.config. Remember to run the AppPool in Integrated Pipeline Mode for the <system.webServer> section to kick in.

Then just change the script tag to this:

<script src="/ga.js" async="async" defer="defer"></script>

Wait, is this a good idea?

I’ll let you be the judge of that. What I can tell you is that this exact code is running on one of my websites and it reports data to Google Analytics just fine.

Does it work? Yes
Is it cool? Totally
Should I do it? N/A


imageIn the beginning of January, we released the Web Developer Checklist with great interest from the general web community. The checklist helps raising awareness of common best practices for building websites.

It was always the plan to branch the checklist out into technology specific checklists to make it even easier to apply all the best practices.

Today we’re excited to announce the first technology specific checklist – the ASP.NET Developer Checklist. It contains links to many ASP.NET specific tools and solutions to common problems.

Not only is it a great tool for all ASP.NET developers to learn from, but also to track the progress of implementing the various best practices.

We hope it will be received well and add value to the millions of ASP.NET developers worldwide. In the meantime we will be working on finishing another ASP.NET specific checklist that focuses on website performance.

ASP.NET is just the first of many web technologies to receive its own checklist, so remember to check the Web Developer Checklist often for updates.


Rule #1 in website optimization is to enable GZip compression on the web server. This is very easy using web.config as explained here. However, some web servers have disabled automatic compression of JavaScript files, because they are served with the content type: application/x-javascript.

For these web servers we can use a web.config trick to change the content type of JavaScript files to text/javascript. This is a completely valid content type supported by all browsers.

Just paste the following XML snippet in to your web.config’s <system.webServer> section.

  <remove fileExtension=".js"/>
  <mimeMap fileExtension=".js" mimeType="text/javascript" />

Chances are that you don’t have this issue, since it seems to only apply to some hosters, but now you know how to get around it should you ever end up in the situation with uncompressed JavaScript files.


imageSo you just built a website and are about to make it public to the world. You go through a few checks to make sure that everything works as expected. Perhaps run HTML validation and other similar services.

But are you sure you remembered to implement all the best practices? Does it look good on mobile devices, in Windows 8 snapped view and what about basic accessibility?

Enter Web Developer Checklist

We’ve tried to come up with the complete list of tasks and checks that every web developer should go through when developing any kind of website. The Web Developer Checklist is structured in a way that makes it really easy to follow the progress as well as getting help to perform all the checks.

Give it a try and let me know what you think.


Many Web Essentials users have requested a more formal process around nightly builds, that should result in a better delivery and update mechanism. To make it really easy to always run the latest and greatest, I’ve now created a custom feed for the Extensions and Updates dialog in Visual Studio 2012.

Here’s how it works:

Go to Tools > Options and open the the tab located under Environment –> Extensions and Updates.


Click the Add button and type “Web Essentials Nightly” in the Name field and “http://vswebessentials.com/nightly/feed.ashx” in the URL field. Now click the Apply button and you’re all set. Now click the OK button to exit the Options dialog.

Now the custom feed shows up in the Extensions dialog. Go to Tools > Extensions and Updates… to verify that the new feed is working. You should have a new sub category under the Online tab called “Web Essentials Nightly”.


The Nightly build shares the same extension ID as the official released versions of Web Essentials, so the newest one will always override the one installed – regardless if it’s the nightly build or the official version. And updates will work normally.

In other words, it should be perfectly safe to use this custom feed without any changes to how the update mechanism works from the user’s point of view. Only difference is that with this new feed, you can get the updates much faster than before.

Give it a try and let me know what you think.