2013 04-02-server-side-backbone

25
HtMl5 eXpErTiSe aT yOuR sErViCe LaUrI SvAn @lAuRiSvAn Sc5 OnLiNe @sC5 SuRvIvInG RoBoTs aNd OlD BrOwSeRs bY SeRvEr-sIdE BaCkBoNe"

description

HTML5 DevConf 2013 talk by Lauri Svan / SC5 Writing single page applications that respect all web browsers and crawlers should be easy. Still, many end up rewriting their single page application with a server-side templating language, too and get trapped to maintaining two codebases. With the emergence of server-side JavaScript, the “holy grail” of running the same app code on both ends seems attainable. Frameworks like Meteor, Derby and Yahoo Mojito have done it, and the efforts of AirBnB and Backbone LayoutManager bring it closer to Backbone developers, too. Still, the current approaches make such assumptions on the backend or enforce such constraints on the programming model that an old-fashioned Backbone.js developer cannot take them in use. This talk compares the approaches for the “holy grail”, particularly from a Backbone application developer’s perspective. In addition, it presents a programming model by which pretty ordinary Backbone applications can run on both ends. The presented approach works for web crawlers and could have limited use for dumb browsers, too. The talk is technical, with the primary audience being single page app developers planning to move their app server-side. The audience will benefit from previous knowledge of Backbone.js.

Transcript of 2013 04-02-server-side-backbone

Page 1: 2013 04-02-server-side-backbone

HtMl5 eXpErTiSe aT yOuR sErViCe  

LaUrI SvAn @lAuRiSvAn Sc5 OnLiNe @sC5

SuRvIvInG RoBoTs aNd OlD BrOwSeRs bY SeRvEr-sIdE BaCkBoNe"

Page 2: 2013 04-02-server-side-backbone

HeLp! My SiNgLe PaGe ApP FaIlS fOr RoBoTs!

Page 3: 2013 04-02-server-side-backbone

WhY dEsIgN yOuR ApP fOr 1% oR 0.1% oF YoUr tRaFfIc?

Page 4: 2013 04-02-server-side-backbone

UsE a PrOxY fOr LeGaCy BrOwSeRs Browser  

Browser  interfaces  

Plain  HTML  

Full  app  

Server  API  

App  Proxy  

Page 5: 2013 04-02-server-side-backbone

WhAt Do I GaIn? •  Solve the Robot problem – remove double code paths •  Speed up time to first render – bootstrap your DOM •  Potentially solve the “legacy browser” problem •  Ease your test automation – mocking your API/App

Page 6: 2013 04-02-server-side-backbone

WhAt DoEs iT TaKe tO AcHiEvE?

•  JavaScript support (node.js) •  Shared module loader (Require.js / Browserify) •  Some way to emulate/abstract out DOM •  Some shims for Browser APIs (XHR, localStorage etc…) •  Some way to tell your app has completed rendering

Page 7: 2013 04-02-server-side-backbone

QuEsTs FoR tHe HoLy GrAiL ReViSiTeD

Page 8: 2013 04-02-server-side-backbone

•  Some partial layering model •  App touches the browser APIs

through all the layers •  Everything needs server-side

shims!

GrAiLs: WhAt yOuR ApP MiGhT LoOk LiKe

Runs on both as-isCompatibility

LayerPlatform Specific

Application Logic & Templates

Backbone

jQuery

Browser API

JavaScript Runtime

Page 9: 2013 04-02-server-side-backbone

GrAiLs: PrOxY BrOwSeR (PhAnToM.Js)

•  Full WebKit implementation on server-side

•  Runs on its own process/server

•  Context sharing with Phantom.js process is tricky

•  Chromium Embedded Framework & Node.js would even better?

Browser

Reverse Proxy

App Server Proxy Browser

smartclients

dumbclients

Page 10: 2013 04-02-server-side-backbone

•  Share the templates on client and server

•  Separate codebases for compositing the page fragments

•  Simple to understand •  Double code paths: Double

testing, maintenance etc.

GrAiLs: TeMpLaTe ShArInG (tHe nOrMaL wAy)

Runs on both as-isCompatibility

LayerPlatform Specific

Application Logic

Backbone

jQuery

Browser API

JavaScript Runtime

Server Logic

Templates

Any Runtime

Data Representation

Page 11: 2013 04-02-server-side-backbone

•  Full app frameworks that hide the DOM

•  Hide client/server messaging (socket.io etc.)

•  Meteor still uses PhantomJS to render for robots?

•  Lock-in to a certain development model

•  Lock-in to a certain backend

GrAiLs: ShArEd ClIeNt-sErVeR Fw (DeRbY, MeTeOr)

Application Logic & Templates

Custom Framework

JavaScript Runtime

Runs on both as-isCompatibility

LayerPlatform Specific

Page 12: 2013 04-02-server-side-backbone

•  JSDOM - Full JavaScript DOM implementation

•  How about the other APIs? •  Browser/HTML5 APIs is huge! •  Slow to emulate

GrAiLs: SeRvEr-sIdE DoM (JsDoM)

Runs on both as-isCompatibility

LayerPlatform Specific

Application Logic & Templates

Backbone

jQuery

Browser API Subset

JavaScript Runtime

Page 13: 2013 04-02-server-side-backbone

•  Use jQuery for compatibility •  Hide the DOM below

•  Limited adaptation problem •  Potentially faster •  Changes to Backbone needed

