Slide 1

Slide 1 text

view-source:https://twitter.com A very brief overview of twitter.com’s frontend architecture

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

@giuseppegurgone 2009

Slide 4

Slide 4 text

2010 @giuseppegurgone

Slide 5

Slide 5 text

2010 @giuseppegurgone

Slide 6

Slide 6 text

@giuseppegurgone 2010 #!NewTwitter Fully Client Side Application jQuery, Mustache, LABjs, Modernizr Home grown MVC “Necessary complexity” – Dan Webb

Slide 7

Slide 7 text

2012 @giuseppegurgone

Slide 8

Slide 8 text

@giuseppegurgone 2012 Expandable tweets

Slide 9

Slide 9 text

@giuseppegurgone 2012 Inline Previews – Previeweet

Slide 10

Slide 10 text

Journey into twitter.com’s source code @giuseppegurgone Previeweet https://github.com/giuseppeg/Previeweet Reverse engineering Minified code Learnt a ton !0 ~ ,

Slide 11

Slide 11 text

@giuseppegurgone Previeweet last iteration pre–cards

Slide 12

Slide 12 text

@giuseppegurgone @danwrong yey! The future is coming and it looks just like the past, but more good underneath. — Tom Lea (@cwninja) May 23, 2012 Server side rendering – 4x faster Progressive Enhancement Flight.js – Component based UI framework CommonJS + AMD via Loadrunner hashbang #! Hello PushState

Slide 13

Slide 13 text

@giuseppegurgone Architecture Flight.js – Twitter’s JS Framework Code splitting (bundles) App initialization (bootstrapping) Routing

Slide 14

Slide 14 text

function inbox() { this.attributes({ myProp: 'hi' }) this.doSomething = function () { this.trigger(document, 'uiDoingSomething') /* ... */ } // after initializing the component this.after('initialize', function () { this.on('click', this.doSomething) }) } var Inbox = flight.component(inbox) /* Attach the component to a DOM node */ Inbox.attachTo('#inbox', { myProp: 'hello' }) Flight.js A component-based, event-driven JavaScript framework @giuseppegurgone

Slide 15

Slide 15 text

Flight.js Components @giuseppegurgone Get a reference to a node this.$node Organised in UI and Data components Decoupled – trigger and subscribe to DOM events Isolated and easy to test and reason about

Slide 16

Slide 16 text

@giuseppegurgone Flight.js Components

Slide 17

Slide 17 text

Code Splitting Bundles @giuseppegurgone

Slide 18

Slide 18 text

var UiTimeline = require('components/ui/Timeline') var DataTimeline = require('components/data/Timeline') /* ... */ function init(initData) { /* Attach components to DOM nodes */ UiTimeline.attachTo('#timeline', initData.timeline) DataTimeline.attachTo('#timeline', initData.timeline) /* ... */ } module.exports = init Code Splitting Bundles @giuseppegurgone

Slide 19

Slide 19 text

App Initialization Bootstrapping @giuseppegurgone

Slide 20

Slide 20 text

/* Grab initial data */ var initData = {} try { initData = $.parseJSON( $('#init-data').val() ) } catch (e) {} /* Grab modules base path */ var basePath = using.path = $('#swift-module-path').val() /* Grab modules names */ var modules = $('.swift-boot-module').map(function (_, module) { return module.val() }).toArray() /* require modules and call their exported function (init) with initData */ using(modules, function () { [].slice.call(arguments).forEach(function (init) { init(initData) }) }) App Initialization Bootstrapping @giuseppegurgone

Slide 21

Slide 21 text

App Initialization until a few days ago... @giuseppegurgone

Slide 22

Slide 22 text

PushState via HTML5 History API Progressive Enhacement UI component to catch clicks on .js-nav links Data component to fetch data and update the URL / History UI component to update the UI Routing @giuseppegurgone

Slide 23

Slide 23 text

Routing @giuseppegurgone Todd Kloots https://youtu.be/hrZl_EQUbRQ

Slide 24

Slide 24 text

@giuseppegurgone #ThankYou