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

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!.

How Self-Executing Anonymous Functions Work

In my recent post on creating a jQueryUI widget, I referenced the concept of self-executing anonymous functions. I’ve actually had a few questions come up at the office lately about how they work, so I figured turning it into a blog post might not be a bad idea. It’s an important concept in Javascript many don’t know about. Others know how to use them, but don’t really understand how or why they work. Today I’ll cover step-by-step how to go from a traditional function to a self-executing anonymous function; hopefully it will be clear at the end how these things work.
Continue reading

Create a Basic jQueryUI Carousel Widget

One of the topics that was of great interest at #jqcon was jQueryUI and it’s impressive widget library.  What didn’t receive as much attention was how exactly to go about creating widgets that are compatible with jQueryUI.  In this first of a series of articles in jQueryUI development, we’ll cover the basics of creating a simple jQueryUI widget.  In future articles, we’ll look at how to pair widgets together using the Publisher / Subscriber (pub/sub) pattern.

This carousel is probably not quite robust enough to be deployed to production and I urge you to avoid copying and pasting this code into your live site. This basic carousel aims to teach you how to build one yourself as well as how to build a jQueryUI widget.

Create the Basic HTML Markup

To begin, we need a basic page and some photos thumbnails to work with. The thumbnails, as you’ll see later, can be any size you choose and our carousel will expand to fit them. Note especially that we’re only including some basic shell markup.  There are a few good reasons for this decision: First, it keeps our basic document clean and free of extraneous markup. Second, it is far less work for people implementing our widget—and fewer potential points of error in their process.

<div id="slide">
    <div>
         <img src="img/carousel/0_10.jpg" width="78" height="29" alt="" />
    </div>
    <div>
         <img src="img/carousel/0_11.jpg" width="78" height="58" alt="" />
    </div>
    <div>
         <img src="img/carousel/1_6.jpg" width="78" height="58" alt="" />
    </div>
    <div>
         <img src="img/carousel/1_4.jpg" width="78" height="58" alt="" />
    </div>
    <div>
         <img src="img/carousel/0_9.jpg" width="78" height="58" alt="" />
    </div>
</div>

For demonstration purposes, I’ve chosen the Cupertino theme available for download from the jQueryUI ThemeRoller application. You can choose any theme you desire—or create your own. Also, you can see I’ve created a reference to a  carousel.js file. We’ll create this file as we continue.

Create the basic framework of a jQueryUI plugin

Now that we have our basic structure in place for the carousel, we can begin to create the javascript that will control the animation and interaction. jQueryUI provides a great construct called $.widget() that will encapsulate all of the functionality of the widget within a single namespace and construct. Let’s start by creating a basic widget:

Continue reading

Using Sizzle with Prototype

Recently, John Resig of jQuery fame released the selector engine used in the new version of jQuery called Sizzle.  Sizzle is a new take on using CSS selectors within Javascript and aims to be far more efficient than the methods commonly used by most current Javascript libraries.

Currently, I’m working on a large project that is nearly ready to deploy.  Most of the Javascript for this project has been written using the Prototype framework; however, we wanted to leverage the speed of the new Sizzle selectors engine in our project.  Given that we are deep in the QA process of the project, large code changes are discouraged to ensure code stability.  What we needed was a quick way to integrate Sizzle with Prototype.

The following code can be added to your Prototype 1.6.x file and will ensure that prototype’s main element collection methods (Element#select and $$) both use Sizzle.  I’ve written before on how slow $$ can be, so these are two quick wins for Prototype performance.

//Overwrite findChildElements to use Sizzle http://sizzlejs.com
Selector.findChildElements = function(element, expression){
    expression = expression.join(", ");
    var results = Sizzle(expression, element);
    if(results.length > 0){
        for(var i=0; i < results.length; i++){
            results[i] = Element.extend(results[i]);
        }
    }
    return results;
};