SlideShare a Scribd company logo
The Evolution of
Airbnb’s Frontend
!
@spikebrehm
Spike Brehm
____________________________
@spikebrehm
!
@AirbnbNerds since 2011
1. A Brief History of airbnb.com
2. Modernizing our JavaScript Stack
3. Airbnb&Isomorphic JavaScript
A Brief History of airbnb.com
! airbedandbreakfast.com2008
! airbnb.com2009
! airbnb.com2012
! airbnb.com2015
Rails 2.x
MySQL
Vanilla CSS
Prototype.js
!2009
Rails 3.x, Java
MySQL, Redis, HDFS,
Postgres, DynamoDB
SASS, O2
jQuery, Backbone,
Handlebars
!2012
! Bootstrap-inspired CSS frameworkO2
Rails 3.x, Java, Node.js
MySQL, Redis, HDFS,
Postgres, DynamoDB,
Kafka, RabbitMQ, …
SASS, O2
jQuery, Backbone,
Handlebars, React,
CommonJS, ES6
!2015
Modernizing our
JavaScript Stack
A. JavaScript Libraries
Flight
The Evolution of Airbnb's Frontend
! Listing management tools
Hitting a Wall with
Backbone&Handlebars
Backbone & Handlebars approach falls apart as UI
components become more dynamic.
No data binding, so have to either:
1. Re-render whole view when model changes
(slow, lose DOM state like focused fields).
2. Drop down to manual DOM manipulation.
The Evolution of Airbnb's Frontend
Airbnb <3 React
React makes it easier to build&maintain stateful UI
components.
React makes it easier to reason about data flow in your
app.
The Evolution of Airbnb's Frontend
The Evolution of Airbnb's Frontend
B. Asset building
Sprockets
Rails asset pipeline: manages JavaScripts,
stylesheets, images, etc.
Written by Ruby devs to solve problems of simple
web apps.
JavaScript </3 Sprockets
Doesn’t solve JavaScript dependency management:
1. Local dependencies (application code)
2. External dependencies (third-part libraries)
/* application.js */	
//= require_tree .
/* application.js */	
!
//= require ./models/listing.js	
//= require ./collections/listings.js	
//= require_tree .
What if one file depends on
another?
Bad: Order matters
Bad: Objects attached to `window`
Bad: Implicit dependencies
Local
dependencies
$ cp ~/Downloads/backbone.js	
app/assets/javascripts/vendor/	
backbone-1.1.12.js
/* application.js */	
!
//= require vendor/backbone-1.1.12.js	
...	
//= require_tree .
What if I want to use Backbone?
Bad: Manually download
Bad: Manually versioning
Bad: Implicit dependencies
External
dependencies
CommonJS&NPM to the rescue
/* collections/listings.js */	
var Listing = require(‘../models/listing’);	
!
module.exports = ...
Good: Explicit dependencies
Good: Don’t worry about ordering
Good: Objects not leaked to `window`
Local
dependencies
/* collections/listings.js */	
var Listing = require(‘../models/listing’);	
var Backbone = require(‘backbone’);	
!
module.exports = Backbone.Collection.extend({	
...	
});
Good: Central management
Good: Explicit dependencies
External
dependencies
$ npm install --save backbone@1.1.2
Explicit Dependencies
Browserify*
Use CommonJS syntax in client-side modules:
`require` and `module.exports`.
Package dependencies from NPM.
Transforms.
* or Webpack
Browserify Transforms
Handlebars var template = require(‘./templates/user.hbs’);	
!
var html = template({name: “Spike”});
es2015 import Header from ‘./Header.jsx’;	
!
const numMonths = 36;	
!
let photos = users.map((user) => user.photo);
Airbnb&Isomorphic
JavaScript
JavaScript code that can be shared between environments.
The Evolution of Airbnb's Frontend
+
Client-side MVC
Client
Server
Your app API
The Evolution of Airbnb's Frontend
+
Client + server MVC
Server
Client
Your app API
Performance
Initial pageload speed.
SEO*
Crawlable single-page apps.
Flexibility
Run code anywhere.
Maintainability
Reduce code duplication.
Performance
Client-rendered app
Download
skeleton
HTML
User sees
content
Download
JavaScript
Fetch data
from API
Evaluate
JavaScript
Exacerbated on mobile: high
latency, low bandwidth
Server-rendered app
Download
full
HTML
Download
JavaScript
User sees
content
Evaluate
JavaScript
Rendr
Moving Away from Rendr
at Airbnb
It was revolutionary to share code between
client and server using Node.js…
10%
90%
Rails Node.js
…but too hard to share code between server and server—
between Rails and Node.js.
Long tail of features to
rewrite in JavaScript:
1. CSRF tokens
2. Custom headers, i.e.
CDN
3. Middleware
4. Application code
Do we rewrite everything in
Node.js?
The single worst strategic
mistake that any software
company can make:
!
Rewrite the code from
scratch.
Joel Spolsky
A New Approach to
Isomorphic JavaScript at
Airbnb
Browser.
Rails.
App.jsx
Fetch JSON data
Node.js.App.jsx
Mystique:
Node.js rendering service
for React components
Allows us to render React components on the server
from within Rails.
Built on Iso, tiny utility for isomorphic bootstrapping of
React components.
https://github.com/goatslacker/iso
! https://www.airbnb.com/getaways/san-francisco A/B testing now
Thanks!!
!
@spikebrehm
@AirbnbNerds

More Related Content

The Evolution of Airbnb's Frontend