6th December 2016

Who are we?

Alain Vagner

Thierry Nicola

Romain Chivot

Universal JavaScript?

Code able to run in multiple environments

Isomorphic Apps?

Seamlessly transition between client- and server-side rendering without losing state

Isomorphic JS Apps

Isomorphic apps

+

Universal JavaScript

Isomorphic JS Apps

  • Used by the main Web companies

  • Supported by the main JS Frameworks

    • Angular, Ember, Meteor, React, …

  • But slow adoption!

Advantages

  • Code reuse
  • Progressive enhancement
  • Performance
  • SEO

Performance

Performance

SEO

Impediments

  • ≠ envs on server and client
    • JS vm
    • JS base libraries
    • DOM not available on the server!
  • How to share the state?
    • What if we do not use node.js?

Our stack

  • Back
    • Mongo / Scala (JVM) / Play Framework
  • Front
    • React / React-router / Reflux

React.js

  • Component based
  • Declarative syntax
  • Does not need the DOM to run (ReactDOMServer)
  • Minimal changes to the DOM
    • Only applies differences
    • VirtualDOM
  • Seamless transition from server- to client-side rendering

Running JS on the Server

  • VM hosted inside the server
    • Java 1.8: Nashorn, J2V8
    • PHP: v8js extension
    • Ruby: execJS (v8, ...)
    • Python: PyV8, PyExecJS
    • .net: ReactJs.net
  • Node.js instance and "web services"
    • REST WS
    • DNode protocol
  • "Serverless" with AWS Lambda (or equivalent)

Java Nashorn

  • Standard in Java 1.8
  • ES5.1 support
  • Java <-> JS bridge
  • jjs cli tool
  • Faster than Rhino ;)

Java Nashorn

ScriptEngine engine = new ScriptEngineManager()
                .getEngineByName("nashorn");

engine.eval("print('Hello World');");

1st try: same code on both sides

Developing lots of boilerplate code for:

  • routing
  • accessing / mocking rest web services
  • persisting state

1st try: same code on both sides

Why it failed:

  • complexity
  • inefficient
  • difficult to build

Proposed architecture

  • Split Components in 
    • Component
      • Does everything except render (Actions, Listeners, ApiCalls, Routing...)
    • ComponentPresenter
      • Does nothing except render
      • All Data is passed via Props

Proposed architecture: SERVER

  • Only ComponentPresenter is required
    • Data can be passed as Props
    • No Routing, No API Calls, no Store
  • Include data as script tag to prefill client-side Component
    • HTML rendered by TodolistPresenter will be mounted by component Todolist 

Proposed architecture: BUILD

  • ComponentPresenter
    • Code can be reused 100% on server
  • BuildProcess bundles
    • ​All Components and their Presenters for Client
    • Only ComponentPresenters for Server

DEMO

Limits

  • Routing might be duplicated 
  • State management & sync
  • debugging on server-side
  • streaming html on server-side
  • Nashorn Perfs?

Limits: PERFORMANCE

  • First visual for client is faster 
    • Make use of caching (Nginx, Varnish,...)
  • Current Setup with JVM Nashorn Engine
    • First Performance test were not that good
    • Nashorn initial Run 30 seconds (warm up)
  • Considering to Switch to Node Cluster for rendering

Performance: Small lab test

  • One of our apps
  • Test with Nashorn, Node and no SSR
  • ab -n 1000 -c4

Performance: Small lab test

Isomorphic Spectrum

Some sharing

None

Full isomorphic

Bare html with full

client-side rendering, 

("classical" SPA)

View layer (templates and helpers)

Full application is shared (routing, controllers, models, views)

Few abstractions

More abstractions

Conclusion

  • Added value at a cost
  • Define your needs
  • Put the cursor on the isomorphic spectrum
  • On the road towards Progressive Web Apps!

Thanks!

Interesting links

Isomorphic Apps with React

By Alain Vagner

Isomorphic Apps with React

  • 1,592