No, CSS isn’t always faster

Recently, a post appeared on Hacker News that was yet another exploration of crazy things that can be achieved with CSS.  Like many others, this example was logos rendered using HTML & CSS.  I quickly commented that I didn’t feel we needed more of these examples which, while cool, do almost nothing to advance web development in general. (Note: as Nicolas Gallagher, mentioned in the comments, his article clearly states that these his icons are an experimentation and shouldn’t be deployed in a real-world environment; apologies if the initial text implied that these demonstrations are endorsements of the “use this in the wild” approach).  I suggested that the people involved in such endeavors would be better suited devoting their efforts to demonstrating tips and techniques applicable to the real world.

While I’m sure I could devote an entire post to why CSS is the wrong tool for this job (see the “related reading” section below for a great argument there), one response to my comment in particular caught my attention:

A CSS logo would be useful for performance issues and overall page rendering speed. A CSS animated logo, such as the Atari example, even moreso than a Flash / JS counterpart. CSS renders more quickly than images, and definitely more quickly than embedded Flash.

It’s time for this misinformed, dogmatic approach to web performance to end.  

When Steve Souders came out with his book, High Performance Websites, and the accompanying YSlow tool, the race to reduce HTTP requests was on! Several years later, it’s somewhat unfortunate that in all of the great advice that Steve doled out, many people never make it past this first bullet point. It’s also unfortunate that this rule set has defined website performance for the masses primarily in terms of network-related bottlenecks.  It’s some to start thinking about performance from a holistic point of view; and not isolating things like network performance and elevating them to higher importance than other concerns.

Note: I mention Steve Souders’ work here here not to blame him for what’s happened; more to make the point that good practices (like those Steve suggests) put to use by people without understanding the full ramifications of that advice can lead to some nasty misconceptions.

Thinking about performance holistically, I’m immediately reminded of the talks John Resig did shortly after Sizzle was released and competitors started popping up everywhere to convince people that selector engines were no longer the performance bottleneck in Javascript. People had become obsessed with a single point of performance and were ignoring the “bigger fish.”

So here we are in 2011, and people are still regurgitating the idea that “using CSS is faster than images” without truly understanding the implications of that statement (and how untrue it can be under the right circumstances).  An analogy that I like to use comes from the world of 3D gaming: Rendering something (for example, a drop shadow) in CSS and markup is the real-time, in-game rendering while downloading an appropriately compressed drop shadow png image is using a pre-rendered full-motion-video cut scene. Sure, the initial payload may be somewhat heavier; but again, looking at the complete picture, pre-rendering allows for overall higher performance.

I mention the drop shadow example because it’s absolutely real.  When the team at Netflix was building the initial versions of our web-based UI for connected devices, we ran into serious performance problems on all sorts of devices like the PlayStation3. One of the things we found that significantly sped up the application was to avoid using CSS effects like shadows, gradients, and other “CSS effects;” instead, favoring pre-rendered effects. In some cases, the performance gains were nothing short of astonishing.

To the examples provided by the initial Hacker News article, let’s look at the Twitter logo demonstration. It’s 27 DOM elements and over 4 kilobytes of CSS.  So already we have a comparably sized payload, a more complex DOM, and now it’s time to add flow and paint operations to actually do the rendering of the elements.  There’s a lot of calculations happening to position and style the elements to appear as the Twitter logo.  By using an image, we bypass the calculations on layout and painting that need to be done to do the rendering; those calculations were already completed.

Performance is more than optimizing for the network layer and initial load-time of a page. As with anything, there are tradeoffs to be made (add a little download time, speed up the rendering) and in different situations, there will be different speed winners based on those tradeoffs. More interesting when working with lower-end devices (such as mobile devices) are the tradeoffs between memory use and computation cycles that I hope to cover in depth in future blog posts.

Sadly, there are few resources that cover the topic of in-browser performance in any more depth than a cursory level. I’ve only touched on it here; though I do hope to continue writing about it. That said, before we can even start talking intelligently about working on performance from a holistic approach rather than focusing on individual concerns, we need to learn to get past the dogmatic rules that are holding us back.

Related Reading: Pure CSS Icons: Make the Madness Stop

Thank you for your vision

