TechCrunch

November 19, 2013

Earlier this year, I had the great luck to be invited to work on the TechCrunch responsive redesign. It was a big undertaking with lots of folks involved:

  • Christine Ying, Ned Desmond, Nico Vincent, Jon Orlin, Alex Khadiwala, Eric Eldon, Alexia Tsotsis, and Matt Burns from TechCrunch who provided the input and direction for the project.
  • Josh Clark, Brad Frost, Dan Mall, Jennifer Brook, Kristina Frantz, Pon Kattera, Greg Sarault and myself working under the Global Moxie umbrella on the front-end HTML, CSS, and JavaScript.
  • Luke Gedeon, John Bloch, and Eric Mann from 10up who did a phenomenal job with the WordPress integration.

Several of the Global Moxie team members have posted about their experience on the project (links below) so I’ll just focus on my contributions in this post. I was the JavaScript guy on this project, but as the token codemonkey, I also handled some of the technical backend stuff (e.g., php, git, automated deployment, etc).

Please read on for the gory details...

Background

If you haven’t poked around TechCrunch recently, I suggest you to take a few minutes to do so. TechCrunch is a sprawling multimedia extravaganza that consists of a nearly a dozen different types of resources - articles, comments, events, slideshows, video channels, author & speaker bios, and more - all capped off with a juggernaut of a homepage that combines everything into a real-time stream of content, that Jennifer dubbed “The River”.

To complicate matters, some of the resources have time-based states that significantly affect the design depending on whether they are dated in the past, present, or future. And the site is meant to be truly responsive - i.e., one site to rule them all on phone, tablet, laptop, desktop, TV, watch, toaster, Jumbotron, etc. And it’s meant to run in whatever browsers those devices are capable of running. And on whatever OS versions those devices are capable of running... etc etc etc.

You get the idea: The TechCrunch responsive redesign was one of the most complex, large scale responsive design projects that I’ve ever even heard of, never mind worked on. It was a project that pushed the team to the edge of their abilities, and I think I speak for everyone when I say that we learned a lot about the techniques, workflows, and processes required for successfully executing a huge responsive web design project.

Overall Considerations

Early in the project, everyone met to discuss the priorities of the site. The ones that were relevant to me were that the site had to be lightning fast, it needed to work everywhere, and “Grade A” browsers would get an enhanced experience.

Within these constraints, we had some very specific discussions about how the JavaScript would be written and what libraries we’d use, if any. My default position on JavaScript libraries is to only use them if you can make a compelling case for doing so. We ultimately went with jQuery, Modernizr, PictureFill, and FitVids. Modernizr, PictureFill, and FitVids were no-brainers because they are pretty small and met our functional requirements perfectly. jQuery was a bigger discussion because it’s large and we weren’t going to be using most of the features that it offers. We finally decided to include it mainly because:

  1. TC is built on WordPress and lots of WordPress plugins have a jQuery dependency, so the odds were good that we’d eventually have to include it anyway. If it’s going to be there, might as well use it.
  2. jQuery makes it really easy for developers of all levels to write bulletproof cross-browser code. While the current developers were perfectly capable of writing raw JavaScript, future developers on the site might not be as advanced.

Side note: We wanted to use version 2.0 of jQuery but there is some limitation within WordPress VIP that forced us to go with 1.9. C’est la via :)

Once we settled on jQuery, we used the following features extensively:

  • Selector engine
  • Event binding
  • Ajax
  • Class manipulation
  • CSS manipulation

Event Binding and Functional Implementations

Roughly a third of the 1500 lines of JavaScript I wrote was basic UI event binding with 18 very short functional implementations (Figure 1).

Functional implementations of JavaScript event handlers for techcrunch.com

Figure 1. Functional implementations of JavaScript event handlers (note the alphabetical order).

A typical event handler would look like this:

And the related implementation would look like this:

With very few exceptions, my functions were fewer than 15 lines of code and 100% devoid of cleverness. In the interest of the long term maintainability of the codebase, I wanted everything to be super easy to read and understand so future developers of any skill level would be able to grok what was going on.

PRO TIP: I religiously separate my event handling logic from my UI manipulation logic. The usefulness of this is especially apparent in cases where you have to listen for different events on different devices that should both trigger the same action. For example, on TechCrunch we display sub-navigation as horizontal tabs in wide viewports and as select elements in narrow viewports. In either case, I have to manipulate the DOM in the same way when I receive a user interaction. Separating out my handlers from my listeners means that I can easily call the same UI manipulation code whether the user event was an onchange or an onclick.

