Slide 1

Slide 1 text

So I’m a doodler, which means while I was making this presentation I kept trying to doodle the backbone logo. I was having a really hard time drawing it, until I noticed that it looked like two overlapping triangles...

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

www.ocupop.com Turns out the Backbone logo was created by Ocupop. Ocupop has also done the logos for Bocoup, HTML5, and Ringmark. You’re probably wondering who starts out a talk with a discussion about logos?

Slide 5

Slide 5 text

I’m Harry, I’m a frontend engineer at Airbnb out in San Francisco.

Slide 6

Slide 6 text

At the heart of it, Airbnb is connecting people that are looking for a place to stay with people that have space to spare. This is the place that I’m staying at right now with my 2 co-workers Dave & Spike. This is our host Kate. She’s probably the nicest Host I’ve ever met. She has a million maps, knows all the cool places to eat and drink in the neighborhood, and has offered to take us grocery shopping at least 3 times.

Slide 7

Slide 7 text

Here’s a heat map of Airbnb listings in San Francisco. On the left is 2008 and right is up till today.

Slide 8

Slide 8 text

AMAZON WEB SERVICES EC2 ELB EMR S3 RDS CloudWatch Elasticache Servers Load Balancing Hadoop Machines Storage Database Metrics Managed Memcache We’re big fans of AWS and use most of their services. If you’re interested in finding out what happens when Amazon goes down, check out a blog post by Tobi Knaup: http:// nerds.airbnb.com/when-the-cloud-gets-dark-how-amazons-outage-a

Slide 9

Slide 9 text

Rails Git Lucene Hadoop Redis MySQL CoffeeScript Backbone.js SASS StatsD Graphite Framework Version Control Search Data Warehouse Key/Value Store Database CS Language CS Framework Stylesheets Aggregates Metrics Store+Renders Metrics We’re a Rails shop. Built with MySql. We’re using Redis to power feeds and an internal tool we call Trebuchet for launching features at subsets of users without deploying. At the moment, Github says our code base is 2.2% CoffeeScript. Which is kind of neat. I only expect that number to grow. It’s not a requirement to write in CoffeeScript, most folks just like trying out. and then a lot of our newest features have been built with Backbone, which brings me to why I’m here today.

Slide 10

Slide 10 text

november 2011 I thought I would start with a story. Our story begins back in November of last year. And it starts with a guy named Joebot.

Slide 11

Slide 11 text

This is Joebot, he’s Head of Product at Airbnb. and one lovely November day Joebot comes over to my desk and asks me a question,

Slide 12

Slide 12 text

Have you seen our mobile site? He asked, “have you seen our mobile site?”..and of course, being the inquisitive engineer that I am, I responded with a question

Slide 13

Slide 13 text

Have you seen our mobile site? We have a mobile site? "We have a mobile site?"

Slide 14

Slide 14 text

Turns out we did. It was just a simple bare bones mobile site. Where if you needed access to your messages or reservations on the go, you could.

Slide 15

Slide 15 text

But when you compare it to the iphone app we had released a year before, you start to get a little sad.

Slide 16

Slide 16 text

About 10% of current site traffic is from mobile devices. So then Joebot starts to pitch me on the idea mobile and dive into the numbers and tells me that 10% of our current traffic is coming from mobile devices.

Slide 17

Slide 17 text

And they were all mostly coming from Social Media. Turns out people love to share links to cool places they find or places they booked. And friends would click through. This is scary when you start to think that one only get one shot at a first user experience.

Slide 18

Slide 18 text

and our first user experience was this.

Slide 19

Slide 19 text

88% 12% Mobile-optimized site Full site So it’s probably not surprising that of all the people that were visiting the mobile optimized site, almost 90% of them would rather scroll to the bottom of the page, click on “View Full Site” and deal with the whole pinch/zoom/click mess of using our full site on a tiny screen.

Slide 20

Slide 20 text

LOW EXPECTATIONS HIGH STANDARDS I tend to try to put things on a scale when I start a project, to kind of see where things lie. And basically with current Mobile Web site the bar was set very low, which was nice, because it felt like we just have to do better than khaki and blue links. At the same time, we love our iphone app and we should be striving to make a product as good or better than that.

Slide 21

Slide 21 text

CTATIONS HIGH STANDARDS But I always get super excited at the beginning of new projects, so in my mind, I was putting the new mobile website here.

