Back to the future: Isomorphic javascript applications
- 2. Back to the future:
Isomorphic javascript
applications
- 3. An isomorphic javascript application:
What is an “isomorphic application”
Why did we need one
How did we build it @ Namshi:
Requirements
Choices
What did we actually do
- 4. Isomorphism
Isomorphism is a very general concept that appears in several areas
of mathematics. The word derives from the Greek iso, meaning
"equal," and morphosis, meaning "to form" or "to shape.”
wolfram.com
http://mathworld.wolfram.com/Isomorphism.html
- 5. Isomorphic application
It’s a dynamic website capable of generating its html on
both server and client side, virtually using the same
exact code in both environments
- 6. and a website
is a bunch of nicely presented html
with an interactive layer on top
- 9. Why do we need one?
Robots: search engines don’t cope with SPAs
- 10. Why do we need one?
Robots: search engines don’t cope with SPAs
Loading speed
- 11. Why do we need one?
Robots: search engines don’t cope with SPAs
Loading speed
Javascript doesn’t “fail safe”
- 20. SPA Page Isomorphic Page
~190Kb js Target 100Kb js
~ 40p page speed at least 90p page speed
- 21. SPA Page Isomorphic Page
~190Kb js Target 100Kb js
~ 40p page speed at least 90p page speed
Angular.js ?????????
- 29. We’re already using it on our SPAs
Well known dependency injection
Data bindings
Jade (and we like it)
- 38. New and fashionable…
…we’re eager to try it :)
The virtual DOM looks amazing
Flux (once you get it) seems quite a good idea
JSX…
… but components are a nice idea too!
- 39. New and fashionable…
…we’re eager to try it :)
The virtual DOM looks amazing
Flux (once you get it) seems quite a good idea
JSX…
… but components are a nice idea too!
and The Internet says it can be isomorphic too!
- 48. ok… let’s try getting what we like…
data bindings
jade
flux
components
- 51. So, how does it work?
Step 1
Understand the view
Data Content
Template
Interaction
- 52. So, how does it work?
Step 2
Strip the interaction layer
Data Content
Template
Interaction
Remember our note: stop at the html.
- 53. So, how does it work?
What do we get form the api:
Data Content
{
data: [],
meta: {},
search: {}
}
{
data: “”,
meta: {},
search: {}
}
- 54. So, how does it work?
What do we get form the api:
{
data: “”,
meta: {},
search: {}
}
This guy is html!
- 55. So, how does it work?
Choose a template engine
Template
Jade:
our current angular ones
Nunjucks:
renders on client and server
- 62. Show me the code!
Server entry point
var app = require('express')();
var tpl = require(‘../shared/tpl');
var url = require('url');
app.get('*', function(req, res) {
var path = url.parse(req.url).pathname;
api.getData(path).then(function(data) {
var html = tpl.render('main.html', data);
res.end(html);
});
});
- 63. Show me the code!
And it’s client counterpart
var page = require('page');
page('*', function (ctx) {
var path = url.parse(ctx.path).pathname;
dispatcher.broadcast('URL_CHANGE', {url: path});
api.getData(path).then(function (data) {
dispatcher.broadcast('DATA_UPDATE', data);
});
});
page.start();
- 70. Show me the code!
Title Component
var tpl = require('../tpl');
var vpo = require('vpo');
module.exports = function(data) {
return tpl.render('title.html', {
text: vpo.get(data, 'meta.seo.pageTitle')
|| vpo.get(data, 'title')
|| 'Namshi.com'
});
};
- 71. Show me the code!
Title Template
<title data-iso-component="title">{{ text }}</title>
- 73. Hey but what about my interaction?
well, according to legend: turns out that back in the 90s
humans were able to use websites simply clicking on links and
without fancy UI wow-effects
- 74. Hey but what about my interaction?
Interaction We call them: widgets
they react to UI changes
they attach to iso-components
interact with data-nm-*
and use VUE.js
- 76. Show me the code!
var dispatcher = require(‘../../shared/dispatcher');
var menu = require('./menu');
var cart = require('../services/cart');
module.exports = function($dom) {
$dom.on('click', '#site_menu .search_trigger', function(e) {
dispatcher.broadcast(‘TOGGLE_SEARCH’);
e.preventDefault();
});
this.bind($dom, {data: { menu: menu, cart: cart }});
};
- 77. Show me the code!
<div id="site_header" data-iso-component="header"
data-nm-class="navigation_open: menu.shiftContent">
<ul id="site_menu">
<li><a href="" class="search_trigger">
<i>{{ 'search' | translate }}</i></a>
</li>
<li><a href="/cart/" class="cart_overview">
<span data-nm-text="cart.itemsCount">0</span></a>
</li>
</ul>
</div>
- 80. did we meet our target?
Isomorphism: yes :)
Size: 162kb (including templates)
- 81. did we meet our target?
Isomorphism: yes :)
Size: 162kb (including templates)
Page speed…