PRO TIP 2: Whenever possible, I sort like objects (e.g., object properties, functions, field names, etc.) alphabetically rather than by something subjective like “importance”. This makes it easy for anyone (including me) to find their way around in my code. Developers often recoil at the thought of organizing things this way but try it for a week and I betcha never go back.

While we’re talking about UI event handlers, here’s a quick tip: In the code, it’s nice to reference a screenshot (or better yet, a video) that highlights the UI element you are binding the event to (Figure 2). I originally did this to help with the handoff to 10up, but on a few occasions I found that it helped me too. I used CloudApp to do this and the whole effort took about 15 minutes, which is a fraction of the time it would have taken me to explain things by typing everything out.

JavaScript event binding with explanatory screenshot URLs

Figure 2. JavaScript event binding with explanatory screenshot URLs in the comments.

jQuery Plugins

The balance of the JavaScript I wrote (around 1000 lines) was devoted to complex UI widgets that I implemented as jQuery plugins.

Some were relatively simple and took no options, like Collapsify:

Some allowed for future changes to class names in the page markup by passing in selector strings, like Carouselify:

Some allowed for configuration options and custom UI markup to be passed in, like Readmorify:

The rest were somewhere in the middle, like Toasterize:

When all was said and done, I was super happy with the plugin approach. It made it easy for me to encapsulate the code to insulate it from accidental breakage, but still allow for easy customization with initialization options to adapt to any future changes to the markup. Robust and flexible: win, win.

Odds And Ends

Some of the most interesting bits of code were short snippets of JavaScript that came about as the result of progressive enhancement and performance optimization efforts at the very end of the process. The two coolest ones were lazying loading of “below the fold” images, and failing over to PNG icons if the browser couldn’t handle SVG.

Lazy Loading Images

The homepage of the site is really long and has a ton of images. When the page is first loaded, the majority of the images are offscreen. Rather than make the user wait for offscreen stuff to load, we point all the “below the fold” image tags at a single placeholder file and update them with the actual image URLs after the page finishes loading. In reality, you’re transferring just as much data (slightly more, actually) but the perceived performance increase is gigantic.

Here’s the simple snippet of JavaScript that does the lazy loading:

There are three drawbacks to this approach:

  1. It doesn’t degrade gracefully: If the user doesn’t have JavaScript enabled, they won’t see the “below the fold” images.
  2. It requires changes to the markup: You have to point the src attribute at a placeholder URL and include the real image URL in a data attribute.
  3. You don’t know where the fold is: Since you don’t know on the server how big a given viewport is, you have to make an educated guess about where to stop including actual images and start inserting placeholders.

In our case, the performance gains far outweighed the drawbacks so we went with it.

PNG Failover

To make it easier to support a broad range of screen densities, we used SVG to create vector icons that would scale perfectly to any size or resolution. Unfortunately, not all browsers support SVG and going without icons would obviously be unacceptable. So, we created a set of PNG icons to display in non-SVG browsers.

It’s worth pointing out that this is an example of “graceful degradation” which I typically avoid in favor of “progressive enhancement”. Normally in a case like this, I would point at the PNG files and upgrade them to SVG for browsers that support it. However, this creates a janky loading experience in the browsers that support SVG so we opted to degrade rather than enhance in this case.

Here’s the simple snippet of JavaScript that does the PNG failover:

Takeaways

If I had to boil this experience down to a list of useful tips for front-end web developers, it’d look something like this:

  • Progressive enhancement trumps graceful degradation. Only use graceful degradation in specific cases where a compromise needs to be made for pragmatic reasons.
  • Carefully consider whether or not to include JavaScript libraries. Only include stuff you’re going to use the heck out of.
  • Separate your event handling from your UI manipulation to make it easier to adapt to different usage contexts.
  • Use a plugin or module pattern to create robust and flexible code.
  • Lazy loading images is worth the effort on long pages with lots of resources. It has some drawbacks but the positive impact on the user experience is huge.
  • Consider using links to screenshots and videos to document your code for yourself and other developers.
  • Alphabetize like objects whenever possible to make them easier for everyone to find.

Of course, everything always depends and YMMV but I think these concepts are great defaults. Happy dev-ing!

Related Links

One More Thing!

I also worked on the Entertainment Weekly responsive redesign with almost the exact same Global Moxie line up. There were tons of similarities between the TC and EW projects, so you might want to check out my EW post which talks more about process and links to a bunch of related articles by the Global Moxie gang.