Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

IIS 7 and JavaScript Compression not working consistently


:P
On this page:

IIS 7 has improved and simplified support for GZip encoding enabled out of the box and for the most part it seems to be working well on my Vista install. I see my CSS and other text content properly GZip encoded. IIS 7 also allows you to encode dynamic content easily which is nice because that was a real bitch to set up in IIS 6.

Compression is configured in IIS 7's ApplicationHost.config file (C:\Windows\System32\inetsrv\config\applicationhost.config) and there's a simple httpCompression section that seems to be pretty self explanatory. Here's what I have set up:

<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
    <dynamicTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="*/*" enabled="false" />
    </dynamicTypes>
    <staticTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="*/*" enabled="false" />
    </staticTypes>
</httpCompression>

and

<urlCompression  doStaticCompression="true" doDynamicCompression="false" />

I think doStaticCompression is the default and doesn't need to be set, although I couldn't get any JavaScript to compress until I added this (but other content did). doDynamicCompression needs to be explicitly enabled although frankly I'm not sure that I'd want that set on all dynamic content.

Notice that unlike IIS 6 where you would map application extensions, IIS 7 uses Mime Types which seems like a better solution for applying compression globally. httpCompression settings are ApplicationHost specific and can't be inherited in lower levels. urlCompression can be moved to child Webs/virtuals but it's disabled by default:

<section name="urlCompression" overrideModeDefault="Deny" />

JavaScript No Workey

As I mentioned static compression seems to work on any text documents (static htmltext, xml and css), but I'm getting no consistent love at all from static javascript content loaded from various applications. In requests to complex pages I see my CSS compressed but not all of my JavaScript is compressed.

For example, I'm using FCK Editor and have some ASP.NET code that loads up a the FCK Editor on a page with the JavaScript as static script src attributes loaded into the page. What's odd is that some .js content compresses but some other does not:

In fact none of the FCK subdirectory content is compressing which is odd.

Is it possible there's some sort of restriction for directory level depth that might be a problem here? File name conflicts?

I mentioned I had similar issues like this on IIS 6 with compression where nothing in APP_THEMES would compress. That thankfully works in IIS 7 now but this behavior I'm now seeing with FCK sure looks like a similar situation.

I ran into a somewhat cryptic message here that describes some of the inner details of the compression implementation. One of the things that's interesting is that IIS 7 will not cache any dynamic content that's compressed in the kernel cache, which means if the server has to recompress content. I'm not sure if this is a great solution to have based on generic content types. I think for situations like this it will be better to dynamically compress only when it's necessary rather than taking the hit of wholesale compression for every hit. In ASP.NET applications doing 'manual' Gzip compression is pretty easy as I showed in this post a while back.

For the moment though I would like to figure out WTF some content won't compress <s>. Anybody running Longhorn Server and seeing if this behavior is different?

Posted in ASP.NET  IIS  IIS  

The Voices of Reason


 

Josh Stodola
June 22, 2007

# re: IIS 7 and JavaScript Compression not working consistently

FCKEditor is already compressed, is it not? I know the source code package has all the "classes" split out by file and they are fully loaded with comments, but there is a utility called FCKPackager that combines all of this and compresses it into a single file (well, two files, one for IE and one for the rest). These "packaged" files are in the /editor/js folder. I thought it came compressed already, but I could be mistaken.

Rick Strahl
June 22, 2007

# re: IIS 7 and JavaScript Compression not working consistently

They're text compressed but not GZip compressed. They probably won't compress drastically but I'm pretty sure GZipping would reduce the file size still a bit more. This also applies only for the main script file - the startup and config files (which are smaller but still around 30k together are not packed in this way.

Anil Ruia
June 22, 2007

# re: IIS 7 and JavaScript Compression not working consistently

Rick, you should enable "failed request tracing" for all extensions for 200 responses and look for the STATIC_COMPRESSION_NOT_SUCCESS reason in the freb log - that will give some idea about why those files were not compressed.

Rick Strahl
June 24, 2007

# re: IIS 7 and JavaScript Compression not working consistently

Anil thanks for the pointer. So after hooking up for 'frebbing' I can see:

51. n n i STATIC_COMPRESSION_START 08:53:56.132
52. n n i STATIC_COMPRESSION_NOT_SUCCESS Reason="COMPRESS_FILE_NOT_FOUND" 08:53:56.132

which is odd. The file is being served so it's definitely there but for some odd reason it's not dealing with files in this path.

The actual path for the above request is:
http://rasvista:80/wconnect/fckEditor/editor/js/fckeditorcode_ie.js

But there's more weirdness. Now this editor loads up a ton of related test content. Some XML files, some CSS and Js files. Some of them compress some of them don't. So this doesn't for the same reason:

http://rasvista:80/wconnect/fckEditor/fckstyles.xml

but this does:

http://rasvista:80/wconnect/fckEditor/fckConfig.js

It seems like it's completely hit or miss.

