Wednesday, February 16, 2011

On Premature Optimization

There has been a lot of discussion in my Twitter peer group lately about what's the right level of optimizing website performance and how to go about it.
Premature optimization is the root of all evil.
This sentence is true but it might also seem like an excuse to never optimize, so lets elaborate a little on the condition when and how to optimize your code.
Lets start by defining optimization for the purpose of this blog entry:
When optimizing for performance one chooses between two or more implementation strategies and picks the fastest one based on the reason that it is faster then the other strategies.
Now that we have defined performance optimization as a choice between multiple implementation strategies is becomes clear that it is just a subset of the more general concept of software design. When picking between implementation strategies in software design one has to regularly pick the worst of all evils to achieve the best possible outcome. The trade offs are:
  • Maintainability
  • Scope
  • Quality
  • Performance
You never get more than 3 of those right with limited ressources. This also means that if we want great performance we will have to be cool with worse maintainability, reduced scope and/or worse quality. As a software designer we need to be aware of this and should make a very conscious decision when we opt for great performance.
Now Steve Souders and friends have proven to great length that in the special case of website and web application load time performance can have a great positive impact on the overall success of a project, thus is will often be the right thing to opt for performance and e.g. decide to reduce scope.
Now if performance optimization can be a good thing, then why is premature optimization always evil: Because the premature refers to the fact that the performance optimization was not done because of a conscious design decision but for other reasons: E.g. because we can or because when writing that ray tracer the other day something proved to be faster.
To differentiate mature from premature optimization I already late down that conscious decisions are the key factor. What is needed for a conscious decision:
Data
When thinking about data and performance profiling comes to mind. Yes, profiling is very, very important, but I was also referring to data in terms of how the optimization will impact the scope, quality and maintainability of your application.
Unfortunately profiling is not the solution to all performance problems. Often you have to make decision early in the software design process when little code is written and you cannot really profile anything (you could micro profile but you don't know if that code is relevant to your overall performance yet). Thus besides profiling you also want to use experience to get some things right in the first place. If you don't have that experience, buy some books. Experience often also is the only way to assess how an optimization will impact things like quality or maintainability. I guess, you need a lot of experience to write good software :)
The good thing is: Computers are fast. This leads to an important rule:
When things aren't too slow, optimizing them will always be a bad idea because the the trade offs in quality, maintainability and scope will result in a net loss.
When designing your software, you should never pick an implementation strategy because it is faster unless you have data (through profiling or experience) to support your decision.
In concrete terms for JavaScript when picking between
  1. C-style loop and forEach -> use forEach.
  2. String builder and concatenation -> use concatenation
  3. Script tag VS. script loader -> use a script tag
  4. etc.
If you ever pick the faster alternative that is cool as well, just make sure that when you work on my team that you are able to back up your decision with data or I'll make you change it to the slower code with a really embarrassing commit statement :)
PS: Point 1+2 in the list above are examples where you will only ever opt to the faster version after profiling. Point 3 is a good example where your experience might tell you that the tradeoff of using a script loader is well worth the effort.

Tuesday, February 15, 2011

Streamie and the Chrome webstore

Full Disclosure: I work for Google but Streamie is my private just-for-fun project. Your results may vary.

I will do a post on Streamie's overall Analytics soon, but lets start off with the numbers related to the Chrome webstore.
This data is from the first week of 2011. Streamie was used by a hardcore scene of enthusiastic users and the numbers weren't big. At this time Streamie was already in the webstore but it wasn't actually available to users of the stable version of Chrome.


The Chrome webstore launched to all users on January 7th and on January 12th Streamie became a featured application. This is what happened:


I will put more data on what happened after that in a later post, but as far as the Chrome webstore is concerned it continued to send a significant amount of traffic to the site (both as direct referrers and from the newtab page).

Some final numbers:
Users who have Streamie installed as an app in Chrome have
- spend 300,029 minutes using Streamie
- send about 10,000 tweets with Streamie

I'm personally somewhat surprised with the overall traffic that Streamie is receiving. It is nice that people like it. The Chrome webstore definitely helped pushing the traffic to a new level, though, which, of course, triggered a lot of blog posts and tweets and then more traffic :)

Sunday, February 13, 2011

Taking away information

Streamie was always a very selfish project. I wanted to build a Twitter client that is optimized for my personal usage. That is consuming tweets from about 350 people on my main account.
I have to be brutally honest: I have always used a second Twitter client (Tweetie aka Twitter for Mac) in parallel. That is because Streamie does not support multiple accounts which is a feature that I need. Why did I not implement this? Because it is not important for my consumption habits. On all the other accounts (@jsconfeu, @hhjs, @streamie and some others) I never actually read the tweets but only look out for mentions and DMs.
That said Streamie is moving forward as a get-out-of-your-way tweet-consumption application: All information that is not completely necessary to read a tweet has been removed from the default view. You can't see the name of the author (but his avatar (This works for me even though I suck at remembering faces)), the age of the tweets or any buttons at all. Just the avatar and the text.
I was recently experimenting with integrating embedly and a two-pane view to view content without navigating away. People hated it and it was against the simplicity of Streamie. People actually like opening background tabs for later reading.
In adition to this several small refinements have recently landed in Streamie
  • The ugly t.co links shortened by Twitter are replaced with a short version of the actual URL. Clicking the link does not go through t.co. This is good for your privacy and also much faster.
  • You can now choose for which type of tweet (all, mentions, DM) you want to be notified. Differently colored favicons are used to for notification through the tab-bar.
  • When somebody deletes a tweet, the tweet content is displayed with a strike and you can actually delete your own tweets.
I'm very open for more ideas about information that can be thrown away or hidden behind a hover or click (please comment). I'm not completely happy with the current hover behavior. At least for touch devices this needs to be changed to a click and maybe it should be a click everywhere (Opinions?).

Update: I changed the rollover info to never resize the tweet. The layout jumping was too much.