Thursday, August 26, 2010

When The User Comes First

Far too many projects and marketing campaigns today start by answering the question "What value does this have for our company?" The question shouldn't center around the company, the question should center around the users. What we should be asking is "What value does this have for our users?"

It's a very simple concept, but it is one that, if adhered to, would fundamentally alter the priorities of a project. If the user comes first, SEO takes a backseat to content strategy. Accessibility and performance cease being afterthoughts and become crucial components of a site. More time is given to user research to determine what users expect to find on your site, and where they expect to find it.

The irony is that by putting the users first, the success of the project would greatly be improved. Build something that users care about and want to use and they'll reward you with their loyalty.

Imagine if every company took the time to ask, and more importantly to answer, this question before launching their projects. Wouldn’t that be refreshing?

Monday, August 23, 2010

Quick Optimization Using Webgrind

I was recently working on a site whose code I was inheriting and the pages took much longer to process than I would've liked. Caching helped, but I wanted to get to the underlying issue so I fired up Webgrind to see if I could trace the problem.

Webgrind is a freely available PHP profiling frontend that sits on top of XDebug. Using it, you can see how many times different functions are called and find what functions called them. You can also quickly see the inclusive cost (time spent inside a function plus calls to other functions) and self cost of each function.

Viewing the logs for the last page load, I could see that mysql_query was called a whopping 52 times and accounted for 84.93% of the processing time (which was at an unacceptable ~3.1ms).

Using the Webgrind frontend, I was able to trace back 23 of those calls to one function. In turn, this function was called by one other function 17 times. I decided to focus there first.

Again, with the help of Webgrind, I could see that this function was called several times, in  separate files, for each page. The function produced the same results each time it was called.

The quick and simple fix, then, was to use a property to cache the results of that function call. So the first time it was called, it would process completely and run the necessary queries. The next time it was called, it would check it's cache property to see if a value existed for the parameter being passed. If the value did exist - it would return that value.

This simple optimization immediately brought the total queries down from 52 to 36. They still accounted for 74% of the processing time, but that time had dropped dramatically from 3.1ms to ~2ms.

36 queries was still more than I wanted. A similar function to the one I had just optimized was responsible (both indirectly and directly) for 25 of the remaining 36 queries, so I thought I'd take a look there next.

Looking at the source, I could see that while the function asked for a boolean parameter to indicate if it should run certain queries, it never actually checked the value of that parameter. So no matter what, it was running all the queries, all the time. Fixing that error brought the total query count down from 36 to 16 and the total time to process the page was now ~1ms.

As a surprising bonus, there were no locations in the code that I had to change now that the function had been corrected. People hadn't been expecting to get those extra values in their return object, so they never tried to use them unless they had passed a true value in for that parameter.

All in all I was able to take the query count down from 52 to 16 and the processing time from ~3.1ms to ~1ms. There's more room for optimization, but this is certainly not a bad start for about 45 minutes of work.

Wednesday, August 18, 2010

SXSW Panel Pimping

The SXSW panel picking madness started last Wednesday. After attending the conference twice, I finally got around to submitting a talk this time around. If you're interested in web performance, neuroscience, and in particular how those two areas intersect, feel free to give it the old thumbs up. Either way I'll be attending (already registered and got the flight and hotel booked) but I'd love to get the opportunity to hear myself talk share some information while I'm there as well.

Enough self promotion. After having taken a look through the options, here's a few more talks that I'm really hoping make the cut. Again, if they sound interesting to you, please give them a thumbs up in the PanelPicker.

If any of you have a panel submitted, or came across one particularly interesting, feel free to let me know. I know many people frown upon the annual "panel pimping" but I actually enjoy it. There are quite a few panels I probably wouldn't have heard about otherwise.

Monday, July 12, 2010

Performance Toolbelt: CSSEmbed

One of the biggest keys to improving the load time of your site is minimizing the number of HTTP requests. There's a lot of overhead involved with each request, and many requests can very quickly slow down your site. One great way to eliminate extra requests is to use data URIs instead of images. If you want the nitty-gritty on what data URIs are, and how to use them, there are a few excellent posts by Stoyan Stefanov and Nicholas Zakas that walk you through the details.

Data URIs can be tricky to implement efficiently however. Since they are a Base64-encoded representation of an image, there is a built-in level of obfuscation that can make manual maintenance tedious. Thankfully, Nicholas put together a command line tool called CSSEmbed which takes the pain out of using them.

