Showing posts with label Optimization Tips. Show all posts
Showing posts with label Optimization Tips. Show all posts

Thursday, October 22, 2009

New articles published on Ajax performance and futures

If you are going to be "prolific" and live up to a company motto of "deliver more than expected," you have to multi-task. So somewhere in the middle of preparing a dozen sessions to present this fall, I also found time to author a couple of articles for some well know (in the developer world, at least) publications. Specifically, I have recently published articles in Dr. Dobb's and .NET Developer Journal.

The articles both cover areas that are within my primary realm of "expertise" (which is web development), but with two distinct approaches:
  • Practical Approaches for Optimizing Web Site Performance (written for .NET Developer Journal) covers tips and tricks for optimizing standards-based websites. Most of the tips are applicable to all websites, though there is some ASP.NET specific advice towards the end. Great resource if you're starting to "tune" your website for performance.
  • Ajax, RIAs, and the Future of Web Development (written for Dr. Dobb's), meanwhile, takes more of a "strategic" look at the future of web development, analyzing trends in web technologies to better understand what the future of web development will look like over the next 18 to 24 months. If you want to know what will shape the future of web development- the technologies you need to start studying now so you can get ahead of the curve- this article is for you.
Both are obviously required reading if you're a web developer, but I imagine that desktop developers, brain surgeons, and even small children will enjoy these articles. Be sure to share the links with your friends and stay tuned for more articles from the "industry influencers" at Telerik coming to another well-known publication near you.

Wednesday, September 30, 2009

RadGrid optimization webinar tomorrow, Register today

If you're like most developers using the RadControls for ASP.NET AJAX, you're probably using RadGrid, Telerik's flagship grid component for the standards-based web. RadGrid allows you to do some incredible things in web applications without requiring you to write much (or any, in some cases) code. At some point, we've probably all experienced how RadGrid can help you create a ASP.NET page with data display, paging, filtering, grouping, editing, and "pretty styling" in a matter of minutes. We marveled at its ease of use and its ability to make us look like "super" developers to our bosses and clients.

But as any application (and developer) matures, your focus shifts from "create features fast" to "make the website as fast as possible." Fortunately, RadGrid can evolve with you. While the "codeless" approach allows you to maximize productivity, there are tons of techniques that you can employ to maximize performance.
It's exactly that path towards performance optimization that we'll explore in tomorrow's Weekly Webinar. Join me at 11:00 AM Eastern, tomorrow, Thursday, October 1st for the first part of an in-depth look specifically covering RadGrid for ASP.NET AJAX optimization strategies. We'll set the stage for optimizing RadGrid and explore at least five optimization techniques that you can begin using in your projects today for improved performance. It'll be fast, but it'll be fun. See you in the morning!

Wednesday, February 04, 2009

Optimization Tips: RadInput vs. RadInputManager

OptimizationTips[Cross-post of content from my Telerik.com blog for your technical reading pleasure.]

In the Q3 2008 release, Telerik introduced a new control to the RadControls for ASP.NET AJAX suite called RadInputManager. Like RadInput, it is designed to enable you to provided textboxes to your users that give real-time validation and feedback based on the entered text. The big difference with RadInputManager, though, is that you don't have to add lots of Telerik Input controls on your page to get this real-time feedback. Instead, you can quickly convert "standard" ASP.NET TextBoxes to RadInput textboxes via the RadInputManager configuration- similar to how you can use RadAjaxManager to quickly ajaxify your page without littering it with UpdatePanels.

RadInputManager is a very innovative control and- in my opinion- one of the biggest steps forward in simplifying ASP.NET form validation to come around in a long time. In this optimization tip, we'll take a look a the RadInputManager (RIM) control to see how it simplifies form validation and see how it helps us improve page performance.

Continue reading RadInputManager optimization tip

SIMPLIFYING FORM VALIDATION

When ASP.NET developers want to validate form inputs today, that usually represents the beginning of a time consuming task where form validation controls are add to the page for every input that needs to be validated. After the assorted RequiredField, RegularExpression, and Range validators are added, their prosperities set, and some type of UI added to display their error messages, you're left with a page cluttered with markup that is unrelated to the actual layout or function of the form. Further, any complex validations on the page are usually set such that they do not get evaluated until the form has been submitted, meaning users get feedback regarding their input errors long after the mistake has been made. Not great for usability.

With RadInputManager that all changes. Instead, validating form inputs becomes easy and painless:

  1. You add standard ASP.NET TextBoxes to your form where you want to collect values
  2. You configure RadInputManager to apply RegularExpression, Numeric, DateTime, or RequiredField validations the appropriate textboxes
  3. You run the page

No markup littering. No need to set properties over and over again on controls that are providing the same validation. And as a bonus, when you use RadInputManager, users get real-time feedback when their input does not validate, enabling them to correct it before submitting the form.

RADINPUTMANAGER VALIDATION TYPES

We won't go in to fully detailing the RadInputManager's properties- there are great docs available for that- but I will highlight it's capabilities as a form input validation control. Via the control's simple configuration properties, you can accomplish any of these validations:

  • Numeric - only accept numeric digits, specify Max and Min number range, specify negative number formatting, specify decimal formatting
  • Date- specify allowed DateTime format, specify allowed DateTime range
  • RegularExpression- specify any regular expression to validate
  • TextBox- use as simple RequiredField validator

In addition to these specific validation types, RadInputManager allows you make any textbox required (essentially replacing the need for separate required field validators) and it enables any textbox's validation to be declaratively connected to a web service for powerful server-side validation. With a single control, you're replacing the need for separate TypeValidators, RangeValidators, RequiredFieldValidators, and CustomValidators for every input on your form.

RADINPUT VS. RADINPUTMANAGER

RadInput has been part of the Telerik RadControls for quite some time and- like the RadInputManager- it provides rich, validated text input. In fact, the RadInputManager is really just simplifying and optimizing the creation of RadInput controls on your page. Rather than manually adding a RadInput every place you need input validation and then initializing all of those controls separately, RadInputManager allows you to simplify the the configuration and optimize the initialization on the client. For example, if you needed to validate 5 numeric textboxes on a form, you might do this with RadInput:

ASPX

<telerik:RadNumericTextBox ID="RadNumericTextBox1" runat="server" MaxValue="100" MinValue="0">         
</telerik:RadNumericTextBox><br />
<telerik:RadNumericTextBox ID="RadNumericTextBox2" runat="server" MaxValue="100" MinValue="0">         
</telerik:RadNumericTextBox><br />
<telerik:RadNumericTextBox ID="RadNumericTextBox3" runat="server" MaxValue="100" MinValue="0">         
</telerik:RadNumericTextBox><br />
<telerik:RadNumericTextBox ID="RadNumericTextBox4" runat="server" MaxValue="100" MinValue="0">         
</telerik:RadNumericTextBox><br />
<telerik:RadNumericTextBox ID="RadNumericTextBox5" runat="server" MaxValue="100" MinValue="0">         
</telerik:RadNumericTextBox><br />
Notice the duplication of properties we have to set for each control. Also note that if we want to change the validation in the future, we have to replace the entire input control. With RadInputManager, the same configuration might look like this:

ASPX

<telerik:RadInputManager runat="server" ID="radInputManager1">
 <telerik:NumericTextBoxSetting MaxValue="100" MinValue="0">
     <Validation IsRequired="true" />
     <TargetControls>
         <telerik:TargetInput ControlID="TextBox1" />
         <telerik:TargetInput ControlID="TextBox2" />
         <telerik:TargetInput ControlID="TextBox3" />
         <telerik:TargetInput ControlID="TextBox4" />
         <telerik:TargetInput ControlID="TextBox5" />
     </TargetControls>
 </telerik:NumericTextBoxSetting>
</telerik:RadInputManager>
Where in the above code snippet I have "TextBox1" through 5 somewhere on my form. Now I'm only setting my validation rules once, and I even have the ability set the "IsRequired" flag (something not available with RadInput). If I need to change the validation of a TextBox in the future, it's a simple matter of defining a new "Validation Setting" in my RadInputManager and adding the TextBox to its "TargetControls" collection.

IMPACT ON PERFORMANCE

When you use RadInputManager instead of RadInput, you're optimizing your page in two ways:
  1. You're reducing the bytes sent over the wire
  2. You're reducing the page initialization time
To observe this, we'll create a simple test that is made-up of two pages: one page has 40 RadInput controls (10 of each flavor, Numeric, DateInput, MaskedTextBox, and TextBox) and the other 40 standard TextBox controls with RadInputManager (configured with 10 controls for each setting type, Numeric, Date, RegEx, and TextBox). We'll load both of these pages in FireFox six times (on an empty cache each time) and measure total bytes received, JavaScript bytes received, HTML bytes received, requests, and average page load time. We'll then compare the numbers to see the relative difference (not absolute, since absolute times are impacted by many factors) RadInputManager has on page performance.

As a follow-up, we'll also re-run the tests- both with RadInput and RadInputManager- with the RadManagers to see how they affect overall page performance.

Bytes Over the Wire

radInputMngr_Chart_Bytes

This chart shows us the difference in bytes sent over the wire when using RadInput vs. RadInputManager for the exact same scenario (40 inputs). I did not include the results of the tests with the RadManagers because they do not significantly effect the bytes sent to the client (in this test, they only reduced total bytes by about 1%). What we see right away is that RadInputManager reduces the total bytes sent to the client by about 22%, but it sends about 5% more JavaScript to the client than RadInput. To achieve he overall reduction, RadInputManager is sending much less HTML- about 55% less in these tests. That's significant for one very important reason:

When a page is requested, all page resources (like JavaScript) will be cached and the cached versions will be used on subsequent page loads. The HTML, however, will be requested and sent every time the page loads.

So while RadInputManager does send slightly more JavaScript, those resource gets cached on the initial page request and then the lightweight HTML gets exchanged after that. With RadInput, you're passing twice as much HTML for every page request.

Average Page Load Time

radInputMngr_Chart_time

When it comes to page load time, we also see a significant gain in performance with RadInputManager. Since the Manager can coordinate the initialization of the validation logic (as opposed to having 40 separate controls trying to initialize on page load with RadInput), overall page load time can be reduced. In these tests, the page with RadInputManager took an average of 23% less time to load than the page with RadInput controls. Page load performance was even better when the RadManagers (RadScriptManager and RadStyleSheetManager, for the unfamiliar) were added, extending RadInputManager's benefit to about 27% less loading time while cutting total requests in half (from 11 to 5).

OPTIMIZATION TIP SUMMARY

RadInput and RadInputManager are two very capable input validation controls. Both have features that make them compelling- such as RadInput's support for numeric "spinners" and RadInputManager's support for RequiredFields- so it's important to pick the right control when designing your pages. For richer UI with more interactive controls, RadInput is currently your best choice. For top performance and highly optimized pages, RadInputManager is the best choice for a few simple reasons:

  • It reduces the bytes sent over the wire and has a better caching story
  • It is much faster to configure than RadInput or traditional ASP.NET validation controls
  • It improves overall page load performance
Hopefully the evidence presented in this article will help you understand the benefit of using RadInputManager in your own projects and show you yet another way Telerik is trying to deliver more than expected when it comes to helping you optimize your web applications.

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, June 25, 2008

Optimization Tips: Series changing channels

Much like the complexities of a broadcast TV network, sometimes popular shows get shuffled around to better align with the interests of the network. So it will be with my ongoing Optimization Tips blog series. From now on, all future posts in this series will be posted on my Telerik.com blog (yes, I have another blog there- subscribe now, if you haven't). With my access to the Telerik.com blogs restored, I'll return to trying to post more technical Telerik content there and more general .NET and Telerik news here. All of you still refusing to subscribe to RSS feeds, now might be a good time to subscribe to at least two.

To usher in the change, I've posted a new installment in the Optimization Tips series on the Telerik.com blogs. The latest installment shows you how to optimize custom skins for the RadControls for ASP.NET AJAX by turning them in to WebResources that can be combined by the RadManagers. We already know the positive effect combining has on page load time, so it is critical we apply it to our applications wherever possible. As a bonus, I've also created a cool new skin for RadTabstrip that you can download along with the associated Photoshop source!

Thanks for bearing with me during this programming change and enjoy the latest installment.

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!

Tuesday, May 06, 2008

Optimization Tips: Using RadAjaxManagerProxy Controls

In this installment of my ongoing series covering RadControls for ASP.NET AJAX optimization tips, I am going to take a short break from talking about how to optimize your page performance and instead cover a tip that will help you optimize your code. Specifically, we're going to take a look at the RadAjaxManager and the RadAjaxManagerProxy controls to see how they enable you to very easily ajaxify all parts of your application.

The ASP.NET AJAX Era
Long before ASP.NET AJAX was a gleam in Microsoft's eye, Telerik was providing robust Ajax tools to its customers. Telerik developed a full Ajax framework that made it very easy to implement Ajax in ASP.NET applications, the cornerstone of which was the RadAjaxManager control. When we began making the transition to ASP.NET AJAX, though, we decided to completely leverage Microsoft's framework in our RadAjax product. We wanted to deliver all of the time-saving benefits of the RadAjaxManager at design-time while relying on ASP.NET AJAX at run-time.

Needless to say, the RadAjax product that exists now does exactly that. It is built completely on ASP.NET AJAX and delivers all of the power of the Microsoft framework through Telerik's award winning tools. But the new RadAjax does more than change the underlying technology handling the Ajax "magic"; it also makes your Ajax configuration easier than ever.

The Old Days
Before RadAjax for ASP.NET AJAX, the task of defining Ajax settings in site's that utilized MasterPages and UserControls (read: almost all sites) was...a bit of a challenge. If you wanted the benefits of the AjaxManager's visual configuration tool (or even in-page IntelliSense mark-up), you had to place a RadAjaxManager on every ContentPage. This worked to a point, but if you wanted to also ajaxify controls on MasterPages, you were stuck with two RadAjaxManagers that wanted to control the same rendered page. To solve the problem, you could put a RadAjaxManager on your MasterPage, but then all settings in your ContentPages and UserControls had to be made programmatically- a laborious and code-cluttering requirement.

Enter the Proxies
With the advent of ASP.NET AJAX, Microsoft introduced the ScriptManager control. This control must be present on any page that uses ASP.NET AJAX and- like the RadAjaxManager- can only be on the page once. To work around the problem of ContentPages and UserControls, the ScriptManager introduced a companion control called the ScriptManagerProxy. This control enables developers to define settings for the primary ScriptManager that are rolled-up in to the primary manager at runtime.

RadAjax for ASP.NET AJAX mimics that architecture. You can now easily define a single RadAjaxManager in your application's MasterPage and then add RadAjaxManagerProxy controls to all ContentPages and UserControls. At runtime all settings in the proxies are rolled-up to the primary RadAjaxManager, but at design-time you get all of the benefits of Source View IntelliSense and the RadAjaxManager visual configurator. See Slide 1 of my embedded Google Presentation (below) to see this layout illustrated.



By utilizing the RadAjaxManager and RadAjaxProxy controls, you greatly simplify your ASP.NET AJAX ajaxification process. First, you don't have to clutter your markup with the UpdatePanels normally required by ASP.NET AJAX, making your code easier to maintain and read. Next, you don't have to manually think through how Triggers should be defined on your UpdatePanels. The RadAjaxManager automatically figures that out based on your simple definition the controls that should be updated after specific control events fire. And finally, RadAjaxManager provides a complete client-side API that makes it easy to perform advanced ASP.NET AJAX operations without having to write a lot JavaScript manually.
Client-side Support
Among the client-side support that the RadAjaxManager offers is the definition of two JavaScript events you can subscribe to: OnRequestStart and OnResponseEnd. You can see the code required to wire-up these client-side events on Slide 2 of my embedded presentation deck (see above). The events are very handy if you want to do anything on the client (such as validation) before an Ajax event fires. You can even cancel an Ajax request before it fires.

This is an extremely easy way to take more control over your application's Ajax, but what if you want to customize the JavaScript events that handle Ajax settings in your Proxy controls? Since the Proxy controls are not actual instance of RadAjaxManager, they do not expose ClientSettings directly. Instead, you need to work a little JavaScript magic to provide custom client-side event handlers for your primary RadAjaxManager that only handle controls ajaxified by your proxy.

Handling Client Events in UserControls
You recall that all ajax settings in the Proxy controls are rolled-up to the primary RadAjaxManager at runtime. That means there is only one point to define the JavaScript events that fire on Ajax requests: the primary RadAjaxManager. You cannot define JavaScript events for each Proxy control. You can, however, change the JavaScript events defined on the primary Manager in the PageLoad of any ContentPage or UserControl.

To change the events defined in the RadAjaxManager, the code shown on Slide 3 of my presentation should be added to the PageLoad event. Notice that the RadAjaxManager class exposes a very handy "GetCurrent" method that makes it very easy to get a reference to our primary RadAjaxManager from any position in our application (on a ContentPage, UserControl, etc.). With a reference to our primary Manager, we can quickly set the OnRequestStart and OnResponseEnd event names (just simple strings).

But wait! Now what happens when an ajax event defined in our MasterPage fires? It travels through our new JavaScript event handlers in our UserControl. That's no good. We only want controls ajaxified by our Proxy to get handled by our new JavaScript event handlers. Is there any way to "route" ajax events triggered in our UserControl to one set of JavaScript event handlers and ignore other ajax events? Yes, sorta.

Route the Events
Since there can only be one active set of JavaScript functions that handle RadAjaxManager client-side events, we have to manually provide support for "routing" events to the proper JavaScript functions. We can do this by inspecting the EventTarget property of the eventArgs passed to the OnRequestStart JavaScript function. That property will contain the full ClientID of the control that initiated the Ajax event. For example, if our button is located in UserControl "ProxyUserControl" on page "Default" in a MasterPage, we might see an ID like:

ctl00$ContentPlaceHolder1$ProxyUserControl1$btnUpdateTime

Ah hah! We have a way to tell where the Ajax event came from. By using some JavaScript to see if our UserControl name exists in this EventTarget string we can correctly route the RadAjaxManager client events. See Slide 4 in the embedded presentation for a complete look at the JavaScript code that handles this routing.

Gotchas
While this is a great solution for enabling custom handling of the OnRequestStart and OnResponseEnd events in UserControls, it does require a couple of assumptions that make our code a little brittle. First, you must know the names of the OnRequestStart and OnResponseEnd JavaScript functions in your MasterPage and you must assume those functions are present. Second, you must know the name of your UserControl so that you can correctly detect if the current Ajax event was fired from within the UserControl. Other than that, you're good to go.

Optimization Tip Summary
So what have you learned today? A few key points:

  • RadAjax for ASP.NET AJAX implements ASP.NET AJAX (not proprietary Ajax). Spread the word.
  • You can (and should) use RadAjaxManagerProxy controls to define Ajax settings in ContentPages and UserControls
  • You can use JavaScript to "route" OnRequestStart and OnReponseEnd events to different client-side functions by interrogating the EventTarget property of the eventArgs
Hope this helps you develop ASP.NET AJAX-enable applications faster than ever and gives you the tools you need to take exacting control over your Ajax behavior. In the next installment in this series, we'll resume with our look at techniques that improve your page load performance when using the RadControls for ASP.NET AJAX.

Friday, May 02, 2008

Optimization Tips: Testing Page Performance

Welcome back to my new series covering optimization tips for the Telerik RadControls for ASP.NET AJAX. The last time we visited, I showed you how you can reduce your initial page load times 30%, on average, by simply adding the RadScriptManager and RadStyleSheetManager to your application's pages. In this installment, we'll look at two follow-up issues: how does the web.config debug property affect page load performance and how much slower is Cassini than IIS.

When I conducted the tests for the first installment, I made sure "compilation debug" was set to false in my web.config and I used IIS to get pretty accurate results (I add the qualification because I didn't run the tests on a high performance web server, but you can expect that would only improve the absolute values). What would have happened, though, if I deployed my test website and forgot to set the debug property to false? Or even more serious, if I had used the Visual Studio Web Server (Cassini) instead of IIS for my tests, how would that have impacted my perception of page performance? That's what we'll quantify in part two. The results may or may not surprise you, but they'll certainly prove to you why it's important to save your impressions of page performance until a site is running in IIS with "debug=false" in the web.config.

Simple property, big impact
One of the easiest ways to tank the performance of your fancy ASP.NET AJAX website is to forget to set the compilation debug property in the web.config to false. This property has been used by ASP.NET for years to control debug and release builds, but the introduction of ASP.NET AJAX and it's richer client-side programming environment has added a serious client-side page load penalty for sites running in debug mode. Specifically, when ASP.NET AJAX detects that a site is running in debug mode, it loads a special debug version of the ASP.NET AJAX client libraries tuned for maximum debugging- not performance.

This feature of the ASP.NET AJAX framework is great for development because it makes it much easier to debug client-side code without impacting the performance of "release" libraries. And when the time comes to move your application to production, a simple property change will let ASP.NET AJAX know that it should deploy the tuned-for-performance release versions of the client libraries and turn-off the excessive debugging. That is, of course, if you remember to change the property.

The compilation debug property is located in your application's web.config file within the system.web block. It is a boolean property that defaults to false, but if you develop with Visual Studio, it is very easy to set this property to true without thinking. If you've been developing with ASP.NET for any amount of time, I'm fairly certain you've seen this setting, but you may not fully understand how substantial the impact is of not setting this property correctly.

To answer that question, I turned to the same sample application we introduced in part one of this series. It consists of a page with RadGrid, RadTreeview, RadMenu, RadSplitter, RadAjax, and (for these tests) RadScriptManager and RadStyleSheetManager. I tested page load times using IIS and IE7/8 and FF2/3, loading the page 6 times in each browser: 3 loads with a primed cache, 3 unprimed. The key difference for these tests, though, is that I set debug in the web.config to true.

In the above chart, the "Unprimed" and "Primed" series are the same values from part one's page load tests with the Rad Managers. They serve as our baseline for the new tests. Next to the old results, you see "Unprimed+Debug" and "Primed+Debug." These series show the difference in page load times when you simply forget to set "debug" to false. From these results we learn a few things:

  • On average, across browsers, debug = true makes initial page loads 27% slower
  • On average, cached page loads are 23% slower
  • Firefox is again the poor performer
      • Initial page loads are almost 40% slower in debug mode with IIS!
The obvious point: don't deploy applications with debug still set to true! You can hurt application page load time by 25% if you miss this.

Convenient and slow
Do you remember when Visual Studio didn't have a web server built-in? I know it's been a while now, but there was a day when every web site developed in VS had to be manually setup in IIS just to see it run. Thankfully, those days are behind us and the Visual Studio Web Sever (originally Cassini) has made the process of quickly building and testing web sites as easy as a single keystroke.

While Cassini is great for rapid application development, it's far, far from being the robust ASP.NET server that is IIS. I think all ASP.NET web developers understand this fact casually (we'd never try to run an ASP.NET website in production on Cassini- if it were even possible), but I don't think the difference between Cassini and IIS performance is well understood- especially in the context of page load time with ASP.NET AJAX. To make that difference clear, I ran another batch of tests, this time testing page load times in Cassini, still with debug set to true.
As with the debug chart, this chart compares our baseline page load times to page load times for our test page (in debug mode) served by Cassini. The results are pretty dramatic:
  • Firefox- even the new and improved Firefox 3- shot page load times through the roof
    • On an unprimed cache, pages load 91% slower (FF2 & 3 avg.)!
    • On primed, pages still loaded 72% slower
  • Across all browsers, pages loaded on average 50% slower
    • Excluding Firefox, pages loaded an average of 20% slower in IE7 & 8
So what? What are supposed to do about a slow development server? Nothing, really. The point here is that you should never make judgments about how long it takes your page to load if you're using Visual Studio's Web Server. When pages are in debug mode (which they usually are in Cassini), your page load time could take more than twice as long in development than it actually will in release mode served by IIS.

Optimization Tip Summary
This tip doesn't really provide you with anything you can specifically do to the RadControls to make them load faster, but it does drive home important points about measuring the performance of your pages that use the RadControls for ASP.NET AJAX. Now that you've seen the actual impact of compilation debug and the Cassini web server on page load time, you know that they can have a dramatically terrible impact on your page's performance and thus on your perception of the RadControls. Always make sure you test performance using IIS with pages running in release mode to get an accurate picture of how your pages are performing.

If you practice this tip, combined with the Rad Managers talked about in part one, and future optimization tips in this series, you'll be guaranteed to see page load times that make you smile- not scream!

Monday, April 28, 2008

Optimization Tips:The Rad Managers for ASP.NET AJAX

Today I am kicking-off a new series of blog posts that will focus on showing you specific ways you can optimize the performance of your applications built with Telerik's RadControls for ASP.NET AJAX. Whenever we use UI components to accelerate our web development, it is easy to forget that we still need to be "smart" developers when it comes to optimizing our web applications. Telerik tries to do as much as is possible at a component level to help with optimization, but as with any good thing like rich UI controls, too much is a bad thing. In this post and those that follow, I will delve in to optimization tips and tricks and show you the effects of each on a sample application. Hopefully it will help you become a better developer and enable you to maximize the performance of your apps, especially those with Telerik's RadControls.

Today's focus is on the new RadScriptManager and RadStyleSheetManager controls. These "manager" controls enable you to easily combine in to a single link all of the JavaScript and CSS links required by the RadControls. Why combine? One of the biggest bottlenecks for browsers these days is created by the concurrent requests limit. By default, both IE and Firefox limit concurrent requests per server to 4, as is recommend by the HTTP RFC guidelines. This limit can be changed, but expect few of your users to actually have done so as the process requires advanced computer skills.

With a limit of 4 concurrent requests (2 persistent connections), you can see how easy it is to clog the pipe with all of the request for images, JavaScript, and CSS on your page. Combining many links for CSS and JavaScript in to a single request can significantly improve your page load time by reducing the number of round-trip requests your page makes when it loads. And by doing the combining dynamically at runtime you don't have to send any unnecessary JavaScript to the client (for controls not in use) or manually maintain combined JavaScript files. It's one of the easiest and most effective optimization tips available.

Let's see the effect of these managers on a simple demo app that uses RadGrid, RadMenu, RadTreeview, RadAjax, and RadSplitter. We'll use FireBug (in Firefox 2) and Fiddler for our tests, and we'll run our site from IIS to ensure we get accurate performance numbers.

Requests and Bytes
The first thing you should notice when using the Managers is that the number of requests your page generates is reduced significantly. Let's take a look at the difference:

  • Requests without Managers
      • Unprimed cache: 32 @ 21.4 KB
      • Primed cache: 3 @ 2.6 KB
  • Requests with Managers
      • Unprimed cache: 16 @ 11.2 KB
      • Primed cache: 1 @ 1.8 KB
Clearly, the managers have a significant impact on your requests. In this demo app, they cut in half the number of requests and the number of bytes sent to the server on page load. That's a pretty significant gain and bandwidth savings for your user. Even on the download side, the Managers reduced the payload sent from the server about 11% on average, for both primed and unprimed page loads.

Page Load Times
While reducing the number of requests and bytes is good academically, it's ultimately page load time that matters to users. To see the effect the Managers have on page load time, I ran the demo through the online stopwatch in IE7, IE8 beta 1, FF2, and FF3 beta 5. I ran the stop watch 6 times for each browser, 3 unprimed cache tests, 3 primed cache tests. I then compiled the results in to the following chart.


This chart reveals a few interesting facts about the Mangers' effect on page load time:
  • Usually, for both primed and unprimed caches, the Managers reduce page load time
      • Unprimed improvement: 30%
      • Primed Improvement: less than 1%
      • Primed Improvement without FF2: 3%
  • As has been observed in other performance tests, FF2 is a poor performing browser
      • It renders pages slowly and renders cached pages slower than first request pages
      • FF3 is a lot faster than FF2 (yay!)
  • Almost all browsers tested render the test page in less than 1 sec with Managers
      • True for primed and unprimed cache
      • Key exception is FF2, but see note above. FF3 solves the problem.
Whether or not you'll see a 30% improvement on initial page load time in your app will require your own testing, but this analysis definitely makes it clear that the Managers can have a very real impact on improving your page's load time.

Optimization Tip Summary
To cut significantly reduce the requests and bandwidth required by your page on the initial visit, and to significantly trim your initial page load time, you should add the RadScriptManager and RadStyleSheetManager to your ASP.NET AJAX applications. For more details on how to add these controls to your page, see this page for the ScriptManager and this page for the StyleSheetManager in the Telerik documentation.

Next up, we'll look at the impact debug=true and the Visual Studio development server have on your page's performance.