So I experimented around a little bit by deleting the temporary compressed folder completely to see if what I'm seeing somehow has to do with files having been compressed at some point but then never having been re packed again.

Sure enough - I'm not seeing the compressed folder path being recreated. So now I'm wondering if there's something wrong with the settings but checking urlCompression is set to true and static compression is enabled for the various file types. What else is there to set?

<urlCompression doStaticCompression="true" />       


and

<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
    <dynamicTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="*/*" enabled="false" />
    </dynamicTypes>
    <staticTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="*/*" enabled="false" />
    </staticTypes>
</httpCompression>

Anil Ruia
June 28, 2007

# re: IIS 7 and JavaScript Compression not working consistently

Rick, we probably failed to create the compressed cache copy of the file - can you try to use procmon to see if you see any failure activity for files/directories inside the compression cache directory?
-Anil

Rick Strahl
June 28, 2007

# re: IIS 7 and JavaScript Compression not working consistently

I took a quick look and ProcMon also reports PATH NOT FOUND found on the path:

c:\inetpub\temporary compressed files\...\fckEditorCode_ie.js

when trying to do a CreateFile.

What is really, really strange is that there are about 5 compressable files in that directory. 2 compress 3 do not.

Looking at the sequence it looks like on the first hit nothing gets compressed the requests fail to find things in GZip cache and apparently don't build GZip content. On subsequent requests it looks that some files are built when the PATH NOT FOUND flag appears.

Now on the problem files that doesn't happen though. It just goes to PATH NOT FOUND and immediately goes on to reading the file from its original location with not attempt ever being tried at creating the GZIP content.

Dave
October 04, 2007

# re: IIS 7 and JavaScript Compression not working consistently

Just out of curiosity - how are you preventing compression to users of IE6? Google IE6 page Hangs Freezes if you want to see why you shouldn't compress for those browsers.

Jeff Atwood
October 19, 2007

# re: IIS 7 and JavaScript Compression not working consistently

Rick,

We're also seeing this same inconsistent compression behavior under IIS7 in Vista.

Sniffer shows some javascript resources compressed; others aren't.

Can Microsoft EVER release a version of IIS that works with compression? It's like a sick joke at this point. Broken out of the box in IIS 5, broken out of the box in IIS 6, and that fine tradition continues with IIS 7..

Jeff

Jeff Atwood
October 19, 2007

# re: IIS 7 and JavaScript Compression not working consistently

Aha. Looks like you need some more javascript content type variants, it is VERY literal about what it will match.

application/x-javascript
application/javascript
application/javascript; charset=utf-8

That helped us.

Sorry IIS7 team! You rock!

Rick Strahl
October 20, 2007

# re: IIS 7 and JavaScript Compression not working consistently

Jeff, not sure if that's the problem though in the code above. IIS is after all retrieving those documents and assigning the content-type. if it works for some files it should work for others.

I think the above adjustments you mention should only make a difference for dynamic results.

Jostein Kjønigsen
February 16, 2008

# re: IIS 7 and JavaScript Compression not working consistently

Well... I just deployed a fresh install of Windows Server 2008 and IIS7.

I had a few issues getting the old IIS6-setup migrated (httpHandlers should now evidently be in system.webServer not system.web) but nothing inhuman.

With everything up and running, I thought I'd verify that gzip-compression was working as it should. And what do I get? Nothing. Absolutely nothing! No compression for static content, and no compression for dynamic content either.

Following various guides to enable it for -everything- on the planet, I still have no http-compression what so ever. No Failed requests are logged either, so I have no possible way to debug this.

This actually works worse than in IIS6. I agree with Jeff here: This is turning into a joke.

Rick Strahl
February 16, 2008

# re: IIS 7 and JavaScript Compression not working consistently

Jostein - one thing I found is that content doesn't cache immediately. It needs to be hit and sometimes hit a few times before it compresses. It's almost as though IIS 7 schedules the compression of the content. If I've used content frequently I do now see everything getting GZipped, but it feels a little like black magic getting there nevertheless <g>...

Imad Jureidini
July 17, 2008

# re: IIS 7 and JavaScript Compression not working consistently

I've been running into the same issues. Ultimately, the solution was to change the following config setting:

<serverRuntime frequentHitThreshold="1" />

The default value here is "2", which means that even static content does not get compressed if it isn't requested twice within a 10 seconds period (frequentHitTimePeriod). Switching to "1" means that the file gets compressed right away.

Hopefully this will fix your problems too :)

- Imad

ChronoPositron
August 05, 2008

# re: IIS 7 and JavaScript Compression not working consistently

This may be a simple fix, but it worked for me. IIS 7 on my box (running Windows Server 2008) was serving up all javascript .js files as 'application/x-javascript'. Once I changed it to serve the javascript files as 'application/javascript' the compression kicked in and my files were sent compressed.

-- ChronoPositron

Gidon
November 17, 2008