GrAiLs: SeRvEr-sIdE jQuErY (ChEeRiO)

Runs on both as-isCompatibility

LayerPlatform Specific

Application Logic & Templates

Backbone

jQuery / Cheerio

JavaScript Runtime

Page 14: 2013 04-02-server-side-backbone

•  Backbone, but abstract out all DOM manipulation from view manipulation

•  AirBNB - Concatenate templates on server

•  No jQuery, no DOM access •  Is it the same anymore?

GrAiLs: AbStRaCt oUt DoM (AiRbNb / ReNdR)

Runs on both as-isCompatibility

LayerPlatform Specific

Application Logic & Templates

Backbone

Adaptation Layer

JavaScript Runtime

Page 15: 2013 04-02-server-side-backbone

GrAiLs: CoMpArIsOn Shared  Client-­‐Server  FW  

Template  Sharing  

JSDOM   Cheerio  

Your  Typical  App  

DOM  Abstracted  out  

Runs on both as-isCompatibility

LayerPlatform Specific

Application Logic & Templates

Backbone

jQuery

Browser API

JavaScript Runtime

Application Logic & Templates

Custom Framework

JavaScript Runtime

Application Logic

Backbone

jQuery

Browser API

JavaScript Runtime

Server Logic

Templates

Any Runtime

Data Representation

Application Logic & Templates

Backbone

jQuery

Browser API Subset

JavaScript Runtime

Application Logic & Templates

Backbone

Adaptation Layer

JavaScript Runtime

Application Logic & Templates

Backbone

jQuery / Cheerio

JavaScript Runtime

Page 16: 2013 04-02-server-side-backbone

AlMoSt aLl oF oUr aPpS aRe BaCkBoNe & JqUeRy YoU cAn’t tEaCh oLd dOg nEw tRiCkS

Page 17: 2013 04-02-server-side-backbone

BaCkBoNe-SeRvErSiDe – oUr DeSiGn PrInCiPlEs

•  We do not need to be a full browser •  We cannot expect the world to change our way •  API compatibility is our friend

•  Make it a polyfill, not a library or framework •  Do not assume anything else than Backbone •  Retain API compatibility, hide the dirty tricks if possible •  Retain the possibility to use 3rd party JavaScript libs •  Keep app specific changes to minimum

Page 18: 2013 04-02-server-side-backbone

InTrOdUcInG BaCkBoNe-SeRvErSiDe •  Run the same Backbone SPA on both

client and server with minimal extra conventions

•  Removes Backbone DOM depencies •  Cheerio jQuery subset for DOM

manipulation •  Polyfills for Cheerio (events, ajax)

Things you may need to change in your app: •  Stick to a subset of jQuery (Cheerio) •  Use a dependency manager that you can

run on both ends (AMD/RequireJS, CommonJS/Browserify)

•  Implement a messaging mechanism between your node.js server and your app

Application

Backbone

jQuery / Cheerio

Browser / Adaptation Layer

JavaScript Runtime

Page 19: 2013 04-02-server-side-backbone

SeRvEr-sIdE BaCkBoNe RePlAcEmEnTs

•  The classes you typically use will run as-is

•  The classes that touch the DOM underneath need changes

We stub out/replace a few things •  jQuery: Cheerio and its fake DOM •  Ajax: Replace jQuery.ajax with a 3rd

party node.js module •  History: Trim away DOM specifics

(window.navigator.location etc.)

Runs on both as-isCompatibility

LayerPlatform Specific

Model

Collection

View

sync

Router

Ajax History

jQuery

Page 20: 2013 04-02-server-side-backbone

One way on how to handle the problem •  Use Backbone events for

messaging •  Single point of control

(App Singleton/Router) •  All relevant objects have an

observable state

WhEn ArE We ReAdY tO SeNd tHe PaGe BaCk?

Backbone App

Router

Model View

Server API

fetch models

handle route

serve JSON

notify

pass the results

Browser / Server

parse path / pushState

Inject to DOM

notify

direct call

event

Legend:

render

verify all states

Page 21: 2013 04-02-server-side-backbone

FeAtUrE dEtEcTiOn – A MuSt HaVe?

•  Require.js is hard to get right on the both ends •  Conditional switches between jQuery and Cheerio needed •  Some client-slide libraries just won’t load

•  Typical applications use DOM and Browser APIs directly •  Typical 3rd party libraries use DOM & Browser APIs

extensively

à You will benefit from a feature detection library

Page 22: 2013 04-02-server-side-backbone

DeMo TiMe

Page 23: 2013 04-02-server-side-backbone

BaCkBoNe-SeRvErSiDe – WoRk iN PrOgReSs

•  It is still experimental, but already demonstrable •  Contributions wanted at our GitHub at

SC5/backbone-serverside •  An article in Mozilla Hacks just got out •  Some of the near-term work involves

•  Handling feature detection (analytics, DOM events) •  Cross-request user state management (localStorage adapters?) •  Concurrency handling (currently we have single, shared DOM) •  Samples on robot & browser detection (express-device)

Page 24: 2013 04-02-server-side-backbone

QuEsTiOnS?

Page 25: 2013 04-02-server-side-backbone

HtMl5 eXpErTiSe aT yOuR sErViCe  

LaUrI SvAn

LeT’s SoLvE tHe CrAwLaBiLiTy PrObLeM!

Software Architect, SC5 Online Ltd https://github.com/laurisvan @laurisvan