Along with my wife, and thousands of my contemporaries around the world, I’ve spent much of this evening digesting the news that Steve Jobs has passed away. Like many others, I’m somewhat shocked at my own, somewhat personal reaction to his death. I’ve never met him personally; I’ve never worked for Apple; and, I only recently even moved to the same side of the country on which he lived.  And yet, like so many others have said on Twitter or in visiting Apple’s main campus or retail stores, I feel somehow connected to Steve and I’m experiencing grief. To his family and close friends, I can only imagine that my grief and the grief of these others pales in comparison to yours; I’m truly sorry for the loss of your husband, father, brother, and very real friend.

I’ve read lots of comparisons tonight about Steve; calling him our generation’s John Lennon or Thomas Edison. I believe these are all fine concepts and I agree with them; however I also view him as our very own, real life Willy Wonka. He was the candy man who worked tirelessly refining new ideas into products and emerging from his factory every so often to share the results with the rest of the world. When he talked about a new product from Apple, we listened–knowing that this new realization of a piece of his vision was something that would make many of our lives just a bit better. When the iPhone was first introduced, Steve could have told us that Oompa-Loompas had to be brought in to help with it’s manufacture and we may well have believed him! He was certainly crazy, eccentric, and saw the world in ways that absolutely no one else did. And for far too brief a period, he surrounded himself with an exceptional group of people to mold his vision into reality so he could share it with us.

Though we never met, any owner and user of Apple products knows Steve Jobs; how could we not?  Steve poured not only his time and energy; but also himself into the products that so many of us use daily.  Through these products, many of us feel we’ve come to know some part of that man; and tonight, we mourn our loss.

No one wants to die. Even people who want to go to heaven don’t want to die to get there. And yet death is the destination we all share. No one has ever escaped it. And that is as it should be, because Death is very likely the single best invention of Life. It is Life’s change agent. It clears out the old to make way for the new.

-Steve Jobs

Thank you, Candy Man. You left this world tasting pretty damn good.

You a UI Engineer? You Want to Work With Us!

In all my time working in this field, I’ve found that finding and hiring quality UI Engineers is incredibly difficult. So many people have entered UI Engineering from so many diverse backgrounds that finding the true engineers of the bunch can be quite a daunting task. For every great person, there are at least a dozen designers who’ve picked up basic coding skills and now fancy themselves capable of holding down a UI Engineer position.  Now that I’m at Netflix, I’m truly among a team of the best UI Engineers I’ve ever worked with. And I’ve got good news: we want you to join us!

I work in the TV platforms group; which means I’m part of the team responsible for delivering the UI on (among others):

  • Sony Playstation 3
  • Nintendo Wii
  • An absolutely massive assortment of connected devices

So…why would you want to join us?

Our engineering talent is top-notch.

We’ve gone way beyond the typical “progressive enhancement” and slightly improved experiences that many people are delivering on the web today. We’re building complete applications in Javascript leveraging design concepts that others working in JS are just beginning to explore including a robust state-chart system, event driven programming (pub-sub), and MVC–all on top of solid OO fundamentals.  This isn’t your average: “throw some jQuery at it and spruce it up a bit” type place; and we’re looking for serious engineers who want to work with Javascript at a high level.

No IE!

Yes, I said it. I haven’t written a line of IE-compatible code since I joined Netflix. It’s kinda awesome.

We get to play with the coolest toys

On my desk at the office, I currently have a half a dozen various devices including TVs and game consoles. How cool is that?  Want more? Think of just about any device you can connect to a TV and lets you watch Netflix. We have them. We get to take advantage of the latest technologies like GPU hardware accelerated compositing to make our UIs perform on even ultra-low-end devices, HTML5 storage for persistence, and CSS3 features without thought of backwards compatibility.

Want exposure, you’ve got it!

Very few, if any, other companies are doing Javascript applications as large and interesting as ours. These are long running, single page, data-driven Javascript applications with connections to HTML5-style video and audio. Fewer still are deploying these applications to an environment of over 20 million customers. I can honestly say it’s very satisfying to see the things I’ve done showing up in living rooms across the US, Canada, and Latin America!

Freedom and Responsibility

Netflix is an amazing place to work. No overbearing bosses, no extraneous meetings, no wasting time on process. Our culture is all about legitimately empowering people and giving them ownership of what they touch.  Lots of companies say they do it; Netflix is the first company of more than 10 people I’ve seen that actually does it.  Freedom and responsibility is the mantra: you’re free to decide how things happen; and you’re responsible for delivering. If it sounds simple: it’s because it is!

