more communities

Over the weekend, we rolled out a few speed improvements to the Stack Overflow engine.

First, we did a quick pass with ANTS Profiler (which is great, by the way) and identified a few places where redundant or unnecessary database queries slipped into our code. We like to do this every few months on common pages as a sanity check. We start a trace, refresh a given page 50 times, then view the hot code paths in the trace. It’s almost always database queries gunking up the works, but once in a blue moon we’ll write code so bad that it actually registers in the hot code paths. Anyway, the golden rule is to measure, then optimize, and that’s what we try to do.

We also took a long, hard look at optimizing the browser cookies we’re sending down to clients (and thus, clients are dutifully sending back to us in each HTTP request). You’d be surprised how big an impact on performance cookies can be. We were able to remove our ASP.NET forms authentication cookie entirely, and cut the length of our standard cookie key in half. I also removed a number of cookies that the /login page was storing which weren’t really necessary. In my testing our typical cookie is about 360 bytes now, compared with over 500 bytes before. Over time, these old unnecessary cookies will fall away naturally, but you may want to clear your domain cookies manually if you want the fastest possible Stack Overflow family browsing experience.

This isn’t as new, but it’s worth mentioning. A few weeks ago, we turned up the HTTP GZIP compression level for dynamic content from the default of 0 to 4. That’s ever-so-slightly slower, but offers an additional 10% reduction in page size. The tradeoff between CPU performance and file size for this setting is documented in exhaustive detail by Scott Forsyth and the “sweet spot” is definitely 4.

(Another item that similarly isn’t new, but always a solid best practice, is to minify your JavaScript and CSS. We’ve had our build script set up to do this for months, using the Java based YUI Compressor.)

We’ve been long time users of YSlow, and more recently Google Page Speed. Some of the recommendations these tools make are only sensible if you are Google or Yahoo (a very rare and select club of the ‘gee, that’s a nice problem to have’ variety) — but many of them are indeed essential no matter how big your website is.

When the browser makes a request for a static image and sends cookies together with the request, the server doesn’t have any use for those cookies. So they only create network traffic for no good reason. You should make sure static components are requested with cookie-free requests. Create a subdomain and host all your static components there.

If your domain is www.example.org, you can host your static components on static.example.org. However, if you’ve already set cookies on the top-level domain example.org as opposed to www.example.org, then all the requests to static.example.org will include those cookies. In this case, you can buy a whole new domain, host your static components there, and keep this domain cookie-free. Yahoo! uses yimg.com, YouTube uses ytimg.com, Amazon uses images-amazon.com and so on.

Another benefit of hosting static components on a cookie-free domain is that some proxies might refuse to cache the components that are requested with cookies. On a related note, if you wonder if you should use example.org or www.example.org for your home page, consider the cookie impact. Omitting www leaves you no choice but to write cookies to *.example.org, so for performance reasons it’s best to use the www subdomain and write the cookies to that subdomain.

We registered the domain sstatic.net for this purpose a month ago, and I’m pleased to announce that all the static resources for the Stack Overflow family of websites are now hosted at sstatic.net. This domain is of course cookieless and optimized for serving static content with the lowest possible overhead (and, as before, a far-future expires header, so zero requests are made to the server for cached static elements).

Using another server for your static content is also a rudimentary form of load balancing; we’ve shaved off hundreds of thousands of requests from our primary servers and delegated them to another server explicitly optimized for and dedicated to that task. Web browsers also tend to “parallelize” their load patterns for the page when they see resources coming from different domains — or a different subdomain, at least.

Anyway, we believe that performance is a feature, and we’re serious about the Stack Overflow family of sites being as fast as we can make them. We continue to revisit our performance every couple of months and try to improve it a little more each time.

As for “performance is a feature”, there is a great article about Amazon (yes, I know, Amazon is in that “if you’re Google or Yahoo” league) that has this nice punchline of “Amazon found that +100 ms increase in response time equaled -1% sales”, or if you want more concrete numbers, “every extra millisecond the page takes to load costs Amazon.com almost six million lost dollars in revenue”:

Normally I would recommend using a more lightweight web server than IIS to get rid of the headers and to reduce the load even more by simply not having to load so many unnecessary features (like authentication), but I think that is not a good idea as IIS is at least proven in high-load situations.

YSlow has helped us change our perception of web site performance dramatically over the last 12 months. It’s a fundamental tool in providing an exciting user experience. A _must_ tool in any developers arsenal, IMO.

Also, if you slap haproxy in front of your IIS server, you might be able to use that to just drop the Server and ETag from your response with little to no performance hit, while gaining some other advantages too, like the ability to drop connections that are taking too long.

@Jarrod Dixon : Cheers! Any sites that could give it a go would be awesome :) Would love to see if it has some good millage in some prod build systems :)

If you ever do get a chance to give it a roll, Jarrod, please post any feedback on the codeplex sub-site. The more feedback, then closer I can get it to being helpful to peeps :) (and more so from the time you first gave it a quick go, without much luck).

If you’re serving your static content from one server, don’t you want ETag’s there? That seems like exactly what they’re designed for. Even for ASPX / CSS / JavaScript, ETag’s are supposed to facilitate browser caching, and Yahoo’s just recommending removing them for webfarms, right? I’m just confused here.

Did you do anything specific to your static server to optimize for static conten?

I noticed you’re using querystrings to version your Javascript references. Do you have some slick system to handle those version numbers?

I heard that sissies play seafoam green plastic bass guitars? I heard that from a lot of people, but I thought I’d ask.

Thanks for tips. We’ve been gradually make a number of these changes at LocateTV, compression, minifying and hosting static stuff on another server. One of the things we haven’t done is go cookieless on the static stuff because our cookies are set to .locatetv.com instead of www. I hadn’t thought of registering a new domain as a solution – an excellent idea.

One of the changes we made recently was to combine all our js (including all jQuery plugins and other 3rd party code) into a single file at build time. We then minify the combined file (using ! for comment sections that have license details so they don’t get stripped) so the are much fewer HTTP requests. This, along with some pretty mind bending spriting (CSS offset madness!) really has helped with the overall performance of the site.

Thanks Jeff. I really love how fast StackOverflow is. Pages load and render almost instantly. At work, I have to support SharePoint, and people keep trying to convince themselves that our SharePoint users will be satisfied with 5-6 second page loads. I don’t think they will be. Speed is a killer feature.

Check out the book “Even Faster Web Sites: Performance Best Practices for Web Developers”. The author has also an earlier book. It has some good tips. (I am not sure but the author might be YSlow’s author or is a dev in that Yahoo’s team)

> Why / how is this domain blocked? And how do we get it unblocked at your place of employment?

It is whitelist-based (as far as I can tell). Any site that isn’t on The List Of Acceptable Content Types is automatically blocked. So it’s possible that it could get unblocked, but just hasn’t had time to be noticed and categorized yet. (The message says: “Your request to access the website “http://sstatic.net/” was denied because of its content categorization: “none””. )

I don’t even know who’s in charge of the firewall; this is a big place and I’m relatively new.

Anyway, I can still read, edit, and (probably) answer; I just can’t comment or vote to close/delete, and it looks incredibly ugly.

Rather than using the domain “sstatic.net”, you should get an even better performance boost by referencing the public IP address of the server with the static content. The browser wouldn’t need to perform a DNS lookup for “sstatic.net”. This would be a significant improvement for users with slow DNS servers.

If the server changes IP addresses, you would just update a web application configuration instead of a DNS entry. Bookmarking these static objects wouldn’t work, but I doubt anyone would care to bookmark referenced JavaScript, CSS, or graphics files.

hi jeff, i am working on asp.net mvc for the first time and have been struggling to input a value (integer) from the user in particular .aspx view file. i need to pass the input integer as a parameter to an Action method in a controller through an Actionlink i have in the .aspx.

Could you please help me with this!

i tried textboxes (asp and html) but they dont meet my req. html.textbox or require me to store the input value from the user in a Model attribute inherited by the aspx.