Slide 22

Slide 22 text

mobile site? Enter Andrew Vilcsak (mobile lead) Enter Dave Augustine (Front-ender) At this point, Joebot says, I wouldn’t being doing it alone. And he brings over Andrew, who’s our mobile lead and was finishing up work on our internal API and Dave, another front ender.

Slide 23

Slide 23 text

Enter Andrew Vilcsak (mobile lead) Enter Dave Augustine (Front-ender) Could you have it done by New Years? and he asks us if we could have it done by New Years. Historically, New Years is one of the biggest days of the year for Airbnb. With New Years only 6-weeks away, Joebot was looking ahead knowing that there would be a spike in traffic on new years from people sharing out where they are staying and just talking about Airbnb in general. So he asked, could be done in 6-weeks? And, you know, being the pessimistic engineers that we are, we responded

Slide 24

Slide 24 text

done by New Years? Of course! Of course!

Slide 25

Slide 25 text

Of course! Exit Joebot Exit Dave At this point, Joebot leaves the conversation. And then Dave let’s us know that he will be on vacation for the next 3 weeks in New Zealand.

Slide 26

Slide 26 text

So it ended up just being Andrew and I sitting there.

Slide 27

Slide 27 text

How’s the api coming? and I asked him “how’s the api coming?”

Slide 28

Slide 28 text

Almost done. Have you made a mobile site before? and andrew said “almost done. Have you made a mobile site before?”

Slide 29

Slide 29 text

No. You? No. You?

Slide 30

Slide 30 text

Nope. Nope.

Slide 31

Slide 31 text

Do we have a designer? Do we have a designer?

Slide 32

Slide 32 text

Not yet. Not yet.

Slide 33

Slide 33 text

And then Andrew and I shared a moment of silence as reality washed over us. In that moment I started to recalculate my mind scale.

Slide 34

Slide 34 text

LOW EXPECTATIONS HIGH STANDARDS Realistically, we were looking at a project that was going to land here.

Slide 35

Slide 35 text

How do we do this? After the moment of silence, andrew asked “How do we do this?”

Slide 36

Slide 36 text

As all good engineers do, we asked google

Slide 37

Slide 37 text

http://venturebeat.com/2011/08/16/linkedin-node/ Eventually I ended up on this article about LinkedIn’s new Mobile Site

Slide 38

Slide 38 text

http://venturebeat.com/2011/08/16/linkedin-node/ And it said they used Backbone (and linked to it!) and I clicked the link.

Slide 39

Slide 39 text

http://venturebeat.com/2011/08/16/linkedin-node/ Took me to the Backbone docs. Close your eyes and imagine Backbone 0.5.3 instead of 0.9.2. I zipped through the docs in one go. Scrolled back to the top and clicked download and told Andrew we were going to be using Backbone.

Slide 40

Slide 40 text

So that was exciting, mobile web was going to be my first backbone project. Feeling ambitious, I proposed using CoffeeScript. I just sent Andrew a gchat message with a link to the coffeescript homepage and he replied “looks fun”. So we were going to build it with CoffeeScript as well. You’re probably wondering, why would you use two tools you’ve never used before when you have a crazy deadline for project you’ve never done before. The best way I can explain it is that we didn’t know better. I figured building this mobile site was going to be like jumping off a cliff and trying to build wings on the way down. Might as well try to learn something new while we were doing it. It ended up being less stressful because it was more exciting to be learning something new.

Slide 41

Slide 41 text

So this is our office in San Francisco. We have a nice open floor plan.

Slide 42

Slide 42 text

Open Floor plans have some problems when you’re in crunch mode. So our first order of business was fixing this.

Slide 43

Slide 43 text

So we cleaned out what was the storage room and put up some white boards and made a nice home for 6-weeks. Unclear if this was an upgrade or not.

Slide 44

Slide 44 text

And we started coding. Where do I get started? We started with the data layer since we had an API good to go.

Slide 45

Slide 45 text

While we were building out the data layer we would take breaks and sketch out what this thing was going to look like. Which was super easy to do because we were separating out the data and the views. Avoiding the jquery spaghetti doom.

Slide 46

Slide 46 text

We ended up getting it done by New Years. It turned out to be awesome to have Dave join back 3-weeks later because after 3- weeks of sprinting, I was fairly burnt out. Luckily Dave just came back from vacation, so he was ready to hit the ground running. So that was back in January. Since January we’ve been using Backbone in a lot of the latest products we’ve launched.

