GZIP is a generic compression method that can be applied to any stream of bits. In terms of how it’s used on the web, it’s easiest thought of a way that makes your files “smaller”. When applying GZIP compression to text files, you can see anywhere from 70-90% savings, on images or other files that are usually already “compressed”, savings are much smaller or in some cases nothing. Other than eliminating unnecessary resource downloads, enabling compression is the next best way to improve the loading speed of your web app.

Enabling At The Code Level (Dynamic)

You can dynamically GZIP text resources on request. This is great for content that may change (Think dynamic html, text, not JS, CSS). The reason it’s not great for static content such as CSS or JS, is that those files will not change between requests, or really even between deployments. There is no advantage to dynamically compressing these each time they are requested.

The code you need to make this work is contained in a nuget package. So you will need to run the following from your package manager console.

In your ConfigureServices method in your startup.cs, you need to add a single line to add the dependencies that GZIP compression is going to need.

Note that there are a couple of options you may wish to use in this call.

The EnableForHttps flag does exactly what it says. It enables GZip compression even over SSL (By default this is switched off). The second turns on (Or off in some cases) GZip of certain mimetypes. The default list at the time of writing is the following (Taken from the Github source here) :

Then in your configure method of startup.cs, you then just need a single line to get going.

Note that the order is very important! While in this case we only have two pieces of middleware that don’t cause issues, other middleware (such as the Static Content middleware), actually send the response back to the user before GZip has occured if it’s first in the list. For safety sake, just keep UseResponseCompression as the first middleware in your list.

To test you have everything up and running just fine, try loading your site and watching the requests go past. You should see the Content-Encoding header come back as “Gzip”. In Chrome it looks like the following :

Enabling At The Code Level (Static)

The issue with enabling GZip compression inside .net core is that if your content is largely static (As in it doesn’t change), then it’s being re-compressed over and over again. When it comes to javascript and CSS, there is really no reason for this to be done on the fly. Instead we can GZip these files beforehand and deploy them “pre” GZip’d.

For this you will need to use a task runner such as Gulp to GZIP your static files in your pipeline. There is a very simple gulp package for this named “gulp-gzip”. Have a search around and get used to how it works. But your gulp file should look something similar to the following :

This is a very simple case, you will need to know a bit more about Gulp to customize it to your needs.

However importantly, you need to map Gzip files to actually return their real result. First install the static file middleware. Run the following from your Package Manager console.

Now in your Configure method in startup.cs, you need to add some code like so :

What does this do? Well first it says that serving static files without running the MVC gamut is A-OK. But next it says, if you come across a file that ends in .js.gz, you can send it out, but instead tell the browser that it’s actually javascript and that it’s just been encoded with gzip. Otherwise it just returns the file as a plain old GZip file that a user could download for example.

Next on your webpage, you actually need to be referencing the .gz file not the .js file. So it should look something like so :

And that’s it, your static content is now compressed!

Enabling At The Server Level

And lastly, you can of course always enable GZip compression at the web server level (IIS, NGinx, Apache etc). For this it’s better to consult the relevant documentation. You may wish to do this as it keeps the configuration out of code (And allows a bit more easier access for configuration on the fly).

Attempting to install a nuget package the other day I got the following error :

Package ‘xyz’ uses features that are not supported by the current version of NuGet. To upgrade NuGet, see http://docs.nuget.org/consume/installing-nuget.

Following the link takes you to this page. Because I am using the inbuild package manager console from Visual Studio, I followed the steps inside VS that say to go Tools > Extensions and Updates and then click the Updates tab to see if I had an update waiting.

I didn’t. Still stuck. Damn.

After a bit of searching I came across this page that has the Visual Studio extensions to be downloaded manually and installed. After downloading the package and installing manually, with a quick restart of visual studio we are up and running on the latest version of Nuget!

If you are unsure if you are on the latest version of Nuget, you can type “nuget help” in your package manager console and it will tell you the version.

If you’re using Gulp across many projects (especially across many open source ones), you may come across errors that look similar to the following :

The issue is caused by having a local gulp install for your project and one installed globally. You can check this by running the command “gulp -v” from a command line. You should see something similar to :

How to fix it? Well first it’s maybe better to understand why this is the case. Why do we have a “local” version of gulp and a global version installed?

The local version is there because it ensures that gulp runs the same on any machine the code is run on. Including your build server or other development machines. Ensuring that the same version is run everywhere is a great way to ensure consistency.

The global version is there because it allows you to type “Gulp” from the command line essentially. Having the executable in your system path is very handy.

The Sledgehammer Fix

I call this the sledgehammer fix because it’s really just brutalizing a solution that happens to work. This fix is to simply update both your CLI and Local Gulp to the same version. You can do this by going into your web project in a command prompt and calling :

Warning. If for any reason your local version or global version was on a specific version of gulp, then you’ve just massacred it. If you’re working in a team you should ask before you do this or be prepared to lose friends in the workplace. Of course, if you’re a one man band and you haven’t picked a version of gulp for any particular reason, then this will work just fine.

The “Slightly More Elegant” Fix

The second fix does take a while of getting used to. Inside your package.json file you can add the following :

You can now run the local installed version of gulp (Without calling the global version), by typing “npm run gulp” from a command line inside your web project. It does take some getting used to if you’ve always just typed straight “gulp” from the command line.

What this does mean is that passing in various options and flags for gulp gets a bit gnarly. You usually end up with something more like the following :

Essentially spelling out all your different options for gulp (Including watches etc) within your scripts section.

The “Elegant” Fix

A more elegant fix is actually by removing gulp entirely from your globals and installing only the CLI. Run the following

This first command removes gulp globally (But not from local installs such as in your web project). The second command installs Gulp-CLI. The CLI is the command line interface for gulp and is the minimum amount to run gulp from the command line, but not actually have any of it’s “working parts” if you will globally. This is great because as above, we learned that the only reason we really have gulp globally is for the command line, not for any working parts. This solves our issue perfectly!