We’ve said for a while that HTML5 will change the way you use the web, but not all browsers are ready for the big change. This interactive chart highlights which features are still missing in your browser of choice. More »
Blog Archives
The HTML5 Readiness Chart Highlights How Well Your Browser Handles the Future [Infographic]
Do you know about this undocumented Google CDN feature?
By now, you probably already know that Google hosts jQuery on its AJAX APIs CDN, free of charge. As I’ve discussed here in the past, I’m a big fan of using their CDN to achieve decreased latency, increased parallelism, and better caching.
If you’ve explored the AJAX APIs documentation a bit, you may know that jQuery UI is also hosted on Google’s CDN. Unfortunately, since jQuery UI plugins depend on a ThemeRoller theme, using a CDN for jQuery UI isn’t as easy as with jQuery itself.
Or, is it?
My <head> is in the cloud
While poking around a couple months ago, I stumbled upon something that I’ve found extremely useful: An entire jQuery UI theme hosted on Google’s CDN!
Not only is the theme’s CSS stylesheet there, but all 14 of the theme’s images are hosted in the correct relative location too. That means you can apply the entire theme to a page with a single CSS reference and no local files.
Even better, while JavaScript and CSS includes are unable to take full advantage of the increased parallelism a CDN offers, the theme’s images do. This makes loading the theme from Google’s CDN particularly effective.
Using it
Using this on your own pages couldn’t be easier. There are no files to download, no paths to worry about, and no configuration is required. Just a reference to jQuery, jQuery UI, and the ThemeRoller theme you want to use will is all you need.
For example, if you wanted to build a quick demo of the jQuery UI Tabs plugin, use these references in the head of your page:
<!DOCTYPE html> <html> <head> <!-- To avoid horizontal scrolling in this code listing. --> <base href="http://ajax.googleapis.com/" /> <!-- Reference the theme's stylesheet on the Google CDN --> <link href="/ajax/libs/jqueryui/1.7.2/themes/start/jquery-ui.css" type="text/css" rel="Stylesheet" /> <!-- Reference jQuery and jQuery UI from the CDN. Remember that the order of these two elements is important --> <script src="/ajax/libs/jquery/1.3.2/jquery.min.js"></script> <script src="/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script> <!-- Initialize the tabs when the document is ready --> <script type="text/javascript"> $(document).ready(function() { // See the jQuery UI Tabs documentation for // more information about how this works. $('#tabs').tabs(); }); </script> </head>
Note: You shouldn’t use the <base> tag like this in your pages. It affects all links on the page, not just those in the <head>. I’m just using it here to avoid horizontal scrolling (the bane of my existence when posting code here).
Then, just a bit of corresponding markup in the body of the document (see the jQuery UI Tabs documentation for specifics):
<body> <div id="tabs"> <ul> <li><a href="#tab-1">Tab 1</a></li> <li><a href="#tab-2">Tab 2</a></li> <li><a href="#tab-3">Tab 3</a></li> </ul> <div id="tab-1"> <p>These tabs were created with JavaScript, CSS, and images hosted on Google's AJAX APIs CDN.</p> <p>Thanks, Google!</p> </div> <div id="tab-2"> <!-- Tab 2's content goes here. --> </div> <div id="tab-3"> <!-- Tab 3's content goes here. --> </div> </div> </body> </html>
That HTML (without a single file or image hosted locally) results in this:

Don’t like the theme in my example? Don’t worry, because all 24 of the standard ThemeRoller presets are also hosted on the CDN. See the end of this post for a full listing.
Nothing’s perfect
There are a couple of potential issues when using these CDN hosted themes.
First, these themes aren’t minified. Minification shaves about 20% off the size of an average ThemeRoller theme’s CSS, which is definitely worthwhile. Hopefully, minified versions will be available at some point (assuming I didn’t miss ones that may already be hiding there somewhere). In the meantime, Google does properly gzip compress them though, which makes the difference less significant.
Second, if you normally customize ThemeRoller’s CSS or images manually, this probably isn’t for you. Lacking control over the base CSS style is something that you can work around, but isn’t worth the complexity and extra HTTP requests.
However, you can still reference the CDN’s images from custom CSS, by using absolute paths.
Conclusion
Overall, this seemingly small feature has been surprisingly useful in my day-to-day development. While it’s technically not very difficult to download and set up local ThemeRoller themes, there’s more friction to it than I care for. Boiling the entire process down to a single CSS reference removes all of that friction.
Even if you don’t like the idea of relying on a CDN hosted theme for production sites, this is great for prototyping. Anything that makes prototyping faster is a big win, because it allows you to try more ideas in the same amount of time.
What do you think? Does this sound useful to you? Are you comfortable leaning on Google’s CDN for your entire jQuery UI theme? Would you use this in production?
Full Theme Listing
The URLs below reference jQuery UI v1.7.2 themes. If 1.7.2 isn’t the latest version at the time that you’re reading this, you should be able to replace 1.7.2 in the URL with the current version and find a current theme hosted on the CDN.
Click any of the thumbnails to view that theme on ThemeRoller.
Click any of the input fields to select the full URL to the theme’s CDN hosted CSS file, ready for copy/pasting into your page.
Attention RSS Readers: You will probably need to view this full post in your browser to see the input fields. Click here to open the post and skip directly at this point in the post.
###
Originally posted at Encosia. If you’re reading this elsewhere, come on over and see the original.
Do you know about this undocumented Google CDN feature?
11 keystrokes that made my jQuery selector run 10x faster
As an ASP.NET developer working on the client-side, one problem you’ll encounter is how to reference the HTML elements that ASP.NET web controls generate. All too often, you find yourself wasting time trying to reference TextBox1, when the element is actually rendered as ctl00_panel1_wizard1_TextBox1.
Much has been written about this, including a post of my own, so I won’t go into detail about many of the workarounds. Instead, I want to take a closer look at the performance drawbacks of one popular solution: the [attribute$=value] selector.
By specifying id as the attribute in this selector, you can avoid ASP.NET’s ClientID issues completely. No matter what the framework prefixes your rendered elements with, they still “end with” the ID you specify at design time. This makes the “ends with” selector a convenient alternative to injecting a control’s ClientID property via angle-brackets.
However, are we trading performance for this convenience? If so, how much?
When Craig Shoemaker asked that question while interviewing me for an upcoming episode of Polymorphic Podcast, I realized I didn’t know the answer as clearly as I’d like. So, I decided to do a bit of benchmarking.
In this post, I’ll share the results of that benchmarking, and show you one way to significantly improve the performance of this convenient selector.
The test scenario
One difficulty when analyzing selector performance is that they all perform well on small test pages. Most performance issues aren’t readily apparent until a page grows in complexity and contains many elements. This can easily leave you overly confident in techniques that survive a simple proof of concept, but don’t scale well to practical usage.
Rather than construct a complex demonstration page from scratch to test against, I decided to use an existing page. With over 160 comments at the time of writing (and testing), the Highslide JS .NET project page is an ideal candidate. Its 1,000+ DOM elements are well suited to expose poorly performing selectors.
Enclosing each comment on the page, there’s a div like this one:
<div id="div-comment-35496" class="comment"> <!-- Comment content here --> </div>
If you imagine that the “div-“ prefix is “ctl00_”, these IDs are a great substitute for the ClientIDs that ASP.NET controls render within naming containers.
So for purposes of testing, I attempted to select the element div-comment-35496 on that page, assuming that I knew its ID of comment-35496 at design time and that the “div-“ prefix was added at run time. This is identical to the process of selecting the div rendered by an ASP.NET Panel control within a Content Page, for example.
Test methodology
To benchmark each selector, I used the following JavaScript:
var iterations = 100; var totalTime = 0; // Repeat the test the specified number of iterations. for (i = 0; i < iterations; i++) { // Record the starting time, in UTC milliseconds. var start = new Date().getTime(); // Execute the selector. The result does not need // to be used or assigned to determine how long // the selector itself takes to run. $('[id$=comment-35496]'); // Record the ending time, in UTC milliseconds. var end = new Date().getTime(); // Determine how many milliseconds elapsed and // increment the test's totalTime counter. totalTime += (end - start); } // Report the average time taken by one iteration. alert(totalTime / iterations);
This simply executes the selector 100 times, recording how many milliseconds each run takes, and then determines the average.
I had originally recorded and displayed an array of each individual time, but found there was very little variation and stopped tracking each execution. The average is good enough for these purposes.
For each selector, I ran the test five times and then averaged the results, resulting in an average across 500 separate executions in semi-isolated batches. Then, I repeated the process for each major browser.
CERN probably won’t be flying me out to work on the LHC with this level of rigor, but it’s accurate enough for measuring the relative performance change between different selectors.
The baseline
jQuery’s #id selector leverages browsers’ native getElementById routine. Though slower than calling getElementById directly, this is a very fast way to reference our div as a jQuery object:
$('#div-comment-35496')
As you may expect, this browser assisted selector is fastest. In fact, every major browser consistently performed this in less than one millisecond in my testing. Most in less than a third of a millisecond.
To safely use this selector in ASP.NET, we have to manually inject the a control’s ClientID property. Otherwise, any naming container added, removed, or renamed would break our client-side code.
You’ve probably seen that accomplished like this:
$('#<%= comment-35496.ClientID %>')
It looks messy and requires a bit more effort, but it’s fast.
ASP.NET 4.0’s ClientIDMode property promises to eliminate this inconvenience in the long-term, but we’re stuck with it for now. For that matter, with many projects still using ASP.NET 1.x and 2.0, slow to adopt the latest version, we may be stuck with the problem for quite some time to come.
Convenience
To avoid the messy work of manually injecting ASP.NET’s rendered ClientIDs, you may have seen the suggestion that this is an easier way:
$('[id$=comment-35496]')
Indeed, this will successfully select the element that we’re after. Since its ID is div-comment-35496, searching for an element whose ID “ends with” comment-35496 works as desired.
Eliminating the angle-brackets is aesthetically pleasing and it’s less up-front work, but what about performance?
jQuery’s selector engine implements “ends with” by performing this test on every element in question, where value is the attribute you’ve specified and check is the string that you’re searching for:
value.substr(value.length - check.length) === check
That’s not so bad if you’re only doing it once, but doing it for every element on the page is a different story. Remember our test page has thousands of elements.
What’s worse, jQuery has no way to know that only one element should match the pattern. So, it must continue iterating through to the end of the page, even after locating the single element that we’re actually interested in.
How bad is it? Over the course of several hundred executions on the test page, I obtained these average speeds for a single $= selector execution in each browser:

The Chrome numbers are unsurprising, given its speedy V8 JavaScript engine. IE8 and Firefox 3.5 perform admirably too. These newer browsers all executed the selector very nearly as quickly as document.getElementById.
However, IE7 and Firefox 3.0 are substantially slower when executing the “ends with” selector. Remembering the non-trivial difference that Firebug made in this interesting post about JSON parsing speeds, I also tested with and without Firebug enabled in Firefox 3.0 (which turned out to be a significant factor here too).
Even though we’re only talking about milliseconds, the penalty in older browsers is too large to ignore — especially when the vast majority of users are still on IE6, IE7, or Firefox 3.0, not the new generation of faster browsers.
Convenience optimized
Remembering that the #id selector is quick because it leverages the native speed of getElementById, we can help jQuery execute the $= selector more efficiently.
If we modify the selector to descend from an HTML tag before performing the “ends with” search, jQuery can use getElementsByTagName to pre-filter the set of elements to search within. Since getElementsByTagName is a native browser routine, it is much faster than jQuery’s interpreted selector engine.
For example, since we know the element we’re after is a div, we could optimize the previous $= selector like this:
$('div[id$=comment-35457]')
The benefit is substantial:

The optimized selector runs more than twice as quickly in IE7 and Firefox 3.0!
Along the same lines, jQuery’s Sizzle engine is able to select CSS classes faster than it can perform substring searches within arbitrary attributes. So, the selector can be further optimized by descending from both an HTML tag and a CSS class.
Since the particular div we’re testing against has a CSS class of comment, let’s try this selector:
$('div.comment[id$=comment-35457]')
The results?

