Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Airbnb's Journey Into Mobile Web

Airbnb's Journey Into Mobile Web

From BackboneConf 2012

Harrison Shoff

June 01, 2012
Tweet

Other Decks in Programming

Transcript

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

    View full-size slide

  2. 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?

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  9. 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,

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  16. and our first user experience was this.

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  22. done by New Years?
    Of course!
    Of course!

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  27. No. You?
    No. You?

    View full-size slide

  28. Do we have a
    designer?
    Do we have a designer?

    View full-size slide

  29. Not yet.
    Not yet.

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  33. As all good engineers do, we asked google

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  49. THINGS WE
    DID

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  54. PAGINATED_BASE

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  58. Router Static View

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  62. - Use moment.js it is rad
    DATES

    View full-size slide