About the author

Miron Abramson
Me
Software Engineer,
CTO at PixeliT
and .NET addicted for long time.
Open source projects:
MbCompression - Compression library

Recent comments

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2017

Creative Commons License

Blog Flux Directory
Technology Blogs - Blog Top Sites

Compress your pages, css, js and WebResources.axd files for better performance

(See updated post:  New & Shiny WebResource.axd compression Module

This post is an update for my previews post about http compression. In that post, I posted a http module that compress aspx pages and WebResource.axd files.
Thanks to Mads Kristensen, that found a performance issue in my code and had a solution for that, I improved my compressor component and also I included a complete project to compress asp.net pages, CSS files, JavaScript files and WebResource.axd files as well. The implementation in really very simple and not lot of changes are necessary in existing project. The page compression is very simple, and common to all http compressors:
 Registering the httpmodule in the web.config:

<add name="HttpCompressionModule" type="Miron.HttpHandlersAndModules.HttpCompressionModule"/>

and the compression itself in the httpmodule: 

HttpApplication app = sender as HttpApplication; 

// Check if GZIP is supported by the client

if (IsGzipEncodingSupported())
{
    app.Response.Filter = new GZipStream(app.Response.Filter, CompressionMode.Compress);

    SetEncodingType(GZIP);   // Set the response encoding type header
}
// Check if DEFLATE is supported by the client
else if (IsDeflateEncodingSupported())
{
    app.Response.Filter = new DeflateStream(app.Response.Filter, CompressionMode.Compress);

    SetEncodingType(DEFLATE);  // Set the response encoding type header
}

The WebResource.axd compression is a bit more complicate, but the idea is to make a 'fake' request based on the requested url when the client asked for WebResource.axd file, get the response into byte[], compress it into MemoryStream cache it as a byte[] and send it to the client. The next time the client ask for this WebResource, it served from the cache (thanks again to Mads Kirstensen). The compression is only when the WebResource serve css or javascript files. over wise, the WebResource is send to the client 'as it'.   The CSS and the JS files compression is similar to the page compression, the differents  are that in those cases, we load the requested file, read it into string, manipulate it  (remove unneeded spaces and stuff), compress it, cache it, and send it to the client. The 'problem' is that css and js files are served by the IIS itself, and not by ASP.NET engine, so what we do is, changing the 'src' attribute for js files to jslib.axd or the 'href' attribute for css files to css.axd, and add as query string the real files name (see in the ReadMe.txt file how it done), and those files are handled by ASP.NET engine and to compress tham - for that, we register the following handlers in the web.config: (another option, is to serve those files via WebResources)

<add verb="*" path="jslib.axd" type="Miron.HttpHandlersAndModules.JavaScriptHandler" validate="false"/>

<add verb="*" path="css.axd" type="Miron.HttpHandlersAndModules.CssCompressionHandler" validate="false"/>

The caching for those files have CacheDependency on the files, so the content is removed from the cache in the moment the files are changed, and reload again when requested. Before sending data to the client, we check the ETag, and if its the same as the client sent, so we can stop the response and send only the code 304. 

Extra features

By configuration in the web.config, it is possible to disable any compression type, decide the time (by days) the cached file will be in the cache, and also it is possible to specified mimeTypes content to not compress or specified aspx files to exclude from the compression.  All configuration description in the ReadMe.txt file. 

 Implementation 

All implementation instructions are in the attach zip file in ReadMe.txt file.

Note

The WebResource compression may not work if the request is url that modified in the windows 'host' file. In that case, you will need to disable WebResource compression (See in the  ReadMe.txt)

  (See update post with new & better code: New & Shiny WebResource.axd compression Module)

Latest code can be downloaded from:

http://www.codeplex.com/MbCompression

Currently rated 3.9 by 14 people

  • Currently 3.928571/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by Miron on Monday, September 24, 2007 8:17 AM
Permalink | Comments (17) | Post RSSRSS comment feed

Related posts

Comments

Joao pt

Tuesday, March 25, 2008 1:42 AM

Joao

Why is there an exception for IE6 browser?

Miron il

Tuesday, March 25, 2008 2:10 PM

Miron

Hey Joao,
IE6 have a well known problem with compression that described here:
http://support.microsoft.com/kb/312496
Still there are lots of users that using IE6, so, better for them to get not compressed data then corrupted data...
If you are interesting in the compression module, I suggest you to read the updated post:
mironabramson.com/.../...d-compression-Module.aspx

John Dillon gb

Wednesday, April 30, 2008 7:12 AM

John Dillon

Fantastic work thanks you very much for sharing this. One small issue I get is that I get an error when I set comPressPage=true?

Here are the settings: <CompressorSettings reflectionAlloweded="true" optimizeHtml="true" daysInCahe="1" compressCSS="true" compressJavaScript="true" compressPage="true" compressWebResource="true" compressThirdParityScripts="true">

Here is the error:

'/Telerik.Web.UI.WebResource.axd?_TSM_HiddenField_=ctl00_RadScriptManager1_HiddenField&amp;_TSM_CombinedScripts_=%3b%3bTelerik.Web.UI%2c+Version%3d2008.1.416.35%2c+Culture%3dneutral%2c+PublicKeyToken%3d121fae78165ba3d4%3aen-US%3a2b085cdb-b44c-4804-80d3-9ac9bd7a0568%3a393f5085%3a9703c1f0%3aa3f85c94%3a6cfd3594%3af2a57eb7%3a665c7bcf%3ac6335cbd%3a526d426%3a4b40c3e6%3a4fc2fd6d%3a34f9d57d" type="text/javascript' is not a valid virtual path.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Web.HttpException: '/Telerik.Web.UI.WebResource.axd?_TSM_HiddenField_=ctl00_RadScriptManager1_HiddenField&amp;_TSM_CombinedScripts_=%3b%3bTelerik.Web.UI%2c+Version%3d2008.1.416.35%2c+Culture%3dneutral%2c+PublicKeyToken%3d121fae78165ba3d4%3aen-US%3a2b085cdb-b44c-4804-80d3-9ac9bd7a0568%3a393f5085%3a9703c1f0%3aa3f85c94%3a6cfd3594%3af2a57eb7%3a665c7bcf%3ac6335cbd%3a526d426%3a4b40c3e6%3a4fc2fd6d%3a34f9d57d" type="text/javascript' is not a valid virtual path.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


[HttpException (0x80004005): '/Telerik.Web.UI.WebResource.axd?_TSM_HiddenField_=ctl00_RadScriptManager1_HiddenField&amp;_TSM_CombinedScripts_=%3b%3bTelerik.Web.UI%2c+Version%3d2008.1.416.35%2c+Culture%3dneutral%2c+PublicKeyToken%3d121fae78165ba3d4%3aen-US%3a2b085cdb-b44c-4804-80d3-9ac9bd7a0568%3a393f5085%3a9703c1f0%3aa3f85c94%3a6cfd3594%3af2a57eb7%3a665c7bcf%3ac6335cbd%3a526d426%3a4b40c3e6%3a4fc2fd6d%3a34f9d57d" type="text/javascript' is not a valid virtual path.]
System.Web.VirtualPath.Create(String virtualPath, VirtualPathOptions options) +3626815
System.Web.VirtualPathUtility.ToAppRelative(String virtualPath) +10
Miron.Web.HandlersAndModules.Filters.PrepareScriptsToComnpression.Replace(Match m) +102
System.Text.RegularExpressions.RegexReplacement.Replace(MatchEvaluator evaluator, Regex regex, String input, Int32 count, Int32 startat) +217
System.Text.RegularExpressions.Regex.Replace(String input, MatchEvaluator evaluator, Int32 count, Int32 startat) +28
System.Text.RegularExpressions.Regex.Replace(String input, MatchEvaluator evaluator) +45
Miron.Web.HandlersAndModules.Filters.PrepareScriptsToComnpression.Found(Match m) +87
System.Text.RegularExpressions.RegexReplacement.Replace(MatchEvaluator evaluator, Regex regex, String input, Int32 count, Int32 startat) +217
System.Text.RegularExpressions.Regex.Replace(String input, MatchEvaluator evaluator, Int32 count, Int32 startat) +28
System.Text.RegularExpressions.Regex.Replace(String input, MatchEvaluator evaluator) +45
Miron.Web.HandlersAndModules.Filters.PrepareScriptsToComnpression.FixScriptsUrl(String html) +72
Miron.Web.HandlersAndModules.Filters.PrepareScriptsToComnpression.Write(Byte[] buffer, Int32 offset, Int32 count) +59
System.Web.HttpWriter.Filter(Boolean finalFiltering) +251
System.Web.HttpResponse.FilterOutput() +97
System.Web.CallFilterExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +54
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +64


Miron il

Sunday, May 04, 2008 3:10 PM

Miron

@John,
Download the updated code (last update at 05-05-08) from the post: mironabramson.com/.../...-third-party-scripts.aspx
It should work fine. Let me know if any problems.

Rajesh in

Monday, June 09, 2008 10:36 PM

Rajesh

Hi,
I am getting the following error when I try to use your code

Server Error in '/gacvolonline' Application.
--------------------------------------------------------------------------------

Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

Parser Error Message: Could not load type 'Miron.HttpHandlersAndModules.HttpCompressionModule'. (C:\GACvolOnline\web.config line 91)

Source Error:


Line 89: <httpModules>
Line 90: <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
Line 91: <add name="HttpCompressionModule" type="Miron.HttpHandlersAndModules.HttpCompressionModule"/>
Line 92: <add name="WebResourceCompressionModule" type="Miron.Web.HandlersAndModules.WebResourceCompressionModule"/>
Line 93: </httpModules>


Source File: C:\GACvolOnline\web.config Line: 91


--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:2.0.50727.1433; ASP.NET Version:2.0.50727.1433

Yaseen

Sunday, June 29, 2008 8:14 PM

Yaseen

It is good work, but in my case i want to compress a Query string how can I accomplished this task

Miron il

Sunday, June 29, 2008 11:11 PM

Miron

@Rajesh,
I looks problem with the configuration.
Take the last code and info from latest post:
www.mironabramson.com/.../...mpression-Module.aspx

@Yaseen,
What do you mean by 'compress a Query string' ?

Ivan br

Monday, February 16, 2009 8:37 AM

Ivan

First of all thanks for sharing such a great work!!
I've tested it successfully on Visual Studio's webserver, I can see the content-encoding tag in Firebug and also the css.axd responses.

The problem is that when I move it to IIS 5.1 (Windows XP Pro, it doesn't come with HTTP compression filter, I'm using IISExpress) I can't see the tags stating that the code is compressed. The css.axd is also bigger.

Is the code server dependent ? I meant, do I need to have any compression filter enabled on the server to make it work ?

Thanks!!

Miron il

Wednesday, February 18, 2009 9:55 PM

Miron

@Ivan,
First, take the latest source code (blog.mironabramson.com/.../...pression-Module.aspx)
The compression component doesn't depend on the IIS Compression filter. It does the compression by itself, and the IIS compression should be disabled. My component is free and open-source (not like IISExpress) and you don't need to buy anything to make it work.
It was tested and it works very well on any IIS (5 to 7)

bharath in

Sunday, April 26, 2009 5:34 PM

bharath

Hi,
CAN YOU SEND ME FULL CODE HOW TO IMPROVE THE SITE PERFORMANCE.USING hTTP hANDLERS .i TRYE UR CODE BUT
FAILED TO HOW IMPLEMENT CAN YOU HAVE HELP ME HOW TO USE THAT ONE .IN MY SITE FULL OF IMAGES.HOW WE CAN FAST WAY OD LOADING....END ME ANY SOLUTION...............PLEASE.

Bradford Dental Implants gb

Sunday, June 21, 2009 10:03 PM

Bradford Dental Implants

This make my huge css code compress so I can use it very effectively in my website. and it will help my site to load faster than before.

SEO us

Tuesday, June 30, 2009 7:22 PM

SEO

Excellent code stuff.I've tested it successfully on Visual Studio's webserver, I can see the content-encoding tag in Firebug and also the css.axd responses.

Income protection us

Tuesday, June 30, 2009 9:53 PM

Income protection

I am using this compression module for compressing the Web Resources but recently I ran into one problem when the site became SSL enabled. All of the sudden, none of the ASP.NET Menus were working. Whenever I hover mouse over ASP.NET menu, there will be one dialog box shown up with message as: Do you want to save the file?....

Demon

Sunday, July 12, 2009 6:15 PM

Demon

Hi,

I tested using from your samples when trying press button with inside UpdatePanel very strange problem appeared, when using latest 3.5 ajax and .NET Framewok 3.5 compression for post process works, when trying use 2.0 Framework with older Ajax doesn't work compression why? I can't use latest Framework becouse by hosting plans problem.

Can any answer why doesn't work MbCompression with Microsoft Ajax in 2.0 Framework.

Response Headers after Post content using Ajax.Net 2.0 (version 1.0.61025.0)

Server: ASP.NET Development Server/8.0.0.0
Date: Fri, 10 Jul 2009 15:53:56 GMT
X-AspNet-Version: 2.0.50727
Transfer-Encoding: chunked
Cache-Control: private
Content-Type: text/plain; charset=utf-8
Connection: Close

Response Headers after Post content using Ajax.Net 3.5 (version 3.5.0.0)

Server: ASP.NET Development Server/8.0.0.0
Date: Fri, 10 Jul 2009 16:03:25 GMT
X-AspNet-Version: 2.0.50727
Content-Encoding: gzip
Cache-Control: private
Content-Type: text/plain; charset=utf-8
Content-Length: 1430
Connection: Close

I downloaded latest your MbCompression source code, mbcompression-23926.zip.

When I change settings.MSAjaxVersion < 3.5 to settings.MSAjaxVersion < 0.9 then after post response server an ajax error message that can't parse response.write() and etc.., but if I change to settings.MSAjaxVersion < 1.0 response was with both Content-Encoding: gzip and Transfer-Encoding: chunked, why?

Thanks

Miron il

Wednesday, July 15, 2009 12:58 AM

Miron

@Demon,
You can't compress Ajax calls on MS-Ajax framework on versions below 3.5.
The framework throw an exception on any modification you try to do to the response.

Acai Berry us

Wednesday, May 19, 2010 10:06 PM

Acai Berry

Interesting article. Well done and good luck with your very great work. I wish you have a luxury time to consider using benefits articles can offer. Thanks for sharing.

jeffrey us

Thursday, May 20, 2010 7:13 PM

jeffrey

Hi .
Mr. Miran Abramson's has done a good blog . I come to know about compressing pages and it is useful . Thank you sir .