Needless to say, it’s a pretty cool time to be on this team.  Post in the comments, send me an email, or apply through the Netflix website.  However you decide to do it, get up and do it! We’re looking forward to talking to you!

Why are you still deploying overnight?

10/17/2011 – Welcome Hacker News folks!

There’s some discussion happening in the comments; but, as always, the better conversation is on the article page on Hacker News itself.

“3:00 am Deployment?  Why Not?”

That was the Facebook status of a former co-worker about a week ago. I happened to be awake and online at the same time (he’s on the East Coast; it was only midnight here) and immediately responded, “The better question is, ‘Why?’”

Deployment.  Production Push.  Go Live.  Rollout.  Whatever you call the process of turning your development codebase into a live, production application, I sincerely hope you’re not living in the Stone Age and doing it in the middle of the night under the guise of avoiding customer impact. Unfortunately, if my past experiences, and the experiences of many I’ve spoken to, are the norm, you very likely are.  If your strategy to avoid customer interruption is based solely on trying to avoid your customers, you’re setting yourself up for even more headaches and long-term failure.

The motivations for these overnight deployments are suspect at best. The claim is that by avoiding the daylight hours, fewer customers will be impacted by the rollout.  Problem 1: You presume there will be problems that impact availability.  You have no confidence in your code quality; or (or maybe, and), you have no confidence in your infrastructure and deployment process.  If you lack confidence that your new system is ready for production, you probably shouldn’t be pushing it to production!  If you think your servers aren’t ready or that your deployment process stinks, take the extra time now to improve them. I’ve seen great companies with absolutely terrible build and deployment processes who have nightmares getting code into production.  At the same time, these same companies refuse to devote more than a single person (or maybe only part of his or her time) to improving that process.

Perhaps even more suspect in the reasoning is the notion that because the process is complicated and volatile, it should be done in off-hours. Problem 2: You’ve got a complicated process and you’re sending over-tired, over-worked people to deal with it.   Imagine, for a moment, that your team is rolling out an update to a service that monitors life-support systems in hospitals.  Do you want tired, stressed, and unmotivated people working on the process?  If deployment is one of your most complicated procedures, why are you sending your people at their worst to handle it?

Earlier, I mentioned that teams are simply attempting to avoid customers by deploying overnight. Aside from this being a futile goal for any global business (and this is 2011), it likely suggests you’re missing two things.  Problem 3: You have no means of doing a phased rollout or a quick rollback. Deployments in this world are likely one-way affairs with a lot of time devoted to pushing the new code and no clean way to revert those changes quickly if something goes South. Make no mistake, I’m not suggesting that deployments are easy (or even that they should be). Nor am I suggesting that everything should always be perfect when deploy code. However, attempting to sneak code out in the middle of the night is hardly meeting the challenge head on.

Compounding all of these issues is the fact that there are some problems you can only see as certain scale is achieved. By hiding from your customers during deployment, you may also be burying your head in the sand with regard to these potential bugs.

Plan For Success; React Quickly to Obstacles

There are several techniques I’ve seen employed that have had a great impact on improving the deployment process to the point teams have felt comfortable deploying while the sun is up.

Involve your QA team early so they have a full understanding of the feature and how to test it. Foster a partnership between QA engineers and developers so they work together to understand the full impact of the feature and ensure that your testing, especially regression, is thorough enough to develop high confidence in your quality.  Always remember that the later in your process bugs are discovered and fixed the more expensive it becomes (especially if these bugs make it all the way to production).  Incentivize your people around delivering quality early–not finding bugs late.

Devote time and energy to your deployment processes; don’t shunt them off onto one guy working in isolation. Establish an owner; but, make sure this person is integrated with the rest of the development team and understands their pain points and needs.  Automate complicated manual processes to prevent mistakes (you know, the type of mistakes that happen when a tired engineer is sitting at his or her console at 3:00 am).

Decouple various parts of your system so they can be deployed and rolled back independently. There’s no sense in having to take your checkout process offline simply because of a regression in your unrelated public API.  This concept is often easier said than done; but it’s incredibly important and worth your team’s investment in time.

Use feature kill-switches aggressively; allow certain parts of your application to be turned on and off via runtime configuration.  Deprecate old functionality rather than destroying it in your codebase. Allow the feature switch to revert to the old code paths without forcing a code rollback or additional push.  Once you’re confident in your new functionality, the deprecated paths can be removed in your next deployment. In cases where this concept is prohibitively difficult or even impossible, modularize the code containing that feature and run both so you can quickly switch back to the old code if necessary.

