How Angular Lets Us Iterate Like Crazy
Interior, startup office loft. Friday Afternoon.
SUIT: Hey dude, you know Feature X that we were asking for?
DEVELOPER: Do I ever! I spent all week working on Feature X, and you know, I’ve really started to take a special pride in how it’s turning out!
SUIT: What if—now hear me out—what if we didn’t do that at all. Let’s just cut it completely. Instead, we’re going to do Feature Y: we’ll graph this one thing against this other thing, and have it automatically annotate and blah blah foo bar etc etc…
This type of exchange is familiar to most developers, and particularly to those of us working in the startup world. The “suit” might be an executive, a product manager, or even a designer (it’s just more fun to call the person who’s telling you what to do a “suit” in this context ((As developers we just love to think of ourselves as rebels, although if I’m being honest about suits here, it was actually the development team at Chartbeat that had a tradition called “Menswear Mondays.” It involved blazers. Also, our CEO seems to only have one outfit, and it’s not a suit, but jeans, a white button-down, and cowboy boots. It must be a… British thing?))).
There are a few different ways this conversation can continue:
1. The developer refuses. She’s worked too hard on Feature X, and dammit, you’ll have to pry it from her cold dead hands!!!
2. The developer begrudgingly agrees to throw out her precious work and start again from scratch, but she’s really not happy with it. Deflated, she might not work as hard this next go-round, and the suit might not be quite as inclined to reimagine the product next time (even if it seems like the right thing for the product).
At Chartbeat, we aim for the conversation to continue something like this:
DEVELOPER: Yeah, we can do that. Actually, you know when I said I’m taking a special pride in this thing? It’s because I anticipated that you’d want to do several revisions of Feature X, and I built some flexibility into the code, so making Feature Y will actually not be so hard. I’m almost glad you asked for this change, because now I have the opportunity to amaze you with how fast I’ll churn this thing out!
Admittedly, that’s a completely contrived example and an exaggerated response. In real life, we’d probably try to see one version through and actually test it out with users before deciding to go in another direction (unless we’re in the extremely early stages of a product/feature). Also, a little bit of disappointment in lost work might be expected and is totally okay—we’re not robots. And from a development perspective, it’s not always best to spend extra time making code super-extensible/flexible if there’s a high likelihood that it will never be used outside of its original context.
But my main point still holds: to end up with the best product we’re capable of creating together, we need to be able to change directions, and we should expect to change directions several times.
We don’t have (or want) the luxury of moving from “requirements gathering” to “specification” and then to “design” and “development” phases. All of those tasks are happening in parallel, all the time. As our user researchers and product designers continue their own iterative processes, the “ideal product” will become clearer and clearer. When presented with a new or revised product goal, the engineering team needs to be ready and able to quickly move toward that evolved goal.
Closure: The Good, The Bad, and The Java
Closure has a lot of cool features, but its best feature by far is its compiler. Briefly, a compiler is the software that takes the easy-to-read code that you write and turns it into the small/fast code that runs in production. Closure’s compiler is extremely good at taking a large codebase—for example, our multi-product internal library along with the large standard library included with Closure—and pruning it down to only the code that is actually used by a program, and then smushing that code into an extremely small file. This feature has proven to be a huge win for our “pinger” code (the code that runs on our clients’ websites) since that code is downloaded about 10,000 times each second, and appeared on 71 million unique pages in the month of November. Making that code small is a win for everybody on the Internet, and the Closure Compiler does a tremendous job.
Changing technologies would mean a new learning curve—a short-term drop in productivity—for all of our front-end developers, so it wasn’t a decision we took lightly. On the other hand, those who had tried Angular during Hack Week were excited by its possibilities—we felt it would enable the creation of better features, with nicer/better code, and would boost productivity once we got over the initial hump. At the end of the meeting, we had decided to use Angular for our new projects moving forward, and even to abandon a Closure-based alpha version of one of our new products and rewrite it using Angular.
We continue to use Closure to maintain our legacy codebases and for our pinger code (where the benefits of Closure’s advanced compilation/compression are really huge) but all new projects are now using Angular.
AngularJS: Making HTML into an Application Language
In my mind, the biggest benefit of using Angular is its usage paradigm, derived from its core philosophy that HTML is a document language and what we want it to be is an application language. In short, where most other frameworks have you write vanilla HTML and then, through some code process, grab pieces of the document and “attach” behaviors to transform the static HTML document into user interface components, Angular in essence allows you to extend HTML by creating your own HTML tags for your user interface widgets. The tagline on the Angular homepage sums this paradigm up nicely: “HTML enhanced for web apps!”
To illustrate the difference, under the more traditional paradigm, we would probably create our graph by having some placeholder for it in our HTML document, like:
Not Your Grandfather’s HTML
Using Angular, we’d have an HTML document more like this (simplified a bit here):
<graph class="visitor-graph"> <axis position="left"></axis> <axis position="bottom"></axis> <line name="typical-week" line-data="model.series.typicalWeek"></line> <line name="this-week" line-data="model.series.thisWeek"></line> <line name="last-week" line-data="model.series.lastWeek"></line> </graph>
3 different stream graphs using the same model data but different HTML templates. The model contains several data series, and each template displays a different stream graph by choosing a different set of series.
Now, I’m glossing over a number of technical details here, but hopefully this gets the general idea across. The flexibility gains over a traditional setup should be pretty clear: when a suit decides we should blow away a graph and create a different one with different info, it’s entirely possible that we only have to change the HTML to make it happen! The level of technical proficiency required to do this kind of change is now lower as well—it’s much more likely that a designer (or even a suit!) can actually make the change without a developer and prototype or explore new ideas. This kind of flexibility would be possible without Angular of course, but Angular especially encourages it by its very philosophy of “HTML enhanced for web apps!”
This post has just scratched the surface of what our front-end engineering team is doing to increase and streamline our responsiveness to shifting goals throughout product development. One final note regarding this continuous iteration process: make sure you hire the right people. Our developers, designers, and managers have a mutual respect and trust in each other’s abilities. Without that trust, constantly shifting goals can very easily lead to frustration and disappointment.
More in-depth technical information will be appearing on our engineering blog more frequently, so make sure to check that out in the coming months if you’re interested in the details!