Compressed GZip content from Windows Azure blob storage

On one of our internal mailing lists, someone asked how to serve gzipped content from Windows Azure storage directly. When serving static content (like JS/CSS files) over HTTP, serving them compressed usually gives you big wins in terms of network performance since you have to send less bytes over the wire.

Windows Azure currently doesn't compressing uncompressed data on the fly for you. However, there's nothing stopping you from storing the data compressed in the first place. The key is to set the Content-Encoding header to 'gzip' when uploading the blob so that when the blob storage serves it back out, clients know that the content they're getting is compressed and know how to deal with it.

One caveat with this approach is that there is no way to support clients which can't support gzip decompression. However, all modern browsers support this really well so you shouldn't run into any issues for plain vanilla HTTP content.

Here's a snippet of code illustrating how to do this. In this, I take a file posted over a Asp.Net file upload control and store it compressed in blob storage.

/* Blob to be uploaded,in this case coming from a file upload control */
var inputstream = fileUpload.PostedFile.InputStream;
var contentType = fileUpload.PostedFile.ContentType;

/* We'll use the filename without the path as the blob key */
var blobKey = Path.GetFileName(fileUpload.PostedFile.FileName);

var container = BlobStorage.Create
(
StorageAccountInfo.
GetDefaultBlobStorageAccountFromConfiguration()
).GetBlobContainer("js");

/*Compress the blob we're storing*/
var compressedData = new MemoryStream();
var gzipStream = new GZipStream(compressedData,
CompressionMode.Compress);
gzipStream.Write(fileUpload.FileBytes,0,
fileUpload.FileBytes.Length);
gzipStream.Close();

/* Store the compressed content to blob store
and set the right Content-Encoding header */

container.CreateBlob(
new BlobProperties(blobKey)
{ /* This is the part that makes it all work! */
ContentEncoding = "gzip",
ContentType = contentType
},
new BlobContents(compressedData.ToArray()),
false/*Don't overwrite*/
);

I uploaded a 20K sample JS file and then hit the blob's URL with Firefox. The screenshot shows you how the 20K JS file got compressed down to 7K and then sent down with the right header for the browser to decompress it on the fly


image


This technique typically works better on large text content like CSS and JS files. I wouldn't recommend using this on images as they are typically highly compressed already. For more on such performance techniques, I would strongly recommend Steve Souders' excellent book.

Labels:


Comments:
this works fine as long as you *know* the client will always accept gzip-encoded content. since i have several cases where this will not be true, i have implemented a 'proxy' service that properly reads and responds to the 'accept-encoding: gzip,deflate' header.

what is the timeframe to support for the 'accept-encoding' header?
 
This is probably obvious however I could use a link to some directions on how to create a classical ASMX web service that runs on Windows Azure that I could use to retrieve stored images using a Silverlight client.

David Roh

JK@SilverlightAzure.com
 
Post a Comment



<< Home

Archives

November 2004   January 2006   June 2006   July 2006   August 2006   September 2006   October 2006   November 2006   December 2006   January 2007   February 2007   March 2007   April 2007   May 2007   June 2007   July 2007   August 2007   September 2007   October 2007   December 2007   January 2008   February 2008   March 2008   April 2008   May 2008   June 2008   July 2008   August 2008   September 2008   October 2008   November 2008   December 2008   January 2009