# re: IIS 7 and JavaScript Compression not working consistently

Changing it to application/javascript also did it for me.


The weird thing is that I first tried to add application/x-javascript to the static compression list, but without results...

Yovav
February 18, 2009

# A Better HTTP Compression Solution

Nice article,

This can be frustrating, especially when dealing with IIS configuration on a live server,

Here is a better solution that works with JavaScript and also compatible and with AJAX enabled content - http://MicroMighty.com/Components/HTTP_Compression_Module.aspx

This HTTP Compression module also uses configureable MIME types and in addition it has some other features that are not being offered by any other http compression software, and the best thing about it is configured in the Web.config and not on IIS,

See how flexible it can be: http://MicroMighty.com/SDK/HTTPCompressionModule/HTTPCompressionModule.aspx

Alexander
April 29, 2009

# re: IIS 7 and JavaScript Compression not working consistently

I had same problem. Next title hapled me.
Getting IIS 7 to Compress JavaScript( http://www.coderjournal.com/2008/04/iis-7-compress-javascript-gzip/ )

ASP.NET Web Forms bloggers
August 14, 2010

# Performance tuning tricks for ASP.NET and IIS 7 – part 1

In this first installment of performance tuning tricks for ASP.NET and IIS 7 we will look at some of

Brian
August 25, 2010

# re: IIS 7 and JavaScript Compression not working consistently

<serverRuntime frequentHitThreshold="1" />

Fixed the problem for us as well, thanks for that tip. I hope this is logged as a bug somewhere, because the developer that built the logic around this flag made a critical process error. This flag is being evaluated continuously (wasting CPU IMO) without *FIRST* checking to see if the file in question has already been written to the compression cache. Once the file has been written it will always be cheaper to check the existence of that file and serve it, opposed to checking the existence of the source file and checking it's recent request history. What is happening is borderline files are flip-flopping between "frequent/infrequent" flag, and because of this they are being served at different compression ratios with different etags, which screws up 304 logic as well. This flaw is causing unnecessary compression events and extra full page returns. The flaw is exacerbated in a server farm of course. While setting the value to 1 bypasses the issue, it shouldn't be needed, especially considering it's a manual change to the application.config that is't reflected in the GUI to my knowledge.

Jesse
December 20, 2010

# re: IIS 7 and JavaScript Compression not working consistently

I'm with Brian: this is a poor approach, for a couple of (additional) reasons.

First, when an administrator configures IIS, s/he expects it to behave as configured. In this case, a bandwidth optimization has been configured, and IIS is choosing to ignore it if it doesn't think it meets certain caching requirements. (Not only won't a resource be compressed when first served, a resource that has been compressed will be served uncompressed if it hasn't been requested for some time. I haven't nailed it down, but it looks like the interval is something like 5 minutes, at least by default.) Caching and compression address different concerns and their configuration should be independent.

Second, documentation for this counter-intuitive behavior is very hard to find. This is partly because one typically wouldn't look at cache configuration to understand compression behavior, partly because the options aren't exposed in the GUI, and partly because there just isn't much documentation.

Anybody know how to file an IIS bug?

Anil Kasalanati
December 28, 2010

# Enabling Http caching and compression in IIS 7 for asp.net websites

v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML

AryeG
November 29, 2011

# re: IIS 7 and JavaScript Compression not working consistently

frequentHitThreshold and frequentHitTimePeriod.

By default these are set to 2 and 10 seconds. That means that if you take more than five seconds between runs you will not be statically compressed (although if you're like me you will see compression because it will default to dynamic compression). If you turn off dynamic compression of javascript files and download really fast you can see that the 2nd and later downloads are compressed (I used Fiddler for this). Even better, the cache seems to age out the files after the frequentHitTimePeriod is over, so you can get cached and then watch it disappear if you don't use it frequently.

I changed the settings in the applicationhost.config file to 1 and 1 hour. This means that it will compress and cache the very first time and won't age the file out of the cache for an hour (presumably it will reset that hour every time the file is hit).

Here are the commands I used (sorry for the line wrapping):

%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/serverRuntime /frequentHitThreshold:1
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/serverRuntime /frequentHitTimePeriod:01:00:00 /commit:apphost

As an added bonus, static compression seems to be about 20% better on javascript than dynamic compression.

Alex
May 28, 2019

# re: IIS 7 and JavaScript Compression not working consistently

Found this post in your StackOverflow answer, hope you don't mind me commenting on an old post.

It's 2019 out there and we're running on IIS 10 these days and STILL having problems compressing one (just one!) particular JS file. Everything is compressed normally, but this one file - just doesn't. Tried all suggestions from the comments (playing with frequentHitThreshold/frequentHitTimePeriod, adding "charset utf-8" to content-type, changing content-type from application/javascript to text/javascript).

The only thing that worked was enabling dynamic content compression. Somehow IIS considers this ONE file dynamic. Weird.


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024