Showing posts with label HTTP Compression. Show all posts
Showing posts with label HTTP Compression. Show all posts

Wednesday, January 28, 2009

Optimization Tips: RadCompression Module

Optimization Tips[Cross-post of content on my Telerik.com blog, for your reading convenience.]

Welcome back to the ongoing Optimization Tips series. It's been a while since the last installment, so it's high-time we took a look at more tips and tricks for optimizing your Telerik-powered web applications. In this the seventh article in this series, we'll take a look at Telerik's brand new RadCompression HttpModule and try to gain a deep understanding of how this tool can help improve application performance. Some of the concepts in this article build on things we've discussed in previous installments, so I encourage you to read the earlier articles before reading this if you have not already done so. Let's get started.

WHAT IS RADCOMPRESSION?

Simply put, RadCompression is a HttpModule that ships with the RadControls for ASP.NET AJAX (Q3 2008 SP2 and later) that is designed to automatically compress your AJAX and Web Service responses. In other words, RadCompression will intercept the bits that your server is sending back to a browser (or Silverlight-client, for that matter) and compress them. Once the compressed bits reach the browser, standard browser technology takes-over and decompresses the response so your application can work with it normally. The compression process is completely transparent to your client-side code (JavaScript or Silverlight) and your server-side code. It simply reduces the number of bits that must be sent over the wire (from your server to your client) and thus- in theory- improves your page performance by reducing the TTLB (time to last byte).

Continue reading RadCompression Optimization Tip

WHAT RADCOMPRESSION IS NOT

RadCompression is not designed to be a complete replacement for other HTTP compression tools, such as the built-in HTTP Compression in IIS 7. Instead, it is designed to work with those existing tools to cover scenarios they usually miss- namely the compression of bits moving back and forth in AJAX (and now Silverlight) applications. If you have HTTP Compression enabled in IIS7, you'll discover that it does not compress your AJAX and Web Service responses; it only compresses the initial bits sent to the browser when the page is requested. By adding RadCompression to your project, you cover those gaps and start compressing your XHR (XmlHttpRequest - i.e. the "X" in AJAX).

