Category Archives: Web

Pragmatic Bookshelf Website Performance

I’ve been a big fan of the Pragmatic Bookshelf series, in particular their monthly online magazine. The magazine are downloadable in PDF, .mobi, and .epub formats, and browsable online in HTML format.

Browsing through the latest couple of issues, I noticed a distinct slowness as some of the images were downloaded. This is usually a hint that a high resolution image is being referenced, but being “cropped” down to a smaller size with the height/width attributes in the HTML. For example, see this story about Ruby Bundler and look at the red ribbon image. The source image is 693×693 but is being displayed as 190×190. It’s also a very high quality level and weighs in at 203KB – compare with the page itself which is only about 10KB. Resizing this JPEG image in PhotoShop dropped the size down to 6KB (or 3KB at medium quality), with no visible difference on the web page.

With those possible savings, I looked closer at the rest of the Magazines pages to see what other performance improvements could be gained, following “best practices” advice from tools like YSlow, PageSpeed, and Rather than trying to solve everything at once, I’ve suggested improvements in priority order. I’ve also focused on content served via because that will be the easiest to change. The 3rd-party widgets like Digg and Reddit can be dealt with later, if at all. (Performance improvements on 3rd-party widgets usually need to come from the 3rd-party itself.)

Step 1: Images Sizes

As a first step, update the publishing process to reduce image sizes required in all page downloads. Specific changes:

  • Re-size images correctly for their use on the page (i.e., don’t re-size via HTML height/width)
  • For JPEG images, save at the lowest quality that still looks good (e.g., Medium or 50)
  • For PNG images, convert to 8-bit if quality is acceptable
  • Run YSlow (lossless compression) on all images and switch to the compressed versions
  • Switch GIF to PNG where recommends (typically for very small images, excludes any using alpha transparency)

Step 2: Image Expiration and Hosting

Continuing to improve the image delivery, there are a couple of specific changes that can help here:

  • Add “expires” settings for images – at least a week, but preferably a “far future” expiration date with version increments in the filename (header_v1.jpg, header_v2.jpg, etc.)
  • Move images currently served on to one of the or domains (which do have image expiration set correctly); also seems to be a bit slower when serving images

Step 3: Better Handling of CSS and JavaScript

On the CSS/JS side, there is some room for improvement in the number and size of these static files:

  • Reorganize and combine the CSS files, removing the use of “@import” as well; currently there are 7 unique CSS files for the core page design (i.e., not counting 3rd-party widgets). These could be combined with the use of integrated media selectors rather than having multiple entries
  • Minify CSS and JavaScript (e.g., using YUICompressor)
  • Add versioning to CSS/JS files and set a far-future expires time

Step 4: Miscellaneous

Finally, here are some additional fine-tuning adjustments that will also help:

  • Confirm whether or not store.js is needed on all pages – remove if not
  • Convert images in page templates to use CSS Sprites
  • Switch Google Analytics to load asynchronously and include JS file at page bottom
  • Change source of diggthis.js from to to avoid extra redirect
  • Change source of button.js from to to to avoid extra redirect

Hopefully the above list gives a good roadmap for the improvements that can be made on a site like this. Most of this hopefully doesn’t require very significant changes to their build process, but should give dramatic improvements for site visitors.

Performance Makeover:

After my team launched a new site design and blog system for the Yahoo! Developer Network, I decided to review the performance of this site to see where it could be improved. In summary, after removing one performance-hogging widget and following recommendations from YSlow and Page Speed, the site should be running much faster now.

This site is running on a shared web host from Pair Networks and is powered by Movable Type. It’s not a very complicated site, but is a good illustration of the improvements possible by following web performance best practices.

My first step was to run the home page through WebPageTest to get a good overview of the problem spots. I was surprised to see about 60 JavaScript and image requests just for the Lijit search widget! On the plus side, they do have expires times set for the images, and no cookies are going back to the domain, but this is still a ton of content to be loaded for the first-time viewer. Based on these numbers, and the fact that I was just experimenting with it, my first step was to remove the Lijit widget.

After removing the Lijit widget, the numbers improved dramatically:

Measure Original After Remove Lijit Improvement
YSlow 78 83 6%
Page Speed 74 83 12%
Requests 59 17 71%
Size (KB) 257 173 33%
Doc Complete (sec) 4.0 1.88 53%

