Tag Archives: engineering

Building a Rocket in 4 Days – A Kicksend Story

Kicksend lets you send tons of photos to people you love. A month ago, we released a revamped version of the awesome Kicksend web app. The relaunch was closely tied to making Kicksend a lot friendlier towards everyday people. To push that along a little further, we were brainstorming a new photo-sending flow for our users. Here’s how it all came together technically, and how this exercise helped influence Kicksend’s current branding.

Whiteboarding
At Kicksend, we whiteboard new product flows as a team. For this session, we were wondering what we could show users that would give them something interesting to look at while photos were sending. We decided that everytime someone sent photos from Kicksend on the web, we’d show them a subtle animation of a rocket blasting off, which was in line with Kicksend’s existing characteristics as a speedy photo delivery service. Here’s Derrick’s first attempt at fleshing it out on paper

First Draft
We had our illustrator, the mighty Mike Kus, come up with visual assets for the animation, which he created for us in a day. This included the actual rocket, flames, support structures for the rocket, a gauge that indicates photo sending progress and a beautiful moonlit background to set the stage. Here’s the result:

 

As photos send, we wanted the dial to fill up, and have the rocket blast off into the night sky, becoming smaller and receding into the distance.

To make the animation as close to reality as possible, we initially opted for HTML5 with an actual physics-based acceleration engine. Essentially, we would be animating the rocket using projectile motion and then scaling it to be smaller as it blasted off into the background. This involved setting up the HTML5 canvas with a coordinate system that made sense, and scaling/rotating/accelerating the rocket as a function of it’s position on the x-axis, while moving the rocket along the canvas using a projectile function tied again to the rocket’s position on the x-axis.

After a few experiments with Mathematica, we found a few custom projectile functions that worked well, and we had a pretty decent proof of concept. When we decided to test performance, however,  we ran into serious issues with every browser except Chrome. The problem seemed to lie less with doing math in the browser at a rapid execution rate and more towards browser compatibility of the HTML5 Canvas. Animations over a big Canvas were lagging most of the time, and we weren’t confident enough to move forward with it, even though animations on a smaller canvas object seemed to be consistent.

Second Draft
At this point, we were considering scrapping the rocket altogether when we realized we should probably give the new CSS3 animation functions a shot. A little digging showed wider compatibility on multiple browsers so we decided to spend a little time poking around.

20 minutes later – surprise! CSS3 animation support is actually quite powerful, and we wound up replacing most of the rocket animation with CSS3 properties. We scrapped the projectile motion equations completely and also moved off HTML5 Canvas for the most part.

The new way of animating the rocket was now a combination of the following CSS3 properties: transition and transform (for rotation) operating on a rocket image. The actual movement of the rocket (slow start, then speedup) is governed by a custom Cubic-Bezier path that the transition property supports.

 

This method was significantly smoother, was supported on many more browsers and essentially gave us a solid foundation on top of which we could build out more of the photo sending interface confidently.

Rocket Gauge
We still had some trouble with animating the rocket gauge. Since it was shaped like an arc, filling in backgrounds using transparent foregrounds didn’t really work cross-browser. This is when our realization that HTML5 Canvas actually works consistently with smaller canvas sizes helped.

The rocket gauge was then coded up as a simple canvas arc that gets drawn on the canvas as the photos send. We also used the aforementioned CSS3 properties to make the gauge’s needle move along with the arc drawing. For IE 8, we reverted to a simple progress bar since it didn’t support Canvas.

 

We pushed the rocket to production and were super happy with the response from our users. Time from whiteboarding to production push: 4 days.

Send some photos on Kicksend to see the animation in action.

And Then…
A few days later, we were wondering what to do about our email newsletter, nurture campaigns and notifications. At that point in time, the layouts were quite terrible, with very limited Kicksend branding. Worse, they looked unfriendly and unapproachable, which directly affected our conversion rates.

When we gave Mike Kus the mandate to redesign our email newsletters and notifications, he used the new rocket to guide his work, resulting in a fresh new look for all our email nurture campaigns, newsletters and notifications, and one that improved the overall cohesiveness and conversions of the app dramatically.

 

 

Looking back…
We’ve been working on Kicksend for over a year now and as a team we’ve gotten to know each other’s strengths very well. This web app relaunch was some of our best work together as a team, where every person on the team stepped up to make our product shine.

Thanks for reading!

PS: If you’re interesting in working on a tight product team, we’re always hiring stellar folk.

Kicksend Practices Part I – Backend and Web

Kicksend is a multiple platform application, we have clients on iOS, Android, OS X, Windows and the web. All of this is powered by a Rails backend, which we treat as an API server. Here are a couple of practices we have in play right now.

The Backend

(Taken by Tom Raferty)

Avoid to_json

Responses are the equivalent of views for your API; your presentation layer. Hence, you shouldn’t use to_json to generate your response, the same way you wouldn’t put presentation logic in your model. Use a templating system/builder like RABL (which we use) or Jbuilder.

