Avoiding Temptations that Harm Website Performance

The following post is a cross-post to Sitepoint’s blog to promote my book Lean Websites.

Web performance matters. Studies have shown that improvements in website performance—such as page load times—can dramatically increase user engagement and profits.

However, life’s short, and time is money. As web developers, we’re paid to get the job done—by clients, bosses and colleagues who may not appreciate the importance of site performance. So the temptation is to cut corners to get the job done—to find the quickest solution, without regard for performance. In these times of rising mobile usage and search engine preference for lean websites, average page weights continue to soar. It’s not a good situation.

Temptation: the pressure to give in to a desire for easy or immediate pleasure

The consequences of giving in to temptation are often not felt until afterwards.

This article describes some of the temptations you’ve probably faced in your web development journey, and why it’s better not to give in to them.

Using Ready-made Scripts

It’s a typical scenario: you need to add something to a web page—such as a slideshow. So you google “web slideshow” and get hundreds of results. There are so many to choose from, all ready to go, and free. Why not just use one as is, save time, and get paid? Doesn’t everyone else?

We often forget to consider the performance of the scripts we choose. Is the code well written? Is it optimized? Do we need all the functionality it contains?

In Chapter 4 of Lean Websites, I examine how to differentiate between copy and paste and copy and waste.

Pretty Images and Designs

A picture is worth a thousands words; and when it comes to web performance, a picture might be worth more that a thousand lines of code in terms of page weight! Poorly optimized images are by far the the biggest cause of bloated websites.

There are some image considerations that can make a huge difference to web page performance.

Not Every Device Needs a High Resolution

There’s no need to show everybody the high resolution version of the image if not needed. Be context sensitive, considerate and respectful. Don’t fill your page with unnecessary heavy assets like images just because you don’t know what else to put there. Trust me, none of your users on their mobile device while roaming wants to download a 2MB retina image.

Images Cost Bandwidth

Images remain the biggest performance culprits. They currently take up most of the file sizes and usage on the internet, as shown in the chart below:

Bandwidth usage of various content typesBandwidth usage of various content types

The temptation web developers face, especially when working under a lot of time pressure, is to just plug in big images, without considering whether to convert them into a more efficient image dimension or format.

In my book Lean Websites, I look in depth at ways to optimize your images and other site assets to ensure that your site is as performant as possible—especially on devices connected to mobile networks.

Performance Optimization as a Part of Development

When time is money, there’s always a temptation to cut corners. One way to cut corners is to put things off and never end up doing them. Performance testing and optimizing are critical, but it’s tempting to put them off till later and then forget all about them.

Performance optimization is often not mentioned as part of the common software development life cycle at all. But as Ilya Grigorik says, “performance is a feature“, and shouldn’t be relegated to an afterthought.

Lean Websites discusses how you can automate optimization, and make it part of your deployment process, with some easy-to-use and free tools.

Libraries and Frameworks

Christian Heilmann, a web evangelist at Microsoft, calls it “death by a thousand plugins“. It’s so easy to attempt to use modern web development trends by including yet another plugin or library. We sometimes forget that anything you put on your page will cost you and your visitor when it comes to performance. Don’t let too many plugins bloat your website. Heilmann also encourages us to remember that “it is not about what you can add—it is about what we can’t take away”. Something to remember next time when you want to paste another plugin into your site.

Libraries like jQuery, Dojo, and YUI are popular tools that help developers kick-start JavaScript projects, making access to JavaScript objects and methods faster and easier. They simplify the coding experience—but at what cost?

Big Query queryMost popular libraries

The file size of these libraries may vary a lot, especially if they are not minified, gzipped and compressed. jQuery minified and compressed is almost eight times smaller than sending it over the wire without optimization (252 KB uncompressed, 32 KB minified and gzipped).

It’s important to decide what framework or library to use early on in a project. It normally doesn’t make sense to use more than one library or more than one MVC JavaScript framework with a project, as different libraries tend to achieve the same goal. And of course, a library should only be loaded once, though it’s not uncommon to see multiple instances of jQuery on a single page:

Website Count Different jQuery version loaded
www.reddit.com 2 1.7.2,1.7.1
www.washingtontimes.com 2 1.4.2,1.4.4
www.tudoseo.com 10 1.6.2,1.7.2,1.7.1,1.6.4,1.8.2,

Duplicate loading of jQuery, source: example Google Big Query on HTTP Archive for the month of July 2014

Why would you want to load more than one version of jQuery? Isn’t this screaming for a good clean-up? There is definitely some legacy code in there that might require an older version of jQuery. Hence, the temptation is pretty big to just add a new version in addition to use newer functionality in jQuery. That seems like a lot of maintenance and legacy trouble. Instead, take some time, go through the functionality of your site and determine which version to convert to.

While sometimes there might be a good reason to include several JavaScript frameworks, there could also be other reasons that should be verified. The overlapping and duplication of plugins can stem from different reasons:

  • The team building the site didn’t agree on a common framework or library to use.
  • Tangled code that developers have to work with. Sometimes they are only being provided with isolated include files, with very little visibility to the parent code. They could be tempted to just plug in their preferred library and version if needed, to continue their work.
  • Missing enforcement techniques.
  • Carelessness or laziness of developers.
  • Use of other web components including the same frameworks.

Lean Websites looks in detail at the consequences of using libraries and frameworks, and how to make the best use of them without negatively impacting on site performance.

Social Media, Ads and Tracking

If you work for a company with a business intelligence, analytics or marketing department, the chances are high that you are being asked to include anything that could help measure the company’s success.

Social media, ads and tracking scripts are big temptations for marketers and companies to better understand their customers and to add or find other revenue streams, such as selling ads. But any foreign content you add on top of your own content—especially if it’s JavaScript-based—will add weight and load time to your page.

There’s not one social media or tracking tool out there that marketing wouldn’t like to try out.

Lean Websites looks in detail at how to properly and securely include third-party scripts and plugins.

A handy rule of thumb is that the value you get from using a third party script has to be greater than its performance hit.


Performance optimization is often an exercise in compromise, and there are always competing interests to be considered.

This article has raised just a few of the issues involved in site optimization—a topic that is finally coming of age in a big way.

Lean Websites provides a detailed, in-depth overview of the many factors involved in creating efficient, performant websites—from understanding user experience and expectations to monitoring performance, automating tasks, and optimizing server requests, site assets, and the networks our sites run on.

Hopefully this this brief introduction has whetted your appetite to find out more! I’d love to field any questions or comments you may have.

Good-Bye OANDA / Hello Mozilla!

I gave notice last week.

This was the hardest resignation day I’ve ever had to go through. Not only because I noticed that people care about me and my work but more importantly to leave something so great behind.

I truly enjoyed working with, and learning from my amazing manager about product management, leadership, respect, opportunities, metrics, strategy and customers.

He defined product management as 3 main parts: customer, data, strategy.
I’ve always found those such great pillars to follow, and core ideas on how to tackle product management.

First product launch: OANDA API with API cupcakes!

But that’s not all. I’ve never worked at a company where leadership and management were so approachable, caring and listening. I already miss all the great conversations and insights I got from my manager, the CTO and CEO, well basically anybody there. I will forever cherish this, and do not ever want to cut my connections to them – Graeme and Ed, you promised me coffee time! I never had the feeling that anybody’s opinion is not valued or not considered, I never had to deal with any egos or had the feeling I couldn’t tell anyone (especially in senior management) if I felt their idea was not something we should pursue.

It’s actually pretty easy, everybody wants to be happy and productive at work, and the best way to achieve that is to work and have fun, together.

I’ve learned what constructive criticism, respect and loyalty mean. I’ve learned to build and form an opinion at work, discuss, feel different and be proud of it, and more importantly stand behind it, something that has not always been easy for me in the past.

I’ve learned so much here. This place is encouraging and positive and that’s what has always kept me there.

Thank you OANDA.

<obvious-shout-out>If you ever get a chance to work for OANDA, go for it, and apply, it’s a great bunch of people.</obvious-shout-out>

And, although I didn’t plan to move on so quickly after my enjoyable and productive 1 1/2 years at OANDA, there is a reason why I had to do it. It’s about growing and taking opportunities, and sometimes they come faster than you had planned.

Throughout my entire life, the web and its openness have always been a passion of mine. I’ve always been fascinated by the web and its possibilities; I’ve built many websites, have cursed about browser compatibilities so many times, built mobile websites for the CBC, lead a mobile/hybrid web app project at the CBC, have hosted many webperf meetups, haven spoken at conferences about the web, and last but not least I’ve written a book about web performance.

This is not to brag about my stuff, it’s more to explain my passion, and by now, I assume you’ve noticed a pattern: I believe in the (mobile) web and I am so passionate about it.

So, in a couple of weeks, I will start as a senior product manager at Mozilla. I can’t wait to bring Firefox on all mobile devices. I’m so thankful and grateful that I can finally put all my passion for the (mobile) web into an organization that truly cares for, and believes in the openness of the web.

My first week at work will be in Whistler, BC, where I will meet all my team members, well all Mozillians. After that, I’ll have my desk in the Toronto office.

I can’t wait!

I believe in the web, and I believe in mobile.

Let’s get started.



Fast-Forward Performance – The Future Looks Bright

Note: This is a cross-post, the original post can be found as part of the 2014 perf calendar.


Generally, I prefer to mention the bad news first:

  • Slow websites will always exist.
  • Websites will continue to become more complex and bigger.
  • Our demand for speed and patience will certainly not decline.

These facts shouldn’t come as a surprise to anyone who cares about web performance.

Predicting the future is difficult and science has not been able to make time travel possible for us to peak ahead to what will happen to web performance. However, have you paid attention to the W3C activities recently? There is some really exciting performance stuff cooking.

My contribution to this year’s performance calendar is to tell you what convenient features we can expect in the future when dealing with web performance.

The future is (almost) here

The good news is that the W3C Web Performance Working Group and browser vendors have acknowledged that performance is an important piece of web development. They have already pushed out, and continue to propose new standards and implementations for those performance APIs.

The purpose of a web API is to provide you with better access to your users’ browser and device. Performance APIs can ease the process of accurately measuring, controlling, and enhancing the users’ performance. In addition, new protocols and HTML elements have been proposed to help serve content even faster and more optimized to users. Prior to these enhancements, it was impossible for developers to accurately measure their website performance.

Please note, I added a browser compatibility table at the end of this post so you can verify each API against current browser support.

I’m excited about the future of web performance and this post describes why.

Can I get an API with that?

There are several already existing, but also new performance APIs that are currently being worked on. To ensure quality and interoperability, W3C standards go through a specification maturity process, as shown below. Starting from step 1, “Editor’s Draft” to step 5, “W3C Recommendation”. Most start landing in browsers (“behind a flag”) during the “Working Draft” phase and get refined over time. After step 3 (“Candidate Recommendation”), developers can expect the API feature to be released un-prefixed in some browsers.

Let’s take a closer look at each API listed in the boxes above, from right to left.

Navigation Timing

This specification defines an interface for web applications to access timing information related to navigation and elements. – W3C

The Navigation Timing API helps measure real user data such as bandwidth, latency, or the overall page load time for the main page, and it is mainly used to collect RUM data.

The API allows developers to inquire about the page’s performance via JavaScript through the PerformanceTiming interface.

varpage = performance.timing,
    plt = page.loadEventStart - page.navigationStart,
// Page load time (PTL) output for specific browser/user in msconsole.log(plt);

Navigation timing covers metrics of the entire page. To gather metrics about individual resources, please check out the Resource Timing API further down below.

You can use this API to collect performance metrics about your user, especially when using RUM as one of your measurement techniques.

Navigation Timing 2 has been announced and will replace the first version.

High Resolution Timing

This specification defines a JavaScript interface that provides the current time in sub-millisecond resolution and such that it is not subject to system clock skew or adjustments. – W3C

varperf = performance.now();
// console output 439985.4570000316

When it comes to performance, accurate measurements are very beneficial. The High Resolution Timing API supports floating point timestamps providing measurements to a microsecond level of detail.

Page Visibility

This specification defines a means for site developers to programmatically determine the current visibility state of the page in order to develop power and CPU efficient web applications. – W3C

The visibilitychange event is fired on document whenever the page gains or loses focus.