Slide 47

Slide 47 text

airbnb.com/communities/12 One of the bigger Backbone Apps is still in “alpha” mode, it’s called Communities. it’s like messageboards 2.0 where folks post threads and other people can comment on the threads, you can thank comments/threads

Slide 48

Slide 48 text

airbnb.com/match Match is a new booking process that makes searching and bookings rooms more efficient.

Slide 49

Slide 49 text

airbnb.com/search For a long time, our Search page had lots of trouble with keeping the state of your search when you used the back button. We ended up solving this problem using a Backbone Router and Backbone History. So after each change to the state on /search, the app serializes every parameter and pushes the new state using Backbone.History.

Slide 50

Slide 50 text

airbnb.com/search Now all search URLs are sharable/bookmarkable because they maintain a search state. Before, our search URLs would either be airbnb.com/search or airbnb.com/ search#modified=true.

Slide 51

Slide 51 text

airbnb.com/reservation/change Even if you aren’t making “Apps” writing code that follows the Backbone structure is nice. You get a lot out of the box and your code base gets a lot cleaner.

Slide 52

Slide 52 text

THINGS WE DID

Slide 53

Slide 53 text

Namespacing // global namespace for apps var AIR = { Models: {}, Collections: {}, Views: { Playlists: {} }, Routers: {}, Apps: {} }; We went a simplest namespace possible. We thought that at some point we would want to share models/collections and weren’t sure if views were going to get shared anywhere. So we went with a simple global object that everything would live under. That way if we had multiple Backbone apps, we wouldn’t run into a name collision.

Slide 54

Slide 54 text

Namespacing var AIR = { models: {}, collections: {}, views: {}, routers: {}, apps: {} }; Namespace mirrors folder structure This also has the nice benefit of mirroring our folder structure, which makes things easier to find.

Slide 55

Slide 55 text

- Used for list of Reviews - Throws iterate, iterate:next, iterate:prev events - Works when resorted because it using indexOf - Can decorate models for easy model.next() model.prev() LINKED_BASE Turn collections into linked lists / evented enumerable lists

Slide 56

Slide 56 text

LINKED_BASE

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

- Adds new items to collection on page - Throws a 'page' event - Should throw a 'page:next' 'page:prev' event but doesn't now, as it isn’t in the use case - Has extra properties for page and offset that are passed with fetch PAGINATED_BASE Linked_Base collections suited for infinite scrolling / pagination

Slide 60

Slide 60 text

PAGINATED_BASE

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

- Prerender(), render(), postrender() and associated events - Bindings() call just to clean up stuff and move it out of initialize - Template class variable for rendering JST[@template] convention - classifyAttributes = whitelist of model attributes that you add as classes on the el if they are true VIEW_BASE

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

No content

Slide 65

Slide 65 text

- Optimistic for nearly everything, pessimistic for big creates like reservations, messages, etc. - When model save fails, there is a global fail function that uses the AppViews.flash() method to display the error message ala a flash message in rails MODELS

Slide 66

Slide 66 text

- Static view: look for /:name in JST[name] or use JST['error'] - Google analytics _trackPageview via the 'route' event - Trailing slash in URL www.airbnb.com/communities/:id/ won’t match https://github.com/documentcloud/backbone/issues/848#issuecomment-3449934 ROUTER

Slide 67

Slide 67 text

Router Static View

Slide 68

Slide 68 text

http://nerds.airbnb.com/how-to-add-google-analytics-page-tracking-to-57536 Google Analytics

Slide 69

Slide 69 text

- On render / page view prefer in memory collection or model - Use local storage if no in memory object is present - Idea is to paint something right away - Meanwhile async fetch the data from the server - Do a deep comparison of the returned json with our most recent version in memory / localstorage (we do this via an overidden sync method) - If changes, replace and re-render CACHING

Slide 70

Slide 70 text

- useful for throwing events when the whole app should care - locale / currency changes for example -- when locale changes, ajax fetch new set of translations a json object, replace our phrases and fire an event that re-renders the current view -- all subsequent views will have the new translations GLOBAL STATE MODEL

Slide 71

Slide 71 text

- Use moment.js it is rad DATES

Slide 72

Slide 72 text

Thanks!