So, if RadCompression does not cover all HTTP traffic, what does it cover? Quite simply, RadCompression will automatically detect and compress requests that expect these content response types (as found in the HTTP request's "ContentType" header or "AcceptsTypes" header):

  • application/x-www-form-urlencoded
  • application/json
  • application/xml
  • application/atom+xml

These types generally reflect the content types returned by AJAX Web Services, ADO.NET Data Services, and AJAX UpdatePanel responses, though there certainly are other scenarios that return these content types (such as a typical RSS feed). If a browser supports compression (and most modern browsers do), and RadCompression is enabled, all content of this type will be compressed. The one exception is IE6, which does not well support this compression, so RadCompression will automatically ignore requests coming from IE6 clients.

HOW DO YOU ENABLE RADCOMPRESSION?

Enabling RadCompression really couldn't be easier. It's a simple matter of adding a HttpModule registration to your site's web.config. Specifically, you need the following:

XML (Web.Config)

<httpModules>
...
<!-- Add this line exactly as is - the name value is important -->
<add name="RadCompression" type="Telerik.Web.UI.RadCompression" />
</httpModules>
<!-- If you're using IIS7, then add this, too-->
<system.webServer>
  <modules>
    ...
    <add name="RadCompression" type="Telerik.Web.UI.RadCompression" />
  </modules>
...
With that single line of configuration (or two lines if you're using IIS7 Integrated Pipeline), RadCompression is ready to work. You don't need to make any additional code or configuration changes. The compression module will automatically look for content that matches the conditions mentioned above and compress it. Remember that HttpModules, unlike HttpHandlers, touch every request processed by ASP.NET, so you don't have to do anything to your pages or services to make the compression work. All compression is handled by the module. All decompression is handled by the browser.

WHAT IS THE BENEFIT?

Time to get down to the brass tacks. Does RadCompression really help improve your application's performance? As you know, in the Optimization Series, we've been testing different optimization techniques and their effect on page load time. It's crude, but it gives you a relative idea of how the technique can improve your application's performance. For RadCompression, I ran eight unique tests, executing each six times to collect a reliable sample set. The tests are composed of two distinct scenarios:

  1. UpdatePanel Updates: In this scenario, there is a page with a RadGrid, bound server-side during the NeedsDataSource RadGrid event, with a RadAjaxManager on the page to "ajaxify" all Grid operations.
  2. Client-binding Updates: In this scenario, there is a page with a RadGrid that is declaratively bound to a ADO.NET Data Service (which, for the unfamiliar, is essentially a fancy WCF web service). The RadGrid fetches data via the service and initializes in the browser and uses the web service for all operations, such as paging.

For both scenarios, the data layer is a simple LinqToSql model using the AdventureWorks database. Both grids are bound to all Employees in the AdventureWorks data store, so the scenarios should be equal except for the way they handle initial data binding and binding for operations like paging. For each scenario, we'll test the following, measuring bytes sent during the request, bytes sent in the response, total requests, and page load time:

  • Initial page load
  • Paging the RadGrid with RadCompression disabled
  • Paging the RadGrid with RadCompression enabled
  • Loading and paging the RadGrid with RadCompression + the RadManagers (RadScriptManager, RadStyleSheetManager)

These tests will show us the relative impact of adding RadCompression to a site. Let's take a look at the results:

Average Bytes Received

Bytes Received

This chart reveals some interesting facts. First, we see that choosing to use UpdatePanels (and server-side binding) or client-side binding does not significantly initial page load size. In fact, it takes a few more bytes to start with client-side binding (though we see when the RadManagers are used those bytes compress better). The real benefit of the client-side binding is revealed in the RadGrid paging operations, where the bytes received are reduced by 62% (on average). When we add the RadCompression HttpModule, we see improvement in both scenarios paging scenarios. With UpdatePanels and "traditional" AJAX, bytes sent over the wire are reduced by about 68% with RadCompression enabled, and by about 86% with client-side binding. So right away we see that RadCompression has a significant impact on reducing traffic for async operations like paging in RadGrid.

Average Page Load Time

radCompress_Chart_loadTime

The load time results can be a bit confusing at first. They are not nearly as dramatic as the reduction in bytes received, so you have to look close to understand what's happening. First of all, we can see that all operations- including the initial page load- are happening in less than one second. In fact, all of the paging operations are happening in about 1/10 of one second! That means the localhost environment makes it hard to see the impact of the compressed bytes on page load time while paging a RadGrid. You can see, of course, that the RadManagers help reduce the initial page load time by about 25%, but the RadCompression module has a negligible impact on the RadGrid paging load time. The take away: for sites deployed to a local network (i.e. intranet sites), you really don't need to worry about performance optimizations at the level RadCompression provides. The latency is low enough and the bandwidth high-enough that you won't see a significant impact on page load performance. For remote sites, though, the delta between load time with and without RadCompression should be much more obvious (thanks to the time required to transfer 75% more bytes over the wire).

OPTIMIZATION TIP SUMMARY

When it comes to RadCompression, the impact it has on your site just depends on where your users are located. If you have a site that is deployed over the web, where latency and connection speeds are unpredictable, reducing the bytes you send over the wire is an easy way to improve your site's performance. And since RadCompression can literally be implemented with a single change to your config file, you really don't have much to lose. In a quick word:

RadCompression is an easy way to reduce the bytes sent over the wire for XHR operations.

Hopefully you'll enjoy this new tool in your Telerik toolbox. Whether you use them or not, Telerik is working hard to give you all of the tools you need to optimize your websites with very little work. When combined correctly for the right sites, we believe we can enable you to not only to build sites quickly, but with measurable top performance.

Wednesday, May 28, 2008

Optimization Tips: Using HTTP Compression

I know it has been a few weeks since the last installment in this series, and with TechEd on the horizon it'll probably be a couple 'til the next, but as long as there is some time in between let's explore another area of performance optimization with the RadControls for ASP.NET AJAX. This week, we're going to take a look at HTTP compression and how this simple technique can deliver a valuable performance boost to your website.

What is HTTP compression?
Since the turn of the century, almost all browsers have supported compressed content via the "content-encoding" (or "transfer-encoding") specs defined in HTML 1.1. When a browser requests a page from a server, it always tells the server if and what kind of content encoding it can handle. This information is communicated in the "accept-encoding" request header. If the server is configured correctly, it can respond to this header value and automatically compress (think Zip) the HTTP content before sending it to the browser. When the content arrives, the browser decompresses the content and renders the page.

The overall goal of HTTP compression is to reduce the number of bytes that must be transmitted over the tubes between your server and the user's machine. Since transmission time is often the slowest bottleneck in loading a page, and since bandwidth directly relates to your costs as a site operator, reducing the bytes you transmit to the user can save you money and improve your site's performance.

How do I use it with ASP.NET?
There are a number of ways to use HTTP compression with ASP.NET. If you have full access to your server, IIS 6 provides some basic compression support. Compression of static content is turned-on by default in IIS 6, but you'll need to take extra steps to enable compression of dynamic content. If you're already in a Windows Server 2008 environment, IIS 7 provides great HTTP compression support, enabling you to define which files get compressed based on their MIME type in your configuration files. Still, to use IIS' compression support, you need to have complete access to your server (specifically IIS), and to get great support in IIS you need to be running Windows Server 2008. (NOTE: For a good overview of compression features in IIS 7, see this blog post on the IIS blogs.)

Fortunately, there are alternatives for developers that want to deploy HTTP compression support with their applications (or for those devs that don't have access to IIS, such as in shared hosting environments). Several open source projects and commercial products exist on the interwebs that provide HttpModules to compress your content based on configuration rules. Once such commercial tool that I've used successfully in the past is ASPAccelerator.NET. By simply adding a HttpModule reference to my web.config and deploying a single assembly in my bin folder, I can instantly begin compressing my HTTP content (served by IIS6 or 7) based on an intelligent set of rules.

For today's tests, that is the approach that will be used to compress our test site. And since we're interested in seeing how HTTP compression helps "real world" site performance, we're going to be doing our testing a little differently this week than we have in the past.

Help Desk demo testing with Gomez
Have you heard of Gomez? If you work for a large, Fortune 500 company chances are you are using their services to actively monitor and measure your company's web performance. Gomez is one of the largest providers of website performance measurement and tracking, and as such, they have some of the best tools available for measuring a site's performance.

What you may not know is that Gomez provides a free "instant site test" that you can use to take one-off measurements of your site's performance as seen by one of Gomez's 12,000 test computers. The free service allows you to supply a URL and select a test city (L.A., New York, Chicago, Beijing, or London), and then Gomez generates a detailed report showing you how responsive your site is. This is a great (free) way to see the real world effects of latency and bandwidth on your site, which makes it a perfect way to measure the effects of HTTP compression on our test site.

And to conduct today's tests, we'll be setting-down our fun InterWebs demo in favor of using the slightly bulkier Telerik Help Desk demo. This demo displays a fair amount of data pulled from a SQL Server 2005 database, and it uses many RadControls, such as RadGrid, RadTreeView, RadMenu, RadCombobox, RadSplitter, RadAjax, and RadCalendar. RadWindow and RadEditor are their, too, but they won't have an impact on today's tests of the primary Help Desk landing page.

How will the tests be run?
To conduct today's tests, we'll start applying the techniques we covered in parts 1 and 2 of this series to the Help Desk demo, collecting 5 Gomez test results from their Chicago test server (the demo today will be hosted on a DiscountASP server in California). All tests will be run as if on empty browser cache (thanks to Gomez) and the average of the 5 tests will be reported. Once we've layered-on our previous performance improving techniques, we'll enable HTTP compression with ASPAccelerator and see what kind performance benefit it provides.

Make sense? Then let's run our tests and analyze the results.

The test results
With the tests run and the averages collected, let's take a look at the effect our different performance improving techniques had on our live test site:

While the absolute numbers here aren't great, they're also not important. This is a completely unoptimized application running on shared hosting with very little server resources, communicating from California to Chicago. What are important are the trends, and the they reveal some very interesting facts:

  1. If you didn't believe the impact of leaving complication debug = true from part two of this series, believe it now. Simply setting debug to false reduced the time it took for our page to load by almost 30% (7 seconds)! ALWAYS set debug to false in production.
  2. The same advice is true for the RadManagers (RadStyleSheetManager and RadScriptManager). By simply adding these to my page (and doing nothing else), I further reduce page load time by over 50%. Combined with the first step, 60 seconds of work has shaved almost 70% of the loading time off of my page.
  3. Finally, adding the HTTP compression shaves another 30% off my page load time, producing a page that takes almost 80% less time to load than the original version! And I haven't changed any code.
The bandwidth comparison
Just as important as page load time in today's tests is measuring how much HTTP compression saves me on total bandwidth. If there is anything in this largely free marketplace we call the Internet that increases our costs as our sites become more popular it's bandwidth (and the servers required to fill it, of course). So if HTTP compression- in combination with our other performance improving techniques- can reduce the bandwidth we consume to send the same pages to our users, we'll directly impact our bottom line. Let's see how bandwidth varied over each stage of our test:As you can see, HTTP compression had a huge effect on the number of bytes we needed to send over the line to load the same exact page.
  • With no "treatments" applied, we sent over 1 MB of data to our user's browser on the first visit! That's a lot of data.
  • Setting debug to false reduced our bandwidth usage by about 15%, and adding the RadManagers only slightly lowered bytes sent from there.
  • When we added the HTTP compression, though, we reduced the number of bytes sent over the wire by over 75%! That's a huge bandwidth savings that should directly translate into higher throughput on on our servers and improved page response times.
We can validate the improved page response times with the overlaid page load time stats. As the bytes are reduced with HTTP compression, we see page load time decrease. But notice how much page load time drops when the RadManagers are added to the page even though they don't significantly impact the page's footprint. Remember, all the Managers are doing are combining data, not compressing. They deliver huge performance gains by reducing the number of links on the page, thus reducing the number of requests the browser needs to make to load all of our images, stylesheets, and JavaScript.

Gotchas
As with all performance tips, you do have to be smart in your application. While HTTP compression is generally a very efficient operation that doesn't significantly task the CPU, you should be careful on high volume sites. The extra CPU cycles required to perform the compression could make site performance worse than it would with compressed traffic. In most low- to medium-volume scenarios, though, you can compress without concern. In the coming weeks, I'll highlight a hardware solution that can solve the woes of compression on high-volume sites (in addition to providing a number of other helpful performance boosters). If you want to explore the tool on your own in the mean time, visit the Strangeloop AppScaler website.

You also need to be careful with HTTP compression and Ajax. Some HTTP compression tools do not play nice with Ajax requests, breaking callback functionality on the page. ASPAccellerator provides support for the ASP.NET AJAX framework, but not all tools may be as helpful. Choose wisely.

Optimization Tip Summary
What have you learned today? Quite simply this:
  • The rules from parts 1 and 2 of this series are still among the most important for improving page performance.
  • Adding HTTP compression to your page with the RadControls for ASP.NET AJAX can measurably improve page performance and significantly lower bandwidth requirements.
Hopefully these tests help you understand and visualize the benefit HTTP compression can play in squeezing every bit of performance out of your site. In the coming weeks, I'll try to do some comparison tests of different HTTP compression methods- IIS 6/7, port80, ASPAccelerator, open source- to give you more guidance if you're trying choose a compression provider. Until then, compress away and do your part to help reduce the bits clogging the Internet's tubes!