Announcing Clojure Miniprofiler

This is a blog about the development of Yeller, The Exception Tracker with Answers

Read more about Yeller here

One of the most important things for me in Yeller’s development is that it is fast. Not just on the backend, where Yeller processes hundreds of thousands of events a second, but also on the user interface. Slow user interfaces are noticeably more difficult to use, and frustrate users.

Web UI performance is a tricky beast, and involves a whole load of different factors. However, a key part is backend performance - if your server doesn’t respond quickly, your users are going to have a bad time.

.Net and Ruby have been enjoying the wonderful Miniprofiler project for a while now. Miniprofiler lets you profile the page you’re browsing, as it happens, in both production (for admin users only) and development. It gives you a deep dive into what database queries happened to render a page, which views were expensive, and so on.

Clojure Miniprofiler is a simple port of Miniprofiler to Clojure. It’s a simple ring middleware, that’s very customizable, and can profile any code you call into.

What does it look like?

An example would be handy right now

As soon as I started using Clojure Miniprofiler on Yeller, it turned up a number of small things that were easy to fix. Duplicate database queries that were taking quite a while, duplicate view rendering and so on. But there was one change that had a big impact on performance. Let’s jump in:

Yeller uses the popular hiccup library for html rendering. However, after turning on miniprofiler I noticed that rendering hiccup was the majority of Yeller’s rendering time on key pages (both show and render-layout are hiccup rendering times):

Here’s the overall pageload time before:

This matches well with my experience with rails apps - rendering html is the dominant factor in pageload time. Not querying the database, not the web framework itself, just plain-jane html rendering.

Doing some digging around in hiccup’s source code, I found that it can precompile html code generation - dramatically reducing the number of data structures allocated and improving performance. So, I wrote a simple macro that I wrapped some key html generation functions in:

(defmacro precompile [view-name & body]
  `(clojure-miniprofiler/custom-timing
     "hiccup"
     ~view-name
     ""
     ~(apply hiccup.compiler/compile-html body)))

And away we go:

That’s a 3x performance improvement, for an overall render time of 126ms. Not too shabby!

Try out Clojure Miniprofiler

If you run a clojure webapp, you should check out Clojure Miniprofiler. It takes almost no time to get setup, and then gives you huge performance insights into your webapp.

The source is up on Github

This is a blog about the development of Yeller, the Exception Tracker with Answers.

Read more about Yeller here

Looking for more about running production applications, debugging, Clojure development and distributed systems? Subscribe to our newsletter: