the cost of performance pt1

Performance is a hot front-end development topic, rightfully so. With (new?) technologies like css3 and html5 demanding a lot more from our hardware, with websites growing to 1MB+ per page and with mobile fashionably riding the hype waves, performance is becoming a key factor in the success of our websites. Left and right you can read about optimization techniques and ways to improve loading and response times, and that's great. But ...

there's a cost

Not too long ago Jens Meiert shared a post on G+ on technical debt. The article itself is not free, but the couple of quotes that Jens lifted from the article speak for themselves. There really is no such thing as catering to all and everyone's needs, there's always a price to pay and the same goes for performance.

What irks me the most when reading articles on performance techniques is that they never seem to discuss the debt (/cost) of performance. At most you hear some critical noises about not overdoing it, simply because the time invested does not relate to the resulting performance gain. What many people don't seem to realize (or won't talk about) is that performance often comes with a very real and tangible cost: it eats away on maintenance.

A quick argument could be made that websites are user-centric, referring to the ideal that you should optimize a site for its users, not for its developers. While this ideal is quite sound, reality isn't as clear cut. When building a site there are usually two essential constraints: time and money. To optimize the quality of the site, it's important to make maintenance as easy as possible. Being able to quickly change something becomes more and more important as time passes, especially if you don't to redevelop your site again each passing year. Making maintenance hard will result in unmanageable sites that will see quality drops all over the place as soon as changes are made to them.

To illustrate what I mean exactly I'll be looking at two common and popular optimization techniques. In an upcoming article I'll be discussing tag cutting, in this article I'm going to focus on rewriting css selectors to improve performance.

rewriting css selectors

A very popular technique indeed. Just looking at the Smashing Magazine Twitter feed of the past two days, I was able to pull two (csswizardry,boagworld) separate posts on selector performance. Both talk about ways to rewrite your selectors in order to increase css performance.

The general idea is to use short and very specific selectors. Ids trump classes and classes trump tag selectors. Starting from the right of the selector, this gives you an idea of how much a selectors weighs on your site (check the boagworld article for some tools to make this data more accessible). A commendable goal and definitely important knowledge for a front-end developer, but let's make it clear what they are really saying.

the quality of css selectors

A css selector is used to target a particular piece of html code and apply styling to it (I know you can also style specific states, but that's besides the point of the article). This should be common knowledge. There is really only one way to do this correctly though. The selector in it's entirety expresses a list of contexts in which the final part of the selector should match, no more, no less.

1/ ul li {color:#666;} 2/ .breadcrumb ul li {color:#000;}

The example above should be clear to everyone. The first line sets the color of li elements within a ul to grey, the second line overwrites this statement for li elements appearing within a breadcrumb, making them full black.

There are two main ways to rewrite your css rules. You can tamper with the html to add extra classes (like .breadcrumbListItem) in order to shorten selectors, or you can remove parts of the selector that won't influence the resulting styles of your site. As someone who will go through great lengths to keep external influences out of my html I'm not even going to discuss the first option. It's just not done. The second option comes with it's own set of limitations though.

When you remove "unnecessary" parts of a selector this can mean one of two things: either you are allowed to remove them, meaning that your selector was badly written the first time around, or you can remove them because current project specifications don't require these parts to be there. If you are allowed to remove them you're actually bug fixing, which is a good thing, but if you're removing the other kind of selector particles you're actively reducing the quality of your css selector.

/* original selector */ .news header h1 {...} /* reworked selector */ .news h1 {...}

Consider the code above. Because current project specifications only allow one heading inside the .news block, the header part could be removed from the selector. But what happens when somewhere down the line (and this could effectively be before the first go-live of a website) the specifications change? What if suddenly extra headings are allowed in the content section of your .news block? Headings that share no common styles with the main heading nested inside the header?

.news .content h1 {...}

You can be sure that nobody goes back to rework the first selector and puts the header part back where it belonged, people will just be adding the rule above and overrule all styles necessary. What happened here is that you just created a very simple block of ugly, badly maintainable css, unworthy of anyone calling himself a front-end pro.

conclusion

A good css selector tries to keep future changes in mind. It defines which styles should hit in what particular set of contexts. Each element within the selector should be there for a reason and shouldn't be allowed to be removed. Sometimes removing a part won't affect the css on your current site, but keep in mind the most obvious of changes in requirements. This requires a certain level of experience, but you'll catch up quickly after doing a couple of real-world projects. Clients love to swap certain boxes around, pulling them from their context and placing them where you would never have expected them to go. Making these kind of changes as painless as possible could well enough prove more important than shaving off those few milliseconds of rendering time.

First and foremost, your css selectors should be correct. Stating that they should be short or performance-friendly and leaving it at that is fooling people into believing they will make better websites like that. That's not to say you can't optimize, but not unless you are fully aware of the cost and consequences of those optimizations.

It's important that you know the rules and best practices in order to break them.