Action cache

We use action caching, based on the principals of key based cache expiration. This keeps cache invalidation very simple for us as they auto-expire whenever an object or a collection is updated. We use a couple of helpers to simplify our cache key generation.

The Web App

The Kicksend web app is made with Backbone.jsHandlebars in Coffeescript. We treat it as a standalone entity, and it consumes our API the same way as our other apps do. There’s no special treatment.

Keep the UI responsive

As much as possible, keep your app responsive and don’t block the user. People have the expectation that rich clients are snappy. Some tips:

  1. Design your app such that you don’t have to use { wait: true }.
  2. Assume that the request will be a success, and have an error state with a retry otherwise.
  3. Load commonly used collections in the background, regardless of the page the user visits.
  4. Keep things asynchronous.

Modularize

Keep your models and collections independent from your views. This makes our views easily reusable (and even nestable). We instantiate individual models in our router and app wide collections on load, and never within the view. In the rare event you need to instantiate a model/collection from within a view, ensure that they are used only within the lifecycle of the view.

Have a single representation of each resource

For each resource (eg. api/lists/1), we maintain a single model representation of it as much as possible. This ensures that the right models are used by our views, so that the any model changes are appropriately reflected in the UI. We use our app wide collections to maintain the “gold” model representation of each resource. Here’s an example:

  1. You navigate to “kicksend.com/home#/lists/1/edit″ to edit your Family list.
  2. To reduce wait time, we make an API call to “/api/lists/1″, and instantiate a single List model – let’s called it Model 1. We then render the list edit page with Model 1.
  3. In the background, we load up our collection of all your lists (KS.lists), which will contain another model of your Family list – we’ll call this Model 2. The rest of the app operates off Model 2.
  4. Any changes to Model 1 is synced back to Model 2 within KS.lists.

Use a view manager

In a single page app, instantiating and destroying your view is important. Mismanagement can lead to a bloated DOM and stray event bindings. Taking a cue from Derick Bailey, we use a singleton to handle all view transitions and cleanups. The Kicksend app has two “containers” that we render views in – within the page or in a modal. With our View Manager, we can easily render any view in either container.

Over the next couple of months, we’ll be discussing more practices we use throughout the Kicksend ecosystem, so stay tuned. As always, we are always looking to improve and we love to hear any suggestions or improvements you may have!

Catch us on Twitter at @Kicksend and @derrickko. Sounds interesting? We’re hiring.

How we rewrote the Kicksend web app in one month

Startups have a phase where the first generation of the product has to make way for the second. In our case, we set out to create

  • a wonderful experience for our users
  • a faster, leaner front end code base
  • a great foundation to build out new features faster

And, those goals meant it was also time to rewrite part of our Kicksend stack.

Rewrites are strangely attractive. Developers love to work on a sparkling clean code base. But in reality, there’s much more to a rewrite beneath the surface. Like all those implementation subtitles and edge cases you took for granted.

Before jumping into a rewrite, start with the business and product considerations, because if a rewrite is the best path then with the right planning and approach, you’ll avoid a lot of pain.

Here’s what worked for us at Kicksend.

Be very clear of your goals

Rewrites can quickly balloon out of control. There will always be the tendency to throw in new features. So it’s important to keep the scope of the rewrite focused. Scope out a minimum viable rewrite – a great place to start would be hitting feature parity with the original version.

We set out to rewrite only the upper levels of our stack, and not the entire application (there was no reason to). In terms of changes, that meant we had three goals:

  1. a migration to a new database schema
  2. a refactored, new RESTful set of APIs
  3. a complete rework of the web application

With those goals in mind, we made sure to hammer out the scope and implementation of each item. We whiteboarded the schema migration, the APIs, and iterated on the new web application’s user-facing design before we wrote a line of code. After which, we split these items up into Pivotal Tracker stories.

From then on, we made it a point not to introduce any features that weren’t directly related to the implementation or didn’t fall in line with our goals, which worked well to curb feature creep.

Simplify

It’s a rewrite. Take the opportunity to simplify.

Each feature and technical decision that made it into our rewrite had to meet the following criteria:

  • simplified our technical implementation
  • improved user experience
  • boosted productivity

1) Cut out Features - Since we measure everything, deciding what to leave out of the rewrite was a straightforward, data-driven decision.

2) Optimized UX - An example of a feature that we did rewrite is “Lists.” In Kicksend, lists are great way to easily send files to private groups of people. We felt that this was a core experience of Kicksend, and we had to nail the user experience. With the rewrite we introduced more intuitive ways for our user to manage their lists and achieved simplification.

 

 3) Swap to Coffeescript – Using Coffeescript made this development simpler and fun, which in turn boosted our productivity. For the curious, the rest of our frontend stack consists of Backbone.js with Handlebars.

On balance, the scope of our rewrite actually turned out to be smaller than the original version.

Get it on production. Now.

Don’t do a waterfall-style “big bang” release. Don’t coop up your rewrite on a staging box, only to be deployed to production on release day. The quicker you can deploy an iteration of your rewrite to production, the easier your life will be.

