ThemeRoller 2.0: Refactoring for Speed


These are my notes from Doug Neiner's talk at the jQuery 2010 conference in Mountain View, California. You can find Doug on Twitter @dougneiner

ThemeRoller 2.0 doensn't have a lot of new features, it just works faster. I was considering calling it SnowThemeRoller.

Overview of ThemeRoller

ThemeRoller allows you to easily apply colors, patterns, opacities, images and textures that you can apply to your site on the fly; once you've configured your theme you can download it and apply it.

Right now ThemeRoller is running on a three-server cluster from mediatemple; it's very popular. We're trying to alleviate these issues brought on by this new popularity.

ThemeRoller 2.0 Improvements

  • Speed Improvements: Server image generation is 40-50x faster. Some older image generation algorithms took a dozen seconds, and we've reduced that to under a second. We've removed our dependency to ImageMagick, which is a memory hog when you're using it. The client-side image and CSS generation is exciting: it's the perfect use case for HTML5 Canvas. It runs in all browsers with different limitation, but FireFox, Chrome and WebKit works really fast because everything happens in the browser.

  • JSON Structure: We've moved to a nested, overridable JSON structure. The names also make a lot more sense if you're working with the JSON directly.
  • Updated Bookmarklet
  • Offline Support: You can run the entire app offline, e.g. at a meeting with a client.

Client Side CSS Generation

The current ThemeRoller goes out to the server to get an updated CSS, which we wanted to speed up.

We looked at using rule editing. However, IE and FireFox each do their own thing, and even when using common libraries you run into problems with Opera and WebKit.

Eventually we appended a style element to include live CSS:



We use simple tokens like:


The CSS generation is straightforward. [Doug walked us through the code that generates and replaces the CSS in the user's browser on the fly.]

HTML5 Canvas Workflow

  • Load the template image
  • Create a canvas
  • Size the canvas (clears existing content)
  • Set the composite mode and opacity
  • Draw the template image
  • Return the dataURL
  • Add the dataURL to the CSS

Send as Little Data as Needed

Send JSON, not HTML, wherever possible. Provide overrides instead of full data whenever possible. We're starting with a basic theme; if you change two values, instead of sending all the values back to the server, it only sends back the values that have changed. When you're trying to speed up your API, try to decrease the amount of data that is being sent.

We anticipate being able to reduce our server load to the extent that we'll be able to move down to one server, from the two or three we have now.

Release Schedule

We'll be rolling out the back-end, followed by the front-end, followed by some extra fields and levers after that.

Did you enjoy this post? Please spread the word.