Showing posts with label ASP.NET AJAX. Show all posts
Showing posts with label ASP.NET AJAX. Show all posts

Tuesday, October 07, 2008

Todd Anglin on MVC, Ajax, Silverlight, WPF, Web Browsers

One of the things I did while in India back in May was sit down with a video crew to film a quick interview for DevMarch.com. The interview has finally been processed and published online and made available for your viewing pleasure. A few quick notes about the video:

  • It was shot in mid-May 2008, so obviously, the info is dated to that period (though most of the content remains relevant today)
  • The video was shot in an old dressing room backstage at the Indian Institute of Science after days of marathon sessions, and the interviewer specifically asked me to not look her direction (she was sitting to the left of the camera). So if I look like I'm trying to not look at the questioner during the video, that's why.
  • The video is about 12 minutes long and it covers a lot of topics. I think it starts with browsers, then moves on to Ajax, MVC, and then WPF and Silverlight. Feel free to skip to the parts that interest you.
The video was shot to help generate content for the DevMarch.com site, a new developer portal launched by Saltmarch Media shortly after the Great Indian Developer Summit concluded. You can find other videos on the site from some of the other speakers I shared the event with, so spend a few minutes looking around if you've never seen this resource before. Other than that, enjoy the info-packed interview!

Watch the interview video now



Thursday, July 03, 2008

Microsoft releases (big) ASP.NET AJAX road map

Microsoft has just published a new, huge road map for ASP.NET AJAX. I know?! After all of this time being fed bits and pieces from many different sources to stitch together ASP.NET AJAX, it turns out there is actually a road map for these features and tools. Or, at least there is now. The published road map is loaded (clocks-in at 13 pages) with interesting ideas and proposals for ASP.NET AJAX v-Next and beyond, so I highly encourage you to take a minute to review it if you're an ASP.NET developer. If you're short on time, though, I've done the reading for you and here are some highlights:

  • MS is going to bring some order to the release schedule of ASP.NET AJAX, it's tools, and it's controls by moving towards more "normal" CTP, Beta, RC release events
  • MS is going to add many features to its client-side scripting libraries, further imitating the features of libraries like jQuery. CSS DOM selectors, Chainable DOM generation, and CSS-based event targeting are all proposed enhancements.
  • MS is going to add "flexible" drag & drop and animation frameworks to the client libraries (a la jQuery, YUI, etc.)
  • MS is going to build client-side data source controls (!) to enable complete client-side data operations. The controls will have corresponding server controls for easy setup.
  • MS is going to invest heavily in the Ajax Control Toolkit with plans to add more complex controls in to the suite. Proposed controls include (quoted from road map):
    • Grid: a client-side, templated grid control with client-side sorting, paging, and editing
    • Treeview: a client-side, tempalted and web-service aware tree with a full client-side object model
    • Upload: an upload control that works outside of full postbacks with progress monitoring
    • Rich Text Editor: a simple, cross-browser and extensible rich text editor
    • Chart: simple and extensible charting, possibly based on Silverlight
  • MS is going to ensure ASPNET AJAX compatibiliy with ASPNET MVC and other non-Microsoft Ajax frameworks/client-side libraries
  • MS is going to deliver a number of improved JavaScript dev tools, including improved IntelliSense and new JavaScript Build Tools (to aggreage, minify, etc. JS code at build time).
This obviously isn't everything from the 13-page road map, but rather a Reader's Digest version. On the surface, Microsoft's goals look ambitious, but they certainly sound like they'll benefit the ASP.NET developer community if met. And while most of the plans in the new road map represent v-Next ambitions, Microsoft isn't aiming to deliver everything covered ASP.NET AJAX v-Next. The following chart summarizes Microsoft's high-level release goals.


You can see that the client-side UI controls are "last" on the list right now, and everything is at least "likely" to make v-Next. As a component vendor, I find it interesting that Microsoft is choosing to wade-in more heavily to what has traditionally be a 3rd party supplied UI market. While 3rd parties like Telerik will leverage their agility and close relationship with customers to always build richer, higher performance, and more complete UI controls than Microsoft, you can never ignore a move like this that creates a "free option" from the creator of the framework. Time will tell if this is a good move for Microsoft or not.

In the mean time, what do you think? Should Microsoft try to deliver more advanced controls like client-side Grids and Treeviews or should they leave that to 3rd parties? Also, what do you think of Microsoft's ambitious plans for ASP.NET AJAX? Sound-off in the comments and don't forget to give Microsoft some feedback, too!

Read the ASP.NET AJAX Road Map now

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.