CSSEmbed is a very straightforward tool that parses a stylesheet and converts all references of images to their data URI equivalents. Installation is as simple as downloading the .jar file and placing it where you'd like. Then you use a simple command specifying any options, the file to output to, and the file to parse, like so:

java -jar cssembed.jar -o styles_uri.css styles.css

Since versions of Internet Explorer prior to IE8 don't support data URIs, you have to use MHTML as a workaround (again, Stoyan has an excellent post with more info). The command for that is very similar — you just need to make sure to declare a "root" (for example, I'd use http://timkadlec.com as my root for this site) which CSSEmbed will use in the MHTML.

java -jar cssembed.jar -o styles_mhtml.css styles.css --mhtml --mhtmlroot http://timkadlec.com

Right now, to my knowledge, you can't parse an entire directory of CSS files, but that's about the only thing I can think of that I'd like to see added. It's a great tool to use during an automated build to really simplify the process of using data URIs and I definitely encourage you to go download it and give it a try.

Wednesday, July 7, 2010

Another New Addition

A short week ago (June 30th), my wife and I were lucky enough to welcome our second healthy baby girl into the world. Just like her big sister, Jessica Claire weighed in at a healthy 8 lbs 15 oz.

Her big sister, thankfully, thinks Jessica is at least somewhat interesting so far and likes to come and "talk" to her. Both girls, as well as their mother, are doing well (if not a bit tired).

I'm sure there's going to be plenty of barbies and tea parties in the future (heck, there's already some "Ring Around the Rosie") but I'm sure I won't mind. I'm just a happy dad whose two little girls have him firmly wrapped around their fingers.

Monday, June 28, 2010

Who's Stupid?

Andy Rutledge wrote a post that is frighteningly on target. He argues that the "quality of your client experiences is directly proportional to the quality of your professionalism". He goes on to state that if your clients are "stupid" you may want to take a step back and consider who may truly be responsible for these failed interactions. He starts by pointing out how you can set yourself up for failure before you even start on a project:
If you don’t research and vet your potential client before asking them to sign your contract, stop being stupid. If you bid on projects even though the potential client doesn’t know much about you or why you’d be a good (or bad) choice for them (they “just need a web designer”), stop being stupid.

He continues by analyzing how web designers can continue to lay the groundwork for "stupid" clients by failing to have a proper workflow in place:
If you aren’t the one defining the project process, stop being stupid. If you don’t define, police, and unfailingly adhere to specific milestone requirements and deadlines for both yourself and your clients, stop being stupid. If you’re producing design artefacts before completing a comprehensive discovery process, stop being stupid.

Too often, we rush blindly forward into new projects and new relationships with clients. This process is not at all conducive to high quality work. Quality work requires an investment of time and a devotion of resources. To craft a site of true quality, you need to take a step back and slow the process down — making sure you understand the problem you are trying to solve and ensuring that the solution you are proposing is the right solution for that particular problem.

While the stupid tag may feel a bit confrontational it does not detract from the argument that Rutledge is making: not all failed relationships are the fault of the client. By failing to invest the proper amount of time and attention into planning, research, and careful consideration of requirements, firms and freelancers often set themselves up for failed client relationships.

Sunday, June 27, 2010

Version 3.0

For the second time this year, I'm launching a redesign of this site. Shortly after putting the last redesign live, I started wishing I'd have allowed for a little more flexibility in the types of content I produced. While I still enjoy writing full, detailed posts at times, there are a lot of times I just want to share a quick thought, or pass along a quote from an article I found particularly good.

I gave Tumblr a try for a little bit, and I loved the freedom it gave me to post content I found important, regardless of how much detail I felt it warranted at the moment. Really, the only thing I didn't like was the fact that I was now blogging in two different places - this site and my Tumblr blog. Since Tumblr had no easy way to import all my old posts from Wordpress, I decided to make use of the custom post type capabilities in Wordpress to build my own version of a tumblelog.

Since the frequency of posts will undoubtedly be picking up with the additions of these shorter post types, let me know if any of you would prefer to have a feed for just the "feature-length" posts. Right now, the main feed pulls everything.

The underlying structure didn't change a ton - it's still HTML5 based. As of the time of this post, there's only one image being used in the site (other than anything called by the Google Analytics script). The rest of the graphical elements are a combination of CSS gradients and data URIs to help reduce the number of HTTP requests.

So have a look around. The plan is for this version of the site to stick around awhile.