Warning: Stylesheets are not enabled in your mobile device. In order to properly view Socialtext Mobile, you will need to enable stylesheets in your browser options.

I spent most of today (so far) using the awesome YSlow tool from Yahoo. It's a firefox/firebug plugin that looks at some different metrics for displaying pages, and then suggests improvements. I'm helping Marc improve the performance of the http://howto.wired.com site. He's looking at creating reproducable performance runs using grinder, and I'm looking at the browser performance. Here's some of the stuff that YSlow suggests makes Socialtext slow:

An average page load of a Socialtext wiki page has 3 external stylesheets and 49 css background images. All of the images should be cached in the browser (for only a day). This is a lot of HTTP requests for first-time visitors. So in a site like the wired one, where we get hit hard if we're dugg, reducing the number of requests could be a big win. To reduce the number of requests, YSlow suggests combining external css and js files (we already combine all our javascript into one file) and using CSS Sprites to stick those 49 images into a single large image.

I think it would be difficult for us to combine the 3 css files on everypage load, as they are each for a different media type (screen, print and wikiwyg).

I'd like to experiment with the CSS Sprite approach, but I haven't yet.

YSlow suggests making your images and static content available from a CDN to improve performance around the world.

I see that we currently set expires headers on images to expire after 1 day. YSlow doesn't think this is sufficient. It suggests that in addition to the images, all css and javascript should have expiry headers of ~1 year. We already use unique URLs for each release, so this is easy.

I created a patch to add expires headers to all of our static content for 1 year.

Compressing content can also help speed times for slow users. Gzip compression of our entire javascript file brings the size from 692325 bytes to 132451 bytes (about 20% of the original size). I'm concerned about the CPU overhead of compressing the data, especially if our app is CPU bound, which I'm not sure about. It may not be so bad if we can cache the compressed static files.

While creating a patch for this, I discovered that mod_rewrite doesn't play well with mod_deflate (gzip). So to get gzipping to work, I needed to get rid of the rewrite rule we use for serving up static content. To do this, I patched gen-config to create a symlink: share/2.14.9.1 -> share/, so that our unique urls "just work".

I think the ideal thing would be to produce .gz versions of all our css and js during build time, and then have apache2 serve up the gzipped content if the browser can accept it. --lukec

We can compress javascript sources by stripping out comments and whitespace which can further shrink our javascript. I patched share/javascript/Makefile to use JavaScript::Minifier, which combined with gzip takes our js down to < 100k, 14% of the original size.

YSlow also suggests not using etags, unless they really are useful. Etags by default use inodes, so if you have multiple backend servers serving content, the etags are likely not correct. They also take up space in the header, so YSlow suggests they be turned off. It's a single apache config: FileEtag None. In our case, the Etags are correct, as we only have one backend server. YSlow's argument is that Last-Modified is just as good for this case, and turning etags off saves some bytes.

So I've got several patches for these suggestions. I'm not sure we want to apply them all, but it's something we can consider.


I'm glad you're using YSlow, I think it's a neat tool.
I was yammering about it quite a lot a few weeks ago-- YSlow is what pointed me to the caching problems with combined-source.js and the too-short Expires headers.

contributed by chris mcmahon on Sep 10 4:48pm


Aren't Etags helpful if you assume the Etag is correct? I'm not sure how wired works, but I thought there was only one back end server. So therefore only one inode, mtime, etc. So Etags should be helping there I'd imagine.

I just updated that part. Etags are indeed correct, but they're not much better than Last-Modified. It's a minor issue either way. --Luke

contributed by Matthew O'Connor on Sep 10 5:51pm


I already changed the expires headers to be 10 years. Hasn't that shipped yet?? It should have.

contributed by Kevin Jones on Sep 10 10:53pm


Merged to trunk yesterday for next release.

contributed by Jon Prettyman on Sep 11 8:15am

Page Last Updated: Sep 12 2:10pm by Luke Closs
Socialtext v3.7.5.4