Avoid unnecessary deployments. When I talked to my friend mentioned above about his 3:00 am deployment, he told me they had to do it to end a contest that their website had been running.  I’m sorry; that’s just not a reason to have to push new code to production. Feature switches targeting alternate code paths could have solved that problem. Moreover, they could have been set on a timer such that the moment the contest ended, the entry form was disabled.  Even following every suggestion here and others you can find, deployments are never going to become easy, only “easier.”  Don’t saddle your team with more of them than you need.

Release early, release often. I realize this mantra has been repeated over-and-over for years; but, that’s only because it’s such important advice. By releasing new code to production often, you’re shrinking the size of each deployment. The less stuff that changes, the less that can go wrong.

Create a system for phasing your rollouts. It’s a much better way to reduce customer impact of issues than simply hiding from your customers. Take your time between each phase to really let issues surface. An example of such a plan would start with a small number; like 5-10%. This level of exposure is still likely less than 100% at 3:00 am; but it’s also likely large enough to alert you to any glaring issues quickly.  Once you’ve cleared that hurdle, ramp up to a number that gives you some level of scale; say 50%. This level keeps your customer impact somewhat diminished if anything goes wrong; and, it will expose issues that may not appear until your app is running “at scale” (such as a new API call taking far more cycles than intended because the caching isn’t working correctly.  You may not notice these extra cycles at low volume; or worse, you may simply write it off that the service isn’t seeing enough traffic to really warm the cache).  Once you’ve crossed that hurdle, you’re ready to ramp up to 100%. Each phase should be designed to contribute confidence along the way that once all customers have this new code, they’ll be getting the quality experience you intended to deliver.

Get Some Sleep (Or Maybe…)

Ultimately, deploying overnight is likely indicative of something (probably several somethings) being broken in your process.  Luckily, by considering your deployment process an important part of your product and devoting time and energy to it, your can turn overnight deployment into a thing of the past and reclaim those late nights for important things like sleep.

Or Adult Swim.  Your choice.

Am I Busy, Fulfilled, or Just Burned Out?

I’ve come to ask myself the above question recently as I’ve entered what’s now my 15th year of writing software for the Web.  Though I’ve only recently started asking that question (recently as in the past week or so) I suppose it’s been in the back of my mind for at least the past year.  Probably longer if I’m being honest. My lament is likely not that uncommon and it’s likely just the truth of what happens when what was once a hobby has turned into a long-term career.

I’ll start by clarifying that I still love what I do; and especially doing it at Netflix. Nowhere have I worked with a more talented group on more interesting problems and I find myself extremely satisfied in my career at this moment.  But if that’s the case, why do I suspect I may be burned (or burning) out?

Easy, I’ve got a stack of ideas for personal projects a mile high that I’ve been “meaning to get to” for years. But every time I sit down at my computer at home to start one after my son has gone to bed, I find myself far more interested in playing a video game, watching a movie, or basically just lounging around the house with my wife. None of this is particularly troubling; except for the longevity of my disinterest in pursuing my own personal projects. For at least one of them, I’ve been sitting on the idea (and domain name) for over a year with absolutely no progress.

For quite some time, I’ve simply chalked it up to being fulfilled at work: my desire to build software is sated by my “day job” and I’m simply yearning for something different in the evenings when I come home.  Fulfillment may yet be the case; I certainly have plenty of motivating factors at home for doing other things (playing with my son, spending what remains of the evening with my wife, etc.); but, if I’m continuing to be honest, I spend a good bit of that time in pure “veg” mode. My wife loves hanging out “old people / parents” style in the evenings reading a book or playing Little Big Planet while I replay some old Final Fantasy game, and while we are spending time together, we certainly aren’t actively engaged with each other in some activity.  I could just as easily pull out my laptop and do some coding (or blogging as the case is right this moment) with Little Big Planet’s catchy music playing in the background. But I don’t.

Which is why I’m starting to wonder if I’m dealing with burnout. Right now it’s not affecting my work-life in the slightest; but I’m (naturally) concerned that if I am showing early (or maybe not-so-early) signs of burnout that it may grow to affect me at work as well. Basically, I’m starting to take it seriously and ask myself the bigger question: assuming that I am burning out, how can I nip it in the bud before it becomes a really bad situation?