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

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!

Android “ended” and “pause” events on <video>

In working on implementing playlists for the Brightcove Smart Players, I discovered some pretty annoying discrepancies between the HTML5 video specification and how Android handles video objects.  I’ve created a droidfix GitHub repository which captures an example of how to solve these problems.

The Problems

On Android devices, similar to the iPhone and iPod touch, video is a modal experience; that is, rather than playing the video within the context of the page, the video is immediately expanded to a full-screen experience. We can debate whether this approach is right or wrong all day long if you’d like; but for now let’s just accept it and move on.

On the Android platform, the video player is opened as if it were a new page. To return to the page from the playing (or paused) video, the user must use the device’s back button.  Several things do (or don’t) happen when you hit the back button:

  1. An “ended” event fires
  2. The currentTime property of the video is reset to 0
  3. A “pause” event does not fire

The ended event is particularly troubling when building a playlist-driven player as the ended event can be used to signal to the playlist that it’s time to load the next video. It creates a funny (for the developer; probably not the user) inescapable scenario when the user pauses the video and the next item on the playlist loads immediately until the end of the playlist is reached.

Workaround

I’ll point you to the GitHub version of droidfix.js to see the code; including an example page showing the code in action. Here’s a quick description of the workaround:

First, when timeupdate events are fired, we store the furthest forward position in the video that has played. We have to do this because of item #2 above; once the video actually ends, we’ll lose the last time index.

Now, when an ended event is received, we check to ensure the video has really reached the state specified for an ended event. In other browsers, we check that the currentTime property of the video is equal to the video’s duration; if that’s true, we’ve reached the end of the video.  For android, we check that the furthest forward position variable we stored earlier is within 2 seconds of the end of the video. Why 2 seconds? Well, the Android browser doesn’t fire a timeupdate event at the end of the video; furthermore, it also doesn’t seem to be consistent as to how far from the end of the video it fires its last timeupdate. In my testing, 2 seconds was a long enough buffer to include all examples; it also has the side-effect of being short enough that we can reasonably assert that beyond that point, the user has “completed’ the video.

If we determine that the ended event is legit, we fire a series of custom listeners set up in droidfix. However, if we determine this is android telling us that the video has ended when it hasn’t, we create a custom pause event and fire it so handlers bound to pause will be triggered.

Go fork and wreak havoc!

I put the example code on GitHub with a pretty descriptive README of how it works along with the current known issues / caveats. Feel free to grab it, modify, comment, etc. If nothing else, it provides an example that you can integrate with your own video solutions.

Meeting people at jQuery Conference

As far as I’m concerned, one of the most under-appreciated and most wonderful things about the jQuery community is the humanity of the people within it.  Though I’d met several people at last year’s conference and made efforts to speak to several of them in the year since, I wouldn’t say that I went to the conference with any expectation of being “in” with the crowd. I reintroduced myself to several people and caught up briefly with those who did remember me.

I soon found that I was involved in conversations that I never would have anticipated at a tech conference. Take, for example, an hour long conversation with @codylindley and @mennovanslooten about our families, my wife’s pregnancy, and the excitement and life changes that my impending fatherhood has in store for me. Or talking about cocktails with @tdreyno (one of my favorite topics, by the way).  Or sharing stories about our misspent youths with @dainbrain. Honestly, these aren’t the conversations I’d been expecting to have and I completely welcomed them! It was great to go beyond the concept of, “this is a person who really knows their stuff,” and get to the people behind the twitter accounts.

I met these, and many other people at #jqcon this year (too many to list, honestly). Even if the conference hadn’t been technically top notch, it would have been 100% worth it just to meet and interact with the incredible jQuery community.

As John @unscriptable Hahn said in a note to the jQuery speakers just after the conference:

JavaScript wouldn’t be where it is today without its awesome collaborative community.  You gals/guys exemplify it.  You all rock!

We’re striving for technical excellence; but the community around jQuery (and Javascript at large, for that matter) is really something we should all be proud to be a part of!.

Pass that Interview 2: Understanding Recursion

Recursion is one of the most misunderstood concepts in software development. Truthfully, in modern software development it has been almost completely replaced by iterative control structures (loops). In front-end UI-layer development, it is very rarely used. However, it’s very common that you’ll be asked questions about recursion during an interview. Why? I compare it to airlines hiring Air Force and Navy fighter pilots. No, they’re never going to need to barrel roll a commercial jet-liner but the fact that they understand and know how to do it makes them more complete pilots. Similarly, understanding concepts such as recursion opens up new ways of thinking for engineers.

In its most simple terms, a recursive function is a function which returns a call to itself. Naturally, one has to be careful with this type of construct as it’s easy to create an infinite loop. A typical recursive pattern involves breaking a problem into smaller pieces (such as searching a large data set) rather than performing a process multiple times as in iteration.

A common interview question may involve implementing a factorial function using recursion. Let’s take a quick look at how we could do this:

function fact(x) {
    if(x > 1) {
        return x * fact(x-1);
    } else {
        return 1;
    }
}

By including a call to itself in the return, the program builds up and subsequently tears down a call stack. Rather than looping over an operation, we’re breaking the problem into smaller pieces until it’s simply returnin the value we passed in.

Drawbacks of Recursion

Now that we have an understanding of how to create a basic recursive function, we need to be able to discuss the drawbacks of this approach. First, in most programming language, the loop control structures (for, while, etc.) are optimized for speed and will (in the vast majority of cases) be faster.

Second, the memory overhead for allocating all of those functions can grow massively; especially in dynamic languages like Javascript. In our above example, if a user called fact(200) we would incur the overhead of creating 200 function instances in memory. You can see that for large operations this will get very heavy.

Stand Out

For the most part in front-end development, you won’t be delving deeply into recursion; but armed with this basic understanding of the topic, you’ll stand out from other candidates who aren’t familiar with a wide array of software engineering concepts.