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