document.addEventListener('visibilitychange', function(event){if(document.hidden){// Page currently hidden.}else{// Page currently visible.}});

This event is very helpful to programmatically determine the current visibility state of the page. For example, the API can be applied if your user has several browser tabs open and you don’t want specific content to execute (e.g playing a video, or rotating images in a carousel). Especially on mobile devices, this can be a great advantage in saving battery consumption for your users when they don’t have your page visible, but open in an inactive tab.

Here is a neat sample page illustrating the firing of the visibilitychange event.

Resource Timing

This specification defines an interface for web applications to access the complete timing information for resources in a document. – W3C

The Resource Timing API is a bit newer and not as well supported as the Navigation Timing API. You can dig deeper into understanding the behaviour of each individual resource of a page. Imagine you putting an image on your page, but not knowing how it performs in the real world, therefor, you would like to know the Time to First Byte (TTFB) metric for this image.

As an example, let’s pick the performance calendar logo (http://calendar.perfplanet.com/wp-content/themes/wpc/wpclogo.png).

varimg = window.performance.getEntriesByName("http://calendar.perfplanet.com/wp-content/themes/wpc/wpclogo.png")[0];
varttfb = parseInt(img.responseStart - img.startTime),
    total = parseInt(img.responseEnd - img.startTime);
console.log(ttfb); // output 93 (in ms)console.log(total); // output 169 (in ms)// you could log this somewhere in a database or // send an image beacon to your serverlogPerformanceData('main logo', ttfb, total);

If Timing-Allow-Origin header is set by third party providers, you can even check the performance of third party resources on your page.

Beyond the main page’s performance (via Navigation Timing API), you can track real user experiences on a more granular basis (i.e. resource-basis). By having knowledge of this data, you can find potential performance bottlenecks for a specific resource.

Performance Timeline

This specification defines an unified interface to store and retrieve performance metric data. This specification does not cover individual performance metric interfaces. – W3C

The Performance Timeline specification defines a unifying interface to retrieve the performance data collected via Navigation Timing, Resource Timing and User Timing.

// gets all entries in an arrayvarperf = performance.getEntries();
for(vari = 0; i < perf.length; i++){console.log("Asset Type: " +
    perf[i].name +
    " Duration: " +
    perf[i].duration +

Check out the detailed post by Andrea Trasatti on the performance interface. He created a tool to generate HAR files from the performance timeline API, which provides you with a timeline view of performance metrics as they happen. You can plot the results as well. Andy Davies created a great waterfall bookmarklet to illustrate this.

Battery Status

This specification defines an API that provides information about the battery status of the hosting device. — Source

The API provides you access to the battery status of your users battery-driven device, as well as events that can be fired.

The charging, chargingTime, dischargingTime and level can be inquired, as well as events can fire based on these statuses.

varbattery = 
  navigator.battery || 
  navigator.webkitBattery ||
  navigator.mozBattery ||
if(battery){console.log("Battery charging? " + battery.charging ? "Yes" : "No");
  console.log("Battery level: " + battery.level * 100 + " %");
  console.log("Battery charging time: " + battery.chargingTime + " seconds");
  console.log("Battery discharging time: " + battery.dischargingTime + " seconds");

More samples and details are posted on the Mozilla Battery Status API page, as well as here

By knowing the users’ battery state, you could serve content based on the status (e.g. don’t send energy intensive elements to the user if the battery level is below 20%).

User Timing

User Timing provides a simple JavaScript API to mark and measure application-specific performance metrics with the help of the same high-resolution timers. – W3C

With the User Timing API, you can set markers to measure specific blocks or functions of your application. The calculated elapsed time can be an indicator for good or bad performance.

performance.measure("measureIt", "start", "end");
varmarkers = performance.getEntriesByType("mark");
varmeasurements = performance.getEntriesByName("measureIt");
console.log("Markers: ", markers);
console.log("Measurements: ", measurements);        
functionloadSomething(){// some crazy cool stuff here :)console.log(1+1);

The markers can help you focus on specific activities on your page and measure important milestones when your application/website is being executed.


This specification defines an interoperable means for site developers to asynchronously transfer small HTTP data from the User Agent to a web server. – W3C

With the beacon API, you can send analytics or diagnostic code from the user agent to the server. By sending this asynchronously, you won’t block the rendering of the page.

  "any information you want to sent");

Here is a neat demo page.

You can use the recommended beacon to carry performance information to a specific URL for further RUM analysis.

Animation Timing

This document defines an API web page authors can use to write script-based animations where the user agent is in control of limiting the update rate of the animation. The user agent is in a better position to determine the ideal animation rate based on whether the page is currently in a foreground or background tab, what the current load on the CPU is, and so on. Using this API should therefore result in more appropriate utilization of the CPU by the browser. – W3C

Instead of using setTimeOut or setInterval to create animations, use the requestAnimationFrame. This method grants the browser control over how many frames it can render; aiming to match the screen’s refresh rate (usually 60fps) will result in a jank-free experience. It can also throttle animations if the page loses visibility (e.g., the user switches tabs), dramatically decreasing power consumption and CPU usage.

Check out Microsoft’s demo page comparing setTimeOut with requestAnimationFrame.

Smoother animations result in happy users, low CPU usage, and low power consumption.

Resource Hints

This specification defines a means for site developers to programmatically give the User Agent hints on the download priority of a resource. This will allow User Agents to more efficiently manage the order in which resources are downloaded. – W3C

Predictive browsing is a great way to serve your users with exactly what they want to see or retrieve next. “Pre-browsing” refers to an attempt to predict the users’ activity with your page (i.e. is there anything we can load prior to the user requesting it?).

The following pre-browsing attributes are meant to help you with pre-loading assets on your page.


For example, if you set up tracking on your page, you probably know where your users are headed most often. You could use resource hints to pre-load subsequent resources of the next page to allow for quicker loading of that consecutive page.

Other proposals (not supported yet)

  • Frame Timing

    This specification defines an interface to help web developers measure the performance of their applications by giving them access to frame performance data to facilitate smoothness (i.e. Frames per Second and Time to Frame) measurements. – W3C

  • Navigation Error Logging

    This specification defines an interface to store and retrieve error data related to the previous navigations of a document. – W3C

Protocols, standards, and new HTML elements


HTTP/2 and SPDY protocol (developed by Google) allow several concurrent HTTP requests to run across one TCP session, and provide data compression of HTTP headers.

It’s no secret that SPDY has been a huge motivation for revamping the HTTP protocol. SPDY is not HTTP/2, however, when the HTTP/2 proposals were introduced in 2012, SDPYs specifications were adopted as a starting point (one single TCP connection, HTTP header compression, Server Push etc.), see more here.

When HTTP was introduced a decade ago, latency wasn’t something that was necessarily thought about. In HTTP/1.1, only the client can initiate a request. Even if the server knows the client needs a resource, it has no mechanism to inform the client. Therefore, it must wait to receive a request for the resource from the client. HTTP/2 promises to make HTTP requests cheaper, reducing the need for us to come up with techniques (or maybe hacks?), such as CSS image sprites, inlining etc., to minimize the number of HTTP requests needed.

The HTTP/2.0 encapsulation enables more efficient use of network resources and reduced perception of latency by allowing header field compression and multiple concurrent messages on the same connection. It also introduces unsolicited push of representations from servers to clients. — HTTP/2.0 Draft 4


WebP is a lossy compression format to promise optimized image delivery for the web. WebP is open-source, developed by Google, only supported in Chrome, Opera and Android but promises 30% smaller file size than a comparable JPEG image. Big websites such as Facebook have started to adopt these techniques with great success, 90% of images sent to Facebook and Messenger for Android use the WebP format, while they see a file size decrease up to 80% from PNG to WebP.

You can convert your images using a WebP converter like ImageMagick or others.

One of the drawbacks is that as long as not all browsers support this new format, you will need to save two versions of the image, one in WebP and one in the legacy image format, resulting in more storage costs.

Some examples of WebP images can be found here.

Picture element and srcset attribute

This specification defines the HTML picture element and extends the img and source elements to allow authors to declaratively control or give hints to the user agent about which image resource to use, based on the screen pixel density, viewport size, image format, and other factors. – W3C

The <picture> element and srcset attribute provide two ways of getting responsive images in the browser. The srcset attribute allows you to target particular screen densities with images that have been scaled. The picture element, on the other hand, is primarily used for “art directed” content: where the contents of the image changes based on a CSS breakpoint. The standard <img> tag serves both a fallback and as the actual image container. Together, picture and srcset help deal with different device size, and accommodates for different image sizes when using responsive websites.

<picture><sourcemedia="(min-width: 1280px)"srcset="large-hero.jpg, large-hero-2.jpg 2x"><sourcemedia="(min-width: 600px)"srcset="med-hero.jpg, med-hero-2.jpg 2x"><sourcesrcset="small-hero.jpg, small-hero-2.jpg 2x"><imgsrc="hero-1.jpg"alt="Hero image"></picture>

Responsive image solutions can help save bandwidth by providing the most optimized image to the users’ screen width and device.

Browser support overview

The number in each column describes the browser’s version number and subsequent versions up.

Specification Internet Explorer Firefox Chrome Safari Opera iOS Safari Android
Navigation Timing 9 31 all 8 26 8 (not 8.1) 4.1
High Resolution Timing 10 31 all 8 26 8 (not 8.1) 4.4
Page Visibility 10 31 all 7 26 7.1 4.4
Resource Timing 10 34 all 26 4.4
Battery Status* 31 (partially) 38 26
User Timing 10 all 26 4.4
Beacon 31 39 26
Animation Timing 10 31 all 6.1 26 7.1 4.4
Resource Hints Canary limited
Frame Timing
Navigation Error Logging
WebP* all 26 4.1
Picture element and srcset attribute * 38 26

*Not part of Web Performance Working Group

More information can be found here and here.

Ready, set, go?

The W3C brings together industry and community to make performance recommendations and specification reality so that developers can implement them. Please note, not all browsers implement the APIs exactly according to specification, so make sure to verify its functionality for your supported browser list.

With power comes great responsibility and while offering all these new techniques and APIs to developers, we will need to make sure that we understand their power. Browsers and content delivery networks (CDNs) have helped us quite a bit in prioritizing and optimizing web delivery. However, giving developers additional tools to boost web performance is much appreciated.

Stay up-to-date

Your best look into the future is to subscribe to the Web Performance Working Group mailing list for any performance related updates.


This blog post is a compilation of different sections from my upcoming book “Lean Websites”, where I discuss not only web performance APIs, but also provide general guidance on how to create lean websites. Feel free to pre-order your copy before the book officially launches in 2015.

Happy Holidays, Everyone!

“Grunt” your way to frontend performance optimization

Performance optimization has been more than ever in the spotlight of web developers, especially for mobile web developers who have to understand and know by heart the challenges and constraints of mobile devices: these devices run off a battery that e.g. drains faster if performance is not taken seriously. The devices are powered by smaller CPUs than desktop devices. Unknown factors like latency and network connectivity challenge developers to build slim, light-weight and fast websites. Data plans still remain expensive and inconsiderate use of served data by web developers should not be ignored.

Clearly, performance is (and should) not (be) an after-thought anymore. When web developers create websites, performance can influence the success or failure of a web product. We’ve been hearing from leading performance advocates like Ilya Grigorik that speed is a feature and should not only be thought of just before a product hits production but rather as an essential part of the web product development cycle.

For example, instead of minifying and concatenating CSS and JavaScript files manually, tools and processes are out there that can help and put these performance tasks into an automated workflow, and more importantly right from the beginning of a product development cycle.

I’ve been using Maven to run most of the automated performance optimization at work, however I’ve been always interested in using Grunt for the same purpose. Grunt is a task runner, created for web products, based on JavaScript that can be leveraged to make performance part of the deployment process.

In today’s blog post I will be sharing some of the plugins for Grunt that can be used to speed up and automate performance optimization. At the end of the blog post, I will present performance results that will show that frontend optimization (FEO) can be fun and easily be automated to cut page load time.

Google’s “Make the Web Fast” team recommends frontend best practices as well as Steve Souder’s “High Performance Web Sites” outlines rules that can be applied for FEO. I decided to pick two of Steve’s rules “Make Fewer HTTP Requests” and “Minify JavaScript” (and CSS, HTML) by using Grunt plugins that can help automate those specific rules. So here it goes.

Note: The post assumes that you’ve worked with Grunt before and know how it’s been installed, and how to install plugins (I won’t go into details, however links at the bottom will help you)

“Let’s grunt it up”

(All plugin headings in this post are clickable links to their appropriate pages)


Montage helps you sprite images to reduce HTTP requests. You will need ImageMagick to be installed. Alternatively, you can also try out grunt-spritefiles.


This plugin is useful when you want to develop and debug a version of your site that doesn’t use the minified and concatenated version of your JavaScript or CSS files. A comment blocks is wrapped around your JavaScript and CSS assets that will be concatenated to your destination after deployment.

<!-- build:js js/magic.min.js -->
<script src="js/1.js"></script>
<script src="js/2.js"></script>
<script src="js/3.js"></script>
<script src="js/4.js"></script>
<!-- endbuild -->

will become

<script src="js/magic.min.js"></script>

You can use grunt-processhtml instead.


Alternatively you could use grunt-closure-compiler instead of combining concat and uglify and cssmin for JavaScript and CSS files.


Uglify and concat go almost hand in hand and should be used together, the concat plugin first makes sure to combine all defined JavaScript files. Uglify only works on JavaScript files. It minifies all code in a one line block of code. Use cssmin for CSS files.


Same logic and idea than uglify, once your CSS files are all concatenated, use cssmin to shrink several lines of CSS code into one single one.


Combine CSS and JavaScript files with this plugin, it allows you to reduce your HTTP requests for each and every file to just one combined file.


imagemin minifies JPG and PNG images. It’s a handy Grunt plugin if you don’t know if the assets you got handed from your designer (or yourself) are optimized for web yet. By using this tool, you have the piece of mind that you use image files in an efficient way. Alternatively, you could use grunt-smushit, it’s based on Yahoo’s great smushit tool that is available in the YSlow plugin for several browsers.


This plugin encodes images as base64 and leverages the technique of data URIs for images, something that can be used inline with CSS to reduce HTTP requests and hence reduce page load time. I’ve written a blog post where this is explained in more detail.


This plugin is using htmlcompressor tool to minify and compress HTML files. The options parameter is handy to tweak your compression, my example uses compressJS and preserveServerScript to also compress inline JavaScript and server script tags in case I wanted to include some SSI code.


Use grunt-exec to run the SPOFcheck. An excellent tool to identify bad 3rd party scripts includes, developed by the eBay team. I didn’t include the scripts asynchronously, hence SPOFcheck complaints to avoid SPOF.

“It’s Magic” Sample Page

I created a simple page themed “It’s magic” where I applied all mentioned plugins. You can find the files including Gruntfile.js here. Please note, I intentionally didn’t put a lot of effort into the styling (It is supposed to look as simple and cheesy as it feels to you)

In a nutshell, the page has a logo, uses JQuery from the Google CDN, includes a simple JQuery gallery with previous and next buttons. Simple JavaScript and CSS files are being used.


The logo is a png logo, the images are not optimized. There are several CSS and JavaScript files that are all individual being included, not minified nor concatenated.


This file is the one that Grunt will create for you. Visually, the file doesn’t look that different, besides the fact that the title has changed….see yourself

Below are screenshots of the two pages (and links) side by side, the one on the left before Grunt tasks were applied. The right one shows the page after Grunt tasks were applied. For the user they both look the same (except for the heading).

without/magic.html with/magic.html
No magic here!

Can you spot the differences?

  1. The logo was being transformed into a data URI
  2. The title has changed from It’s not magic to It’s magic
  3. The local CSS and JavaScript files were being minified and concatenated
  4. The HTML was being compressed, comments were taken out automatically
  5. The next and previous buttons were converted to a sprite file
  6. On build, SPOFcheck was applied and gave us the following warnings so we could address possible SPOF issues

Screen shot 2013-08-02 at 7.25.05 PM

Let’s take a look under the hood

Here are the waterfalls for both versions:

Without magic

With magicmagic

WebpageTest Results

I ran WebpageTest for both files with 9 runs for IE8 with a DSL connection to retrieve the median. Here are the performance results:

  1. Without magic results
  2. With magic results
  • HTTP requests dropped by ~48%
  • Page load time (PLT) dropped by ~10%
  • File sizes dropped by ~10%

Even if those numbers are not that high (mostly due to the simplicity of the experiment), it shows that Grunt can help you automatically optimize your deployment process.

As you can tell by the sample code, there are many mix and match options available, depending on the magnitude and granularity of your page structure. Nevertheless, this little sample shows how to use Grunt to optimize performance and to illustrate what is possible. Feel free to use the code as a starting point, and tweak or customize it to your likings.

General references and info to get you started with Grunt

Performance check: CBC’s logo as pure CSS, Data URI and simple PNG on the scale

There is always room for improvement. Period.

Think about the 100 meter men’s sprint. I am  amazed how it continues to be possible for human beings to still become faster and improve their performance.

I’m not Usain Bolt – I can’t run 100 meters in 9.58 seconds but I might be able to run (mobile) websites under 10 seconds.

Today, I want to focus on a technique I first heard about at the Velocity Conference in 2011 in Santa Clara and how to compare it with other ways to serve images in HTML pages.

Data URI is based on base64 encoding and basically encodes data (e.g. images) into bites. It can be used to improve performance.

Data URI as “Performance Enhancer”

Instead of requesting for example a PNG image, you could encode it as base64 and serve it inline with your HTML code. That way, you reduce one HTTP request – right there – 200ms saved. Instead putting it inline, you could also put it encoded in an external stylesheet.

Watch out for caching limitations though. Data URIs can’t be cached as they don’t have a standalone cache policy, they are part of the file that includes them. So they can only piggy-bag on other cacheable assets, e.g CSS or HTML files.

As Nicholas explains, if you put data URI images inline with HTML, they can only be cached as part of the HTML cache control header. If the HTML is not cached, the entire content of the HTML markup, including the inline data URI will be re-downloaded every single time. That approach, if the image is big in size, can slow down and weight down your page. Hence, one option is to to put it in stylesheets because they can have an aggressive cache while the HTML page can have no cache or a very limited cache.

Limitations and Browser Support

Think about the browser audience of the site you want to leverage data URIs for. If you target modern browsers, including new mobile devices because that’s where you really want to focus on performance the most, you might be able to ignore the following limitations and accept the little restricted list (thanks to Fire) of supported browsers.

  • Firefox 2+
  • Opera 7.2+ – data URIs must not be longer than 4100 characters
  • Chrome (all versions)
  • Safari (all versions)
  • Internet Explorer 8+ (data URIs must be smaller than 32KB)

Motivation for Comparison

I’ve been reading a lot about web performance techniques and for some reason the data URI practice got stuck with me. I started off by creating the CBC gem (logo) in CSS to verify if CSS performs better than serving images. While I was playing around with that, I thought why not adding another dimension to the test and check the performance of the CBC logo as data URI. Voilà, I had my basic scenario for the test:

Check the performance of the CBC logo as

  1. An image in pure css
  2. A plain PNG image as background image
  3. A data URI (in CSS and inline with HTML)

Setting up the Test

The purpose of the test was to figure out what kind of presentation for the CBC gem would be the fastest and slimmest.

Prerequisites and Conditions

  • All HTML and CSS files were minified and use the same markup (despite the logo in pure CSS which needed to have a few more div classes to render the circles)
  • Each HTML version was tested with empty cache
  • Performance results were performed with WebPagetest (10 runs on an 3G simulated browser) to find the Median.

1. Logo in pure CSS (30px x 30px)

Pure CSS 30x30purecss Screen Shot 2013-05-01 at 5.40.46 PM
Description: Thankfully, the CBC gem consists of circles, 1/2 and 1/4 circles, those shapes can easily be created with CSS. I used this page to help me get started. Instead of setting up a fixed size and color, I decided to use SASS to help me be more flexible with my settings for the logo. The scss file lets me define color and size of the gem.
Note: Maybe the pure CSS logo has a bit of issues with some of the 1/4 circles but that’s probably due to some math formulas I didn’t do right in the SASS, I believe this can be ignored. Hence, This version cannot be used as the official CBC gem.

2. Plain PNG Image (30px x 30px)

PNG Image 30x30
Screen Shot 2013-05-01 at 5.40.59 PM
Description: Simple PNG file  included in the CSS as a background image. CSS included in main HTML.

3. Data URI in CSS (30px x 30px )

30x30 data URI

Screen Shot 2013-05-01 at 5.41.04 PM
Description: I used Nicholas’ tool to create my CSS files including data URI. However there are many tools to help you create your own data URI encoded files.

You can see from the browser screenshots above that all logos look pretty much the same to the user.

Test Results

Screen shot 2013-07-23 at 2.33.49 PM

The results show that the median load times serving the logo as pure CSS in comparison to the Data URI solution are being almost the same whereas the logo as a background image in CSS took the longest.

I looked at the base64 string and thought how big it would be if I had used a bigger image. So I googled and found the following “It’s not worth to use data URIs for large images. A large image has a very long data URI string (base64 encoded string) which can increase the size of CSS file.” (source). I decided to test it out myself. So, my next question was “How would the test above turn out if I used a bigger CBC gem logo”. I picked a width and height of 300px. While I was preparing the 300px x 300px pages, I also decided to create another version of the Data URI, not part of the CSS but inline within the HTML.

1. Logo in pure CSS (300px x 300px )

There was not much of a different in terms of markup and setup for the pure CSS and PNG in CSS version. I updated the SASS for the cbcgem.scss to accomodate a logo of 300px x 300px instead of 30px x 30px. The file size didn’t change much because it is all based on math calculations

2. Plain PNG Image (300px x 300px )

Instead of loading gem-30.png, I created a version gem-300.png and updated the CSS.

3a. Data URI in CSS (300px x 300px)

Screen shot 2013-05-01 at 9.09.15 PMI noticed that the size of the Data URI encoding as expected increased dramatically from a 30px x 30px encoded image to a 300px x 300px image (almost 10 times, see full view of screenshot on the left).

3b. Data URI inline within HTML (300px x 300px)

Screen shot 2013-05-01 at 9.31.58 PMInstead of pasting the long base64 string into the CSS, I added it as an img src to the HTML page (see full view of screenshot on the left)

I used WebPagetest again to run 10 tests to find the Median.

Screen shot 2013-07-23 at 2.33.57 PMThe links to the WebPagetest results can be found at the bottom of this post.

Observations & Take-Aways

  • Creating simple shapes in CSS (via SASS) is highly scalable because it doesn’t influence the size of the CSS file significantly. The size of the CSS file won’t change much if I choose to produce a 300px x 300px logo or a 10px x 10px logo. For all tests performed this solution seems to be the most efficient and fastest one.  
  • I didn’t  find the observation true that if the encoded image is bigger than 1-2kB it wouldn’t be worth using Data URI to improve performance. When looking at the last test round (300px x 300px), we can see in the results that the page with the encoded image is still faster than the page with a 300px x 300px PNG image.
  • It is interesting to note that the inline data URI version is faster than the data URI CSS version (and almost as fast as the pure CSS version).  Having to serve 2 HTTP requests with a total size of 4kB, the median load time was faster than the one serving the data URI via CSS.

Further Readings and References

WebPagetest Results

CBC Gem 30px x 30px

CBC Gem 300px x 300px

My contribution as a female tech speaker – Living the minority

I love talking about, and listening to the things I am passionate about (who doesn’t?). I love sharing my knowledge and learning about others. I love conferences. It’s a great place to learn new things, validate your knowledge, connect with like-minded and come back home with a bunch of things you want to try out and work on.

So it happens that one of the things on “my list of things to do in life” is/was to present at a conference. I happily and proudly checked this off last weekend.

I had the pleasure to speak with a smart colleague at FITC’s “Web Performance and Optimization” conference in Toronto, this past weekend.

Our topic was similar to the one we submitted (and got accepted) to the O’Reilly’s Velocity conference in San Clara this summer. I’m so beyond excitement to be presenting similar things (and more) to all those great and talented web performance enthusiasts in a few months.

Allow me to give a brief recap of the presentation from last Saturday – the way I experienced it.

It was a small conference, around 70 people attending, probably ~7 of those attendees were women – that’s it, not more! Well, not a huge surprise to me, I’m used to that from my time as a Computer Science student 10 years ago. But is the ratio still so drastic? Oh, and in addition, I was the only female speaker that day.

While I was listening first (and later presenting myself), I noticed that most male presenters had a very specific way of selling and promoting themselves – They all were very confident (Not jealous, good for you, boys!). A supportive and beautiful person on my side that day, full of great constructive criticism, noted something after I was done presenting. She confirmed something that I had honestly (and secretly) already felt, she said I could have been more promoting myself “..like the guys did”. It’s true, as the only woman speaking that day, I could have represented the female minority better by maybe emphasizing my successful web performance results to those 63 men and 7 women that day. Well, it’s not that I wasn’t passionate about my topic – Maybe it’s just that women share their success in a different, less self-selling way and/or are less confident.

I’d like to quote something from Geek Feminism now:

So! Getting women to submit content: easy? Um. When I’d talk to men about the conference and ask if they felt like they had an idea to submit for a talk, they’d *always* start brainstorming on the spot. I’m not generalizing — every guy I talked to about speaking was able to come up with an idea, or multiple ideas, right away…and yet, overwhelmingly the women I talked to with the same pitch deferred with a, “well, but I’m not an expert on anything,” or “I wouldn’t know what to submit,” or “yes but I’m not a *lead* [title], so you should talk to my boss and see if he’d want to present.”

Ok! So I guess I am not imagining all of this. It really seems to be true that men are generally more confident than women when it comes to work related areas where they can promote themselves.

The beautiful thing about life is that you (can) always learn and get better.

And to be honest, my observation at FITC’s conference has even more encouraged me to submit call for speakers forms! I enjoyed presenting! Like a lot – You ain’t stoppin’ me now.

Below the slides from our talk on Saturday

[slideshare id=17289690&w=427&h=356&sc=no]

Additional resources in regards to women in tech and female speakers

  • https://plus.google.com/communities/101818001236662563704/stream/02ee47c3-6a09-4925-8467-e503c684c4ce
  • https://twitter.com/callbackwomen
  • http://www.facebook.com/ShePlusPlus
  • http://2012.jsconf.eu/2012/09/17/beating-the-odds-how-we-got-25-percent-women-speakers.html
  • http://geekfeminism.org/2012/05/21/how-i-got-50-women-speakers-at-my-tech-conference/

asp.net, i think i like windows.

so i have been getting involved more and more in VS2005 lately. i have to say windows is surprising me and is actually making my life really easier when it comes to building web applications. today, i found out about a nice tool to manage displaying different content depending on their role. the role management offered by vs2005 is nice and can be used very easily. It allows me to customize information that will be presented by users through different templages. This is done based on theirs roles.

It’s sometimes recommended to read about the “what’s new”.

Manage user-based content display and user data persistence


i seem to not be able to stop reading about the “new” web. while i am still trying to get news and information about web2.0 and being excited about this “WebOS” and the web becoming the main application platform for users these days, i have found another terminology today (maybe for a lot nothing new, for me something new to research): semantic web or …1…2…yeah web3.0

Tim Berners-Lee describes the idea in his semantic web road map article and says clearly that the problem is still that “the web is designed for human cunsumption” but “the structure of the data is not evident to a robot browsing the web“. So the idea of the semantic web clearly tries to “solve this problem by developing languages for expressing information in a machine processable form“.

if you need examples and maybe a bit “easier” article to read, the bbc article “Smart sites to power semantic web” might belp you.

confusion with coldfusion

seriously, i don’t know why some people decided to use coldfusion 4.5: right now, i have to understand and enhance somebody’s coldfusion code to make it work for the company i work for. while trying to do that, i realize that most of the functions that i need now to speed up the code, are not available for version 4.5

is there anybody who has a good resource for coldfusion 4.5?

moving forward to more futuristic methods/technologies:
i found a nice one-chapter example of the new series by o’reilly: head rush AJAX.
I really like the style how this serie of books presents its content to the readers: easy, funny and nice to read and understand. I am really thinking of buying it.
Another one I am reading/using is this one:  head first design patterns.