We spent the first two weeks preparing our code base to accomodate the rewrite on production. That meant a whole bunch of chores like retrofitting our current APIs to write to the new schema, changing up the web application to use the new set of APIs, and migrating over to Rails’ asset pipeline. After all that, we were running our rewrite live in production, in parallel to the original version.

Results

  1. We continuously deployed (our usual cadence)
  2. We battle-tested our rewrite in production for a month and a half
  3. “Launching” just meant flipping a switch

Rewrites are tempting, but can also be deceptively complex. Don’t rush into one. Have a well thought out plan. It worked for us; we launched smoothly and right on schedule.

So check out our shiny new web app, or grab our mobile and desktop apps.

Catch us on Twitter at @kicksend and @derrickko. And join in the discussion on Hacker News.

PS. Sounds interesting? We’re hiring.

How we decreased sign up confirmation email bounces by 50%

Kicksend uses the tried and tested pattern of sending our new users confirmation emails to verify their identity. With that, there will always be emails that aren’t delivered successfully, which we care about a lot.

A bounced confirmation email means that our new user wouldn’t have been able to activate their account. So they’ll either have to either sign up for a new account, or contact us to change their email address. These are steps we don’t want to put any user through.

So we recorded and setup detailed notifications for every email bounce, to make sure that we are always aware of what’s happening (thanks Mailgun!). And we soon started to see patterns.

People would misspell their email addresses and be unaware of it, resulting in a delivery failure and a lost user. And it got even more interesting – most of these invalid email addresses were a result of a misspelled domain; “hotmail.con”, “gnail.com”, “yajoo.com”. A clear opportunity for improvement.

Example


Taking a leaf from Google, we created a quick plugin that suggests the right spelling of misspelled email domains. After launching it, we saw bounces drop by 50%! Little prompts to guide the right user behavior always goes a long way. Give it a try.

And we have open sourced it. Mailcheck.js, the jQuery plugin that powers our spelling suggester, is now available for forking on Github: https://github.com/Kicksend/mailcheck. Enjoy!

Catch me on Twitter @derrickko.

Less Annoying Activity Emails: Clustered Notifications Using Resque

Two weeks ago, our number one user request for Kicksend was not related to filesharing (because we were already awesome at that), but for clustered email notifications. Kicksend users often send files in small groups punctuated by short intervals. For example, they drag in a batch of photos from iPhoto, then select the next batch and then drag those in with a brief interval in between those two events. The first round of email notifications for our MVP just sent out an email for each file, which as you can imagine was pretty annoying if someone sent you twenty files at once. Time for an upgrade.

What we really needed was a way to group file upload events together so that we could send a digest email instead of multiple separate emails, and since we were a weeknight-only startup with limited time and resources we needed to do it in a way that was simple, quick and scalable. 

We were already using Chris Wanstrath’s most excellent Resque for our background jobs, which includes sending out emails using resque_mailer. It would’ve been nice if any solution we came up leveraged the existing background job stack instead of adding a ton more dependencies.

Thinking it through on paper, we got a basic flow down that solved 80% of our problem. First, we needed the following pieces:

  • The ability to schedule Resque jobs to be run in the future
  • A special notification event class to handle the clustering logic
  • A clean way to update scheduled notifications with new information

We found resque_scheduler and it’s Resque#enqueue_at method to be perfect for scheduling Resque jobs to be run in the future (we believe DJ has the same feature) and also a way to remove already scheduled jobs. Next, we created a NotificationCluster class that encapsulates all of the logic required to create, group and schedule email notifications. Here’s what that class looks like:

Now, let’s trace through a typical ‘event’. Bear with us here. When the user drags in the first file: a new NotificationCluster object A is created in the data store and that object’s email job is scheduled to be sent out in CLUSTER_TIMEOUT seconds. Then, every subsequent file that’s uploaded within CLUSTER_TIMEOUT seconds since the previous one will update object A and append the file-id to A’s associated_files serialized array. Along with the append, it will remove any existing jobs scheduled to be run for A, and creates a new email sending job scheduled for the future.

This mechanism allows for rolling events. When the user is done uploading files and a subsequent CLUSTER_TIMEOUT period has passed without any new files, A’s final email is then sent out to the recipient with a list of all the files (from the serialized associated_files array) that were updated.

The solution we’ve outlined is a very simple way to do clustered events without having to resort to K-Means clustering of timestamps, which would’ve definitely taken us a lot longer than the hour and a half it took to implement and test this. When time and money is limited, resourceful solutions built off pre-existing, well-tested libraries that solve 80% of the problem trumps hours of coding up new solutions that’ll get you the remaining 20%.

Ultimately, all of this engineering just comes down to making your users happy. People have a very low tolerance to a badly written email. Doing whatever you can to convert annoying emails into useful ones is, in our opinion, totally worth it. 

Kicksend is effortless realtime filesharing with your family and friends.