IE7 doesn’t improve much, but Firefox 3.0 shows another excellent increase in its performance. The reason that Firefox shines here is that it implements a native getElementsByClassName routine that IE7 doesn’t (though IE8 does).
While slower than the getElementById powered #id selector, these optimizations have given us a 3-10x speed increase while referencing exactly the same element as the original $= selector. That’s a pretty good return on the investment of typing a measly eleven characters (div.comment) in front of the selector!
A mountain out of a molehill?
This post may seem like a lot of effort to spend on a seemingly tiny performance differential. In fact, I almost considered leaving this one on the shelf, because it’s often difficult to sell the importance of milliseconds.
But, you know what? Milliseconds count! A performance difference of a few dozen milliseconds is a perceptible delay. A few hundred will alienate your users.
Research has consistently shown a strong correlation between fast sites and higher conversion rates, more user actions per visit, and user satisfaction. Compounded across the thousands or millions of times a particular function in your application will be used, it is absolutely worthwhile to invest a few minutes in order to save a few milliseconds.
Conclusion
I hope you’ve found this information useful. Without hard data, it’s difficult to decide which optimizations are premature and which are worthwhile. Especially since your page is likely to grow more complex over time, I think the data clearly shows that selectors which don’t directly target an ID should always descend from an HTML tag when possible.
Perhaps the most important takeaway is that you must keep in mind how easy it is to write one succinct line of jQuery code that results in a non-trivial loop. The real danger lies in putting a selector like $= within a loop yourself, unaware that what appears to be a simple loop is actually a relatively sluggish nested loop.
The other lesson here is that if speed is crucial, you should inject ClientIDs and use the #id selector (as in the baseline shown above). Even the most optimized “ends with” selector in this post still runs at least one order of magnitude slower than the direct #id selector.
Instead of simply posting that div.class[id$=id] is faster than [id$=id], I wanted to explain the sequence of events that led me to that determination. Armed with knowledge of how I optimized the “ends with” selector, I hope that you have a few new optimization tricks up your sleeve now.
###
Originally posted at Encosia. If you’re reading this elsewhere, come on over and see the original.
11 keystrokes that made my jQuery selector run 10x faster
4 ASP.NET AJAX JavaScript UI methods you should learn
Wrapping up my series on some of ASP.NET AJAX’s less utilized client side functionality, this post will take a closer look at some of ASP.NET AJAX’s JavaScript UI helper functions. These methods are great because they abstract away most of the tedious work that comes with supporting cross browser compatibility, leaving us with a nice, consistent API.
Specifically, I’m going to show you examples of using addCssClass, getBounds, getLocation, and setLocation to accomplish a few client side UI tasks.
Easily adding and removing CSS classes
A relatively underused feature of CSS allows you to directly apply multiple CSS classes to the same element. For example, maybe you’ve got an online test and want to style the test results to display correct answers in green and incorrect ones in red. This is one way you might do that:
.answerResult { font-weight: bold; } .correct { color: green; } .incorrect { color: red; }
Answer #1: <span class="answerResult correct">correct</span> Answer #2: <span class="answerResult incorrect">incorrect</span>
This is a clean solution to the problem. The markup is semantic and avoids repetition by splitting the highlight from the base styling. However, if we need to manipulate this on the client side, it’s going to take more work than is ideal.
Luckily, the ASP.NET AJAX client side framework provides helper functions to alleviate that complexity. DomElement’s addCssClass and removeCssClass are exactly what we need. Assuming the span was given an ID of answerResult, this is all that would be necessary to dynamically add the CSS for a correct answer:
Sys.UI.DomElement.addCssClass($get('answerResult'), 'correct');
I often use this technique in production by creating CSS classes with the same names as the status states of a field’s range of values. Then, when displaying that data, it’s trivially easy to also add some contextual styling with addCssClass.
Determining the size of an element
If you work on client side UI functionality long enough, you’re eventually going to want to determine the size of HTML elements at runtime. This turns out to be no fun at all, if you want to do it accurately cross-browser. Instead of suffering through that ordeal, you can use DomElement’s getBounds method. It returns an associative array with an element’s size and position.
For example, what if you’ve filled a GridView with an arbitrary amount of data and want to find out how tall it is? How would you go about that?
var height = Sys.UI.DomElement.getBounds($get('GridView1')).height;
It doesn’t get much easier than that, does it?
Locating and moving an element
The final methods that I want to take a look at are getLocation and setLocation. After all, the next logical step after finding the size of something is figuring out where it’s at and moving it around.
For example, let’s say you want to move a div, SomeDiv, 75px to the right:
var loc = Sys.UI.DomElement.getLocation($get('SomeDiv')); Sys.UI.DomElement.setLocation($get('SomeDiv'), loc.x + 75, loc.y);
Throw it in a loop and you’ve got yourself a basic animation:
for (i = 1; i <= 75; i++) { Sys.UI.DomElement.setLocation($get('SomeDiv'), loc.x + i, loc.y); }
Conclusion
You probably aren’t going to use these functions as often as $addHandler or the base type extensions. However, when you do need them you’re going to be really glad you know about them. They save a lot of work, and help to automatically ensure a level of cross browser compatibility that is tedious to constantly write from scratch.
###
Originally posted at Encosia.com. If you’re reading this on another site, come on over and take a look at the real thing.