With the big piece out of the way, now I could focus on the remaining issues, uses YSlow, Page Speed, and as my guides. I implemented a series of improvements:

  • Removed Mint tracking; the Mint UI looks cool, but this is redundant with Google Analytics which I’m already using
  • Removed Yahoo! Buzz badge; I don’t think anyone ever “buzzed” one of my stories so this isn’t needed
  • Added gzip compression for text files (HTML, CSS, JavaScript) served off my domain; I didn’t realize that my host provider had mod_deflate installed, so I was able to configure it via .htaccess files
  • Reduced image size by converting PNG files to 8-bit, and then running everything through SmushIt
  • Changed Google Analytics to use the asynchronous version
  • Merged separate print CSS into the main stylesheet, using “@media print” designators
  • Modified my CSS/JavaScript combo handler to include Last-Modifed and Vary headers in the response, for improved cacheability
  • Minified JavaScript using YUI Compressor
  • Minified CSS using cssmin.js
  • Moved images from to Amazon S3 hosting

After all of the above, the results compared to the original were pretty good:

Measure Original Perf Changes
& Remove Lijit
YSlow 78 96 23%
Page Speed 74 97 31%
Requests 59 14 70%
Size (KB) 257 77 70%
Doc Complete (s) 4.0 1.28 68%

Observations and further things to investigate:

  • Google Ads still drag down the page grades a bit, but don’t have a huge impact on page load time so I’m leaving them in for now; I’m only running ads on individual entries now, not on the home page
  • WebPageTest helped me understand lossy optimizations beyond SmushIt; for example converting 24-bit PNG to 8-bit, and saving JPEG with lower quality level
  • I tried using YUI Compressor to minimize my CSS, but it broke the site layout slightly, so need to investigate this further
  • One of the Page Speed recommendations is to minify the HTML; I tried that manually and found about 5% further reduction in delivered file size, but it’s not easy to implement on the dynamically-built Movable Type pages so will ignore that rule for now
  • The images are on Amazon S3, but not yet hosted via Cloud Front which is a true CDN; I plan to do some testing with this both ways to see how much it helps
  • I’d like to work S3 and SmushIt into Movable Type workflow, hopefully in a plugin

Overall this quick makeover was a good illustration of the available performance tools. Like any optimization, you need to make sure to measure first to identify the slow spots. I would also suggest not blindly following every recommendation, but aim to solve things in the proper way for your own environment.

A Clear Explanation of Tracking Cookies (All Things Digital)

Just ready a story relating to Yahoo on All Things Digital today and noticed they do a really nice job of explaining their use of tracking cookies:

Some of the advertisers and Web analytics firms used on this site may place “tracking cookies” on your computer. We are telling you about them right upfront, and we want you to know how to get rid of these tracking cookies if you like.

I’m impressed with the visual treatment and the fact that they’re very upfront with this information. Of course you’ll only see this message once (or whenever you clear all your browser cookies), but it’s a big improvement over most sites.

For more details on tracking cookies, see the EFF’s coverage of online behavioral tracking.

Click the image below for a full size screenshot:

All Things Digital Cookie Tracking Notice
All Things Digital Cookie Tracking Notice

Fiddler Web Debugging Proxy With Any Browser

Fiddler is an extremely useful tool for debugging any web traffic on Windows environments. From their website:

Fiddler is a Web Debugging Proxy which logs all HTTP(S) traffic between your computer and the Internet. Fiddler allows you to inspect all HTTP(S) traffic, set breakpoints, and “fiddle” with incoming or outgoing data. Fiddler includes a powerful event-based scripting subsystem, and can be extended using any .NET language.

I originally used Fiddler back the early days with Internet Explorer, but have recently picked it up again for use with several different browsers. Although some browsers have more native capabilities now (like Firefox with FireBug), using Fiddler consistently makes it a bit easier to concentrate on the problem at hand rather than the tool itself. Fiddler can also handle and decode HTTPS traffic now.

Setting up Fiddler with different browsers is pretty straightforward:

  • Internet Explorer: No changes needed; when Fiddler is running it will automatically pick up all IE traffic
  • Google Chrome: Same as IE (automatic)
  • Apple Safari: Same as IE (automatic)
  • Opera: Same as IE (automatic), but may need to start Fiddler before Opera
  • Firefox: Change network options to use the HTTP proxy at address, port 8888; also see the Fiddler Firefox addon
  • Curl: Curl from the command line is very useful when testing webservices; to route through Fiddler, just include the proxy option like --proxy
  • Other Apps: See the Configuring Clients help page for any other application which lets you configure a proxy
  • Mac/Linux: For cases where you need to debug on a different platform, you can still route traffic through Fiddler on a Windows system; after starting Fiddler, set up the application on Mac/Linux to use the proxy at windowshost:8888

For more background and “how-to” guides to get started with Fiddler, check out the Fiddler help page.