Pro tip: Increase webpage performance using sprite, data-uri and jammit

For quite some time at Josh Software, we have been concentrating on improving backend server performance. You can read about load testing and bench-marking and improving upload performance using nginx upload module. This post is about improving frontend performance by getting your pages to  load faster using techniques like sprites, data-uri and jammit.

These tools have been around for about a year now — and are highly recommended. First off – basics:

Data-uri

Data-uri provide a way to send binary data in-line in the CSS. So you can embed images (not links) directly into your HTML, CSS or even JS! For example:

.bullets {
   margin-left: 20px; background:
   url('data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
g9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC')
   top left no-repeat;
}

However, there are few disadvantages of data-uri, some of them critical enough to consider its usage!

  • Data-uri is limited to 32kb
  • Internet Explorer 7 and below do not support data-uri. (You would be surprised how many people still use IE7 and even IE6!)

Sprite

Sprites have been used since the 70’s but its a recent entrant for combining with CSS. Sprites have been heavily used in gaming and 3-D hardware graphics. A sprite is a bunch of images grouped together into a single image. A CSS Sprite uses the image offset to render inner images. A good example of sprite code is here.

In the CSS, we use the background-position relative to the sprite image! If a website which has 50 tiny images, 50+ requests are sent to the server just to render that page. Using sprites, it would be only 1 request for a single image. The remaining images are rendered as offsets of the sprite. This reduces my server load from 50 to 1 for the images! Considering network latency, HTTP headers processing etc. — this itself brings on a solid performance boost!

There are plenty of ways to generate a Sprite . There are a few good resources for generating sprites — there is also a topic floating on quora on this (my inspiration for the blog btw). I preferred to write my own quick sprite generator. The gist is available here.

Using it is simple.

# this creates a png, so don't add the extension
css = SpriteWriter.new("/path/to/images/folder", "/path/to/sprite/img", "/path/to/css")
css.generate

Some examples of the work we have used sprite is at List.ly. If you look at the details of this page, you would find a tp-sprite.png The corresponding CSS shows how it is used.

Jammit

Jammit is a top-grade asset packaging library. It provides excellent compression techniques. It is highly configurable and can be used in different pages in different ways. It can be used along with data-uri, so it provides state of the art techniques for caching and serving images, CSS and JS.

It is frequently said that data-uri have now replaced using sprites. However, I dis-agree! Browsers which do not support datauri should also be catered to.

Using Jammit now provides us one alternative:

“embed_assets datauri” can be turned on in jammit. This turns on data-uri support for only those browsers which support data-uri. Others will ‘automagically’ be served the unmodified stylesheets!

In this way, we can choose which technique we require to load pages faster.

However, Jammit does not support sprites & datauri together. In my next post, I plan to show how we modified jammit code to serve sprites or datauri depending on the browser!

So, we now crank out the best possible options to load pages faster for ANY browser – be it datauri or sprites!

Stay tuned for further updates here.

I hope you found this article valuable. Feel free to ask questions and give feedback in the comments section of this post. Thanks!

23 thoughts on “Pro tip: Increase webpage performance using sprite, data-uri and jammit

    1. Sprite being “a graphical overlay” would be more accurate.

      However, I guess, the aim of this post is not the get into the internal details of a sprite but how it can be used.

    2. I think the miscommunication is in the specific use of the word sprite. A sprite is (one of many definitions) one of the many single images from the larger resource. An image containing many smaller images to be rendered individually is a sprite sheet.

  1. Data-uri is limited to 32kb

    Afaik, this is only the case in IE8 and IE9. This limit is not present in other browsers

    1. Yes Ruudjah, you are right. This is a Internet Explorer statistic. However, most compression engines tend to not convert larger images into data-uri due to pending incompatibility.

  2. This seems like a way to inject nefarious JavaScript into a page beneath the radar of content scanners.

    I think it is irresponsible of you to be promoting this.

    1. Hi Steven,
      I guess you have mis-understood. Datauri and sprites are accepted techniques to increase page-loading performance. Jammit is a compression asset manager among other things.

      Content scanners will scan ALL rendered HTML — so if someone inserts malicious JS, it will definitely be scanned!

      Like vzmind has mentioned, I too am keen to see why is nasty. Please give more details.

    2. This is like saying you can do nefarious things with JavaScript, therefore the promotion of JavaScript is irresponsible.

  3. Damned Steven, that s frightning. Could you elaborate? Do you speak about a possible nasty use of data uri?

  4. Pingback: Quora
  5. hey Gautam. Interesting article.
    Did you actually do some performance testing with data uris? Because in a test I just did, my page load time actually increased – due to a larger css file. Even though my requests (for css images) have gone done.
    What’s your experience?

    1. We have used datauri in list.ly and performance is good. We dont have any benchmarks for this. If you are using same image multiple time in css then css file size increase so better use separate css class for each image or use sprite image. Also dataurl is base64 encoded data so data size increase after encoding. For this you can use gzip compression in your server to reduce css response size.

  6. Very good written story. It will be useful to anybody who employess it, as well as yours truly :). Keep up the good work – can’r wait to read more posts.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.