I think the word denotes mapping of client side data to the server side data. In frameworks like Meteor, if there some addition or deletion of data on the server side, browser notices the changes and updates the page accordingly. In frameworks like Rails or Django, changes of data on server side doesn't update the client side page (unless you customize the app with ajax)
We do this sort of thing on the site I work on, Google+. Initial page-loads are rendered on the server, subsequent page-loads are rendered on the client. Really good for performance. It's just the templating system that's common code, though, the server is still Java.
Why not render the templates in PhantomJs and have a user account that can push the rendered template back into the server cache. No need to duplicate the work of writing two backends. Or hell, just use Rhino and generate the reified pages on the server.
The soy templates have a java (tofu) backend already (several years old).
The phantomjs idea is a shit idea and should go away. Phantom is fine and good for headless testing (hells we use it for quite a bit else) but seriously it is not a solution for a real load.
In my scenario an alternative (Rhino or PhantomJs) engine would generate a page once and then push that rendered page to the server. No real load would be sent to it. Single code path for all template rendering. Zero cross implementation bugs and the client still gets a fully reified page on first load.
Shit idea is a little harsh for sure, but the problem is when your page relies on dynamic data and you can't prerender it. It's just too expensive to boot up a DOM on the server.
sorry thurn, this is off topic: is there a complaint / improvement suggestion page for G+? there are some serious design bugs in G+ that we'd love to have/solve(d) :)
My main concern - how does application state get handed off to the client-side code after the initial render? Sure, it's nice to have some pre-rendered templates, but at some point it needs to "transition" cleanly to the client.
I just started hacking on Rendr last night, so I don't know if it shares state between Express on the server and the client-side app. My guess would be that Rendr does not have this built in as it's stated design goal is to stay small/modular.
(author here) We just bootstrap some JSON onto the page to transfer application state to the client. It's the same approach as the `express-state` (mentioned in a below comment). Same as any client-side app.
You keep using that word. I do not think it means what you think it means.
Using precisely defined mathematical words in contexts where they only make sense vaguely to a layperson ruins their original usage. Make up a new word. Repurpose a shitty English word. But leave our damn maths words alone.
Old man quarterto shakes his fist at you! Get off my smooth, compact lawn!
Amen! I'm glad someone said something. That really bothered me. It's actually the only reason I clicked on the link. In my head, they'd somehow mapped Javascript onto another language and were able to convert interchangeably between the two or something like that. Needless to say, I was disappointed.
Whoa old man quarterto, who said the word ever belonged to math people in the first place? I could argue that math people have a bad habit of squeezing English words into strange contexts that corrupt the original meaning. Take "manifold" for instance, or "curl", or even something as harmless as "mode". They all meant perfectly fine things until the math people claimed them as their own.
He has a point. The system they are describing in the article isn't even isomorphic. If it WAS, it wouldn't depend on node.
To clarify, if it was a true example of isomorphism it wouldn't be contingent on a single runtime environment or language.
A better example of isomorphism in computing would be two modules of code that perform the same function and have the same abstract interface but that are written in DIFFERENT languages.
I don't see why different languages would matter. It's a matter of abstracting things from one system and having that abstracted set function in a different one. edit: To clarify, yes, the set would remain intact and functional in both systems.
I've been thinking about this for the last few hours... and regardless of the language used, I think I'm finding the point of confusion!
isomorphic: modules that have the same abstract interface and functionality but that are written in different languages and executed in different runtimes
monomorphic: modules that have the same abstract interface and functionality and that are written in the same language and have the same runtime
heteromorphic: modules that have the same abstract interface and functionality and that are written in the same language but run in different runtimes
homomorphic: modules that have the same abstract interface and functionality but that are written in different langauges that run on the same runtime
See, the thing is... languages are compiled to runtimes, right? But they are transpiled to other languages...
There surface area of this discussion is very interesting and seems to have some interesting properties, and if you don't mind the math pun, it is truly a complex issue!
As for how to actually name these different things, I don't think I really mind... maybe isomorphic and monomorphic swap in the above definition... I've been reading some latin and greek roots to try and give them good names, but I'd love some suggestions!
For example, a function written in Scala that functions the same as a function written in JRuby and compiled to the JVM would be an example of a "homomorphism".
And a function written in JavaScript that is compiled to run in both node and the web browser is an example of "heteromorphism".
A function written in JavaScript that is compiled to run in the Ruby runtime is an example of "isomorphism".
Monomorphic would just be sort of like an identity property.
Also, I have no idea what I'm going on about, so please help me fix the language!
Maybe isomorphic IS the correct term for what is going on in the article, who knows? :)
A lot of mathematics intersects with programming. There is a clear notion of isomorphism in programming and computer science. The pedestrian web dev is not aware of it.
Imagine a graph theory researcher calling a program which handles graphs a web app. Isn't that confusing?
>"According to M-W "isomorphic" has pre-existing definitions from medicine and chemistry"
That link doesn't say that those definitions were "pre-existing". They say the first use was on 1862 but failed in specifying in which context was used first.
(author here) Good point. TBH, I have no idea what "isomorphic" means in the mathematical sense.
I was inspired to use "isomorphic" from a 2011 article by Nodejitsu [1]. It seemed like a fine way to describe this approach. I would gladly use a better would if I were to find one.
Technically, you're correct, see the biology and chemistry use of the word. But seeing how you're dealing with a mathematically inclined audience, there will be disapproval. I think it's a very useful concept in general, the more it gets out into the world, the better.
What about simply DRY? isn't that what you're aiming for - having code sharable between client and server such that you don't have two pieces of code that do the same thing in two different places?
Shall "multiplateform javascript [code]" be suitable here? Looks like this is all it's about: having a single js code generating the same results, with no dependance on the plateform.
I can't disagree more. From thefreedictionary.com:
(Mathematics) A one-to-one correspondence between the elements of two sets such
that the result of an operation on elements of one set corresponds to the result
of the analogous operation on their images in the other set.
This seems exactly like what the author is describing. Colloquial English does not have an objective standard -- it is a constantly evolving language. I certainly agree with this term's usage unless a better one is suggested.
But notice that the isomorphism is the correspondence itself. When you read "isomorphic JavaScript," you would be right to ask "isomorphic to what?" What is JavaScript in correspondence to?
If there is an isomorphism here, it is between the separate runtimes (client and server), and not the language.
I agree. Even if not precisely defined, isomorphic usually refers to things that are (possibly) different, but "look the same" under a particular lens (for example, a set of operations).
OTOH, this is talking about the same thing running in two different contexts. More appropriate terms might be uniform, homogeneous, ...
Actually isomorphism only means, similar form. And it makes sense in the context - as in server and client code have similar form.
The fact that it's used in math is incidental. It's used in biology and chemistry as well. It does leave space for ambiguity because of closeness of math and computer science, but overall it's correct usage.
I wish I could filter out totally uninteresting threads in HN website that are disturbing my reading experience - is there any CSS hack / tool that adds a "don´t show this thread" button to HN discussion threads?
A great thing about the web is that a multitude of server side languages can be used. While I don't ever want to have to write the same template twice, having everything converge on nothing but Javascript doesn't seem like a very inspiring future to me.
If you are building a service or API, then you can do that in whatever language you like. The natural language for writing client side apps is JS (ok, the only language, for now).
Correct. If you're already writing a bunch of JavaScript for the client-side, then just think about this approach as migrating some of that client, UI logic to the server.
No. Any thick client architecture has to deal with this problem. The current resource-oriented models (by which I mean they're focused on serving http resources) are severely limiting those of us who want to develop a web application.
Some people are side-stepping the issue by saying that the whole presentation layer must be moved to the front-end, but that approach is really incompatible with the web.
If anything, the current state of the front-end is thanks to server-side developers who want to bring their world view to the browser. (Think: MVC -> Backbone / Ruby -> Coffeescript -- apologies to the authors of those tools)
I whole heartedly agree and lately I've been getting worried that too many people in the web community are onboard with a node-centric view of the browser...
It may the same language, but the runtimes are completely different and have incredibly different use cases and environments. Not only that but I'd rather have a healthy ecosystem where the Unix runtime, .NET runtime, JVM runtime, and even interpretive runtimes that are built on top of those runtimes likes Ruby, Python and JavaScript are all considered equally!
That is closer in line to what the real definition of isomorphism is describing. :)
In my experience, including rendering code both server-side and client-side is overkill. Just put all the rendering and templating code client-side, period.
If you want your page to appear more quickly, then instead of loading content data with AJAX afterwards, just include JSON arrays of content directly within the HTML source itself, and use JavaScript to populate the page instantly, even as it loads.
(Obviously SEO is a different case, but there are tools built for that specifically.)
The approach you mention is much easier. However, it does make for slower perceived page load times, even when serializing JSON on the page, because the browser has to fetch, parse, and evaluate JS files before rendering the HTML into the document. This can take many hundreds of milliseconds, especially on mobile devices.
In my experience, server-side rendering has led to a much better UX.
I think the idea is that the same bit of code would be running both on the server and/or the client, depending on what you need. So it wouldn't require any more work on the end developer's part.
I like the basic idea, but my hope is that we can go the other direction and bring more interesting languages to the client side. I know this is done to some extent using JS or Asm.js as a compile target with a whole bunch of existing projects. But it would be great to see this really move forward.
It seems like CoffeeScript did this rather successfully, and with source maps, the debugging story is getting better too. Any reasons why this might not be a more compelling future than the "JS everywhere" vision?
this is interesting so Javascript can now be used for server-side which removes the need for Ruby on Rails and Django basically? can someone summaries this article, time is of the essence.
For those interested in GWT, I've got a similar library I'm working on for GWT, but I call it "PoA" for Page-Oriented-Architecture. The idea is to have the best of both worlds from both an SPA (Single-Page-Application) standard point, while preserving the fundamental webby-ness of URLs/pages. Of course, since it is Java, a lot of code is shared between server and client, running full performance in the JVM, plus globally optimized JS on the client.
It works by authoring all pages in HTML/CSS/WebComponents with basic MDV-style two-way databinding as separate stand-alone pages. These are then globally optimized together as a monolithic SPA application, and then code-split back into separate pieces. A servlet then processes the template on the server, does the data binding, and sends back a fully rendered bit of HTML + inlined JSON data within a single HTTP request. The JS code starts up and binds to the template and model, and then launches async loads of the rest of the compiled templates.
You get URL addressability, crawlability, fast initial page load, plus SPA-style fast switches, global aggressive optimization, offline, sharing of heap objects between pages, etc.
I'm curious to see how this shared rendering between client/server plays out for non JS based frameworks such as Django, Rails, etc.
I've been feeling the burn myself—the desire to fully switch to handlebars templates in my Rails app. The expensive part would be building my API out more than I have, because I rely on associations in Rails view renders. However, gaining 1 template engine to rule front & back.
(OP here) Probably your best bet is to create a small Node web service that takes a template name and data and returns HTML. Then your (Rails, Python, PHP) app can call out to that in the request cycle.
Instagram.com does something similar; it's a Django app.
Seems to me that the approach with best separation of concerns would be to redirect the initials requests directly to node, which would then call the Python/Ruby/etc API to get the data to render the template. After that, the browser JS could call the API directly, and so the latter would never have to know about templates at all.
There's a different approach that performs all rendering server-side and sends snippets of HTML to the browser to be woven into the existing page. I suspect that would be more natural for non-JS frameworks.
I'm having a brain freeze here. How do you render a DOM on the server and then push it out to the client? Convert in memory DOM to a text/html representation before sending?
To iterate a point in the article, a number of client-heavy sites built on Angular and Ember have been rendering their content on the server-side to be presented to crawlers like the Googlebot for SEO purposes.
I understand node.js with V8 and also Phantom JS but how does a client browser view the DOM rendered on the server is what I'm asking. I'm guessing it gets rendered and serialized to JSON for transport, but I could be over-thinking it. Server side rendering is the same as it ever was, just with new tools.
There are a few options. Easiest is to just render HTML strings on the server, not actual DOM. But, you can also use a DOM implementation if you want to, like jsdom or PhantomJS, and then capture the outerHTML of an element as an HTML string to serve. But, that is slower. React.js has a nice middleground approach; it has a fast pure-JavaScript DOM abstraction that can emit either DOM (browser) or HTML (server).
There is a confusion between isomorphism and monomorphism when it is related to JavaScript as it runs in the web browser runtime compared to the node runtime.
I feel this tension is at the root of the CommonJS vs AMD discussions that have been taking place recently as well as issues related to npm, bower, and browserify.
Monomorphic code, while being very easily shared amongst different runtimes, still needs to aware of the mechanisms, strengths, and weaknesses of those runtimes!
Projects like browserify-cdn and sites built with on top of it like requirebin.org do a lot to bridge the gap but raise some interesting questions about wrappers like UMD.
I feel there is room for a better protocol for sharing code between the different environments.
I'm currently doing some research on the subject and plan on writing a spec and implementing some example interfaces.
BTW, projects like Bower head in the opposite direction and seem painfully unaware of their actual context...
I mean, installing a package manager to then install a package manager should raise some eyebrows, right?
Wasn't this the idea with GWT so many years ago? In GWT's case, it was Java on both sides. I don't believe that it solves the problem and I don't believe Javascript on both sides will solve the problem.
This is a classic "impedance mismatch" like O/R mapping. At the end of the day, there may be no good, i.e. simple, solution. It is inherently difficult and messy.
GWT is not Java on both sides. Its Java on the server, Javascript on the client. The Java client side code compiles to Javascript...the abstraction is way greater than what OP is presenting. (JS & JS)
GWT is/was a terrible amount of overhead baggage, but had some brilliant event systems and DOM tricks for its day.
> GWT is not Java on both sides. Its Java on the server, Javascript on the client. The Java client side code compiles to Javascript..
And the Java server code compiles to JVM bytecode. Languages often compile to some other form to run, and the fact that the compilation target is different for different parts doesn't change that the programming language is the same.
> GWT is/was a terrible amount of overhead baggage
GWT is very much alive and kicking, but it's primarily used on internal business applications with large and complex code bases. And what overhead baggage are you talking about? GWT is designed to reduce overhead though cross-compiled, browser-spesific builds, dead-code removal, and js-optimizing.
Conspicuously absent from the author's article was Angular. What is it about Angular that doesn't lend itself to this dual purpose frontend and backend infrastructure?
Lots of potential hidden state as well as the need to support the entire DOM API server-side. For example, directives may add hidden state to the DOM and assume full availability of DOM API (even jQuery). The server will have to support all that
Also, you'll have to re-do the entire rendering on the client, then swap the server-generated DOM with the client-generated DOM. Its probably possible - but is it worth the effort?
At the Meteor meetup last week, David Greenspan outlined an interesting approach to how Meteor UI separates the "template-parsing" logic from the "rendering" logic with an intermediate representation (in Javascript) of the steps you need to take to produce that HTML. Check out the video (relevant slide is at 16:47, but the entire talk is awesome):
The cool thing is, other template languages (like Handlebars, Jade, etc.) can compile to this intermediate representation, which then gets rendered on any updates.
If the front-end community could agree on a protocol for how to represent these steps in, say, JSON, then we could be on our way to a world where you could use any rendering engine with any template library, on the client or the server.
That is, if the community could agree on a representation :)
Funny thing, had related talk today with my co-worker...
Anyway, so problem currently is that client devices are slow and HTTP requests are expensive/slow. If these were not issues - I guess rendering on a client would be just fine?
If above is correct, I do not see good reason for smallish websites/apps/whateverucallit fallback on server rendering, as it looks like every single year mobile devices getting faster and faster. And we have SPDY on a way to mainstream.
Do I want to wait 3 seconds to get HTML or wait 100ms to get bootstrap code and see pieces rendering as data comes in? Probably doesn't matter, since it will take roughly same 3 seconds to render it on client side.
Ultimately, perceived responsiveness of webapp depends a lot on particular implementation. If you wait for all data required for page to render - yes, it will be slow. If you render pieces of page as data comes in - user sees that something going on and this is good enough. Why it should matter where data will be converted to presentation, on server or on a client? It is still waiting. And if client is not happy with it? Buy beefier hardware!
No server should take more than 100ms-500ms on a sufficiently cached page to process and to begin transferring, in non-edge cases. The only thing that could take that long is a shitty datacenter/vps, and as such, transfer speed/latency limits will encumber all types of requests.
In the end, you still have to transfer data from databases, so ignoring that, client-side template rendering seems like a non-issue to me. Surely it's never the latency issue unless you're serving at ~100+ requests per second, which translates to many millions of requests a day, and I don't believe 99% of websites are doing this.
Mostly Django user attempting to ask from outside the Node/server-side js community for an explanation of why we're invoking "isomorphic" here:
As far as what's going on, are we just saying that the js for rendering the page is equally capable of talking to the API and doing the DOM work while running on the server as it is when downloaded, interpreted, JIT'd etc before fetching the actual request content? Does this mostly eliminate an extra RTT to the API if the js/web application server experience relatively zero RTT due to network/physical proximity to the API server? Does this incidentally make SEO possible while having fat clients and server-side initialization all in one setting and with mostly one code base?
Assuming I'm on track, working backwards towards understanding the implementation as it relates to "isomorphic", if a program's output state is a valid input state to initialize the program (we're talking fat, stateful MVC clients after all) state, then all that's needed to re-create the entire execution state of the current program is to copy itself into the output in such a way that it will be run upon receipt (we link js files in the page). I'm going to take a wild guess that the output state of the client doesn't have the necessary template tags etc used when a cold page is rendered, server or client-side, so the server has to serialize some of the state and pump it into the copy of the program to make it as if the client we're sending is the client that rendered the page, keeping the client's internal representation consistent with the state of the page.
If this is true, we're taking a program that cannot be initialized from it's own output and modifying it to be a program that achieves the same effect. JS is modifying JS, and is therefore said to be "isomorphic?" It still sounds like a glorified way to describe a serialized execution state, one that happens to involve a program in a language outputting a valid program in the same language, but the purpose is to achieve the effect, as far as the developer is concerned, that the output is a valid input, albeit with an intermediate technique to make the abstraction hold water.
If I'm on track, then I have to say it's rather as if we have a fat client, output of one render, serialized client state (because the DOM is not sufficient to re-create the program state or else our client js has to initialize from one format that's programmer friendly and one that's program-friendly), and necessarily a third-leg responsible for injecting the client js and serialized state as js into the output.
Standing to see the mauve dusk of my life against the impending rain of spears and arrows, I must ask if we can not simply call the js necessary to achieve the equivalent state of running everything client side a "continuation" and call the entire technique "client continuation programming?" with it implicitly understood that creating the continuation involves a third piece of program? I'm prepared to die. I just want to know.
Now, the Web has matured into a fully-featured application platform, and fast JavaScript runtimes and HTML5 standards have enabled developers to create the rich apps that before were only possible on native platforms.
Eh, saying "matured into" implies that the current state is somehow better or more desirable than the previous state, and somewhat implies that this was the expected / desired goal state. I reject all of those implications. I posit that it would be more correct to say that "the Web has been mangled, bent, distorted, twisted and hacked into a fully-featured application platform..."
A Web browser should be good at browsing, trying to make it into an application runtime is a "separation of concerns" violation of the first magnitude. It might work, but let's not pretend there aren't other choices, or forget to continue researching alternative approaches to delivering applications over the Internet.
AirBnB's Rendr library is not a JavaScript, and only JavaScript solution. It is however a library that allows you to mostly unite your web rendering layers on the web client and application server.
Look at the first diagram in the article and you'll notice that the author shows 3 environments:
1. Client (obviously the browser is JS)
2. Application Server (the server-side rendering environment = what he says can now change to JS thanks to Rendr)
3. API Server (use whatever you want here - JS, Java, Ruby, Python...)
And, in production you will no doubt need a "static" server as well (for rendering privacy, tos, etc. pages). Plus all of the other production systems (like a queue, stream processing, and so on) that are not JavaScript environments.
So then you couldn't use a CDN to load your JS files, which might kill your performance gains. How does this change loading partials?
I disagree about the complexity. I've build Angular apps with a RESTful backend that couldn't be simpler. I also haven't noticed any performance issues. It's faster than traditional sites for me. SEO is a problem though.
121 comments
[ 0.17 ms ] story [ 160 ms ] threadAlso, you can't patent this now.
The phantomjs idea is a shit idea and should go away. Phantom is fine and good for headless testing (hells we use it for quite a bit else) but seriously it is not a solution for a real load.
Shit idea, lil harsh.
However, Yahoo already released a solution for shared Express/client state: https://github.com/yahoo/express-state
Using precisely defined mathematical words in contexts where they only make sense vaguely to a layperson ruins their original usage. Make up a new word. Repurpose a shitty English word. But leave our damn maths words alone.
Old man quarterto shakes his fist at you! Get off my smooth, compact lawn!
Polymorphic: many shaped. Monomorphic: single shaped. Isomorphic: same shaped.
According to M-W "isomorphic" has pre-existing definitions from medicine and chemistry that could align better with what OP is trying to say. http://www.merriam-webster.com/dictionary/isomorphic
Good day quarterto! I shall now leave to take a smooth ride in my compact car.
To clarify, if it was a true example of isomorphism it wouldn't be contingent on a single runtime environment or language.
A better example of isomorphism in computing would be two modules of code that perform the same function and have the same abstract interface but that are written in DIFFERENT languages.
isomorphic: modules that have the same abstract interface and functionality but that are written in different languages and executed in different runtimes
monomorphic: modules that have the same abstract interface and functionality and that are written in the same language and have the same runtime
heteromorphic: modules that have the same abstract interface and functionality and that are written in the same language but run in different runtimes
homomorphic: modules that have the same abstract interface and functionality but that are written in different langauges that run on the same runtime
See, the thing is... languages are compiled to runtimes, right? But they are transpiled to other languages...
There surface area of this discussion is very interesting and seems to have some interesting properties, and if you don't mind the math pun, it is truly a complex issue!
As for how to actually name these different things, I don't think I really mind... maybe isomorphic and monomorphic swap in the above definition... I've been reading some latin and greek roots to try and give them good names, but I'd love some suggestions!
For example, a function written in Scala that functions the same as a function written in JRuby and compiled to the JVM would be an example of a "homomorphism".
And a function written in JavaScript that is compiled to run in both node and the web browser is an example of "heteromorphism".
A function written in JavaScript that is compiled to run in the Ruby runtime is an example of "isomorphism".
Monomorphic would just be sort of like an identity property.
Also, I have no idea what I'm going on about, so please help me fix the language!
Maybe isomorphic IS the correct term for what is going on in the article, who knows? :)
According to http://en.wiktionary.org/wiki/isomorphism
one meaning is similar form. As in - server and client code have similar form.
Imagine a graph theory researcher calling a program which handles graphs a web app. Isn't that confusing?
And there's a (unsolved) conjecture that every NP-complete language are p-isomorphic: http://en.wikipedia.org/wiki/Berman%E2%80%93Hartmanis_conjec...
That link doesn't say that those definitions were "pre-existing". They say the first use was on 1862 but failed in specifying in which context was used first.
I was inspired to use "isomorphic" from a 2011 article by Nodejitsu [1]. It seemed like a fine way to describe this approach. I would gladly use a better would if I were to find one.
[1] http://blog.nodejitsu.com/scaling-isomorphic-javascript-code
Programmers these days!...
A few ideas:
"End-to-End JavaScript" - popular but not exactly what you mean but close
"Run Anywhere JavaScript"
"Write Once JavaScript"
"Two Sided JavaScript" - server-side and browser-side
"Browse-N-Serve Javascript"
longingly gazes into the distance
longingly gazes into the dead stars
http://mathworld.wolfram.com/Isomorphism.html
If there is an isomorphism here, it is between the separate runtimes (client and server), and not the language.
OTOH, this is talking about the same thing running in two different contexts. More appropriate terms might be uniform, homogeneous, ...
The fact that it's used in math is incidental. It's used in biology and chemistry as well. It does leave space for ambiguity because of closeness of math and computer science, but overall it's correct usage.
Frankly, Node is a way for front-end developers to write server-side code without having to learn too much new stuff.
Some people are side-stepping the issue by saying that the whole presentation layer must be moved to the front-end, but that approach is really incompatible with the web.
If anything, the current state of the front-end is thanks to server-side developers who want to bring their world view to the browser. (Think: MVC -> Backbone / Ruby -> Coffeescript -- apologies to the authors of those tools)
http://coffeescript.org/ http://elm-lang.org/
It may the same language, but the runtimes are completely different and have incredibly different use cases and environments. Not only that but I'd rather have a healthy ecosystem where the Unix runtime, .NET runtime, JVM runtime, and even interpretive runtimes that are built on top of those runtimes likes Ruby, Python and JavaScript are all considered equally!
That is closer in line to what the real definition of isomorphism is describing. :)
In my experience, including rendering code both server-side and client-side is overkill. Just put all the rendering and templating code client-side, period.
If you want your page to appear more quickly, then instead of loading content data with AJAX afterwards, just include JSON arrays of content directly within the HTML source itself, and use JavaScript to populate the page instantly, even as it loads.
(Obviously SEO is a different case, but there are tools built for that specifically.)
In my experience, server-side rendering has led to a much better UX.
It seems like CoffeeScript did this rather successfully, and with source maps, the debugging story is getting better too. Any reasons why this might not be a more compelling future than the "JS everywhere" vision?
It works by authoring all pages in HTML/CSS/WebComponents with basic MDV-style two-way databinding as separate stand-alone pages. These are then globally optimized together as a monolithic SPA application, and then code-split back into separate pieces. A servlet then processes the template on the server, does the data binding, and sends back a fully rendered bit of HTML + inlined JSON data within a single HTTP request. The JS code starts up and binds to the template and model, and then launches async loads of the rest of the compiled templates.
You get URL addressability, crawlability, fast initial page load, plus SPA-style fast switches, global aggressive optimization, offline, sharing of heap objects between pages, etc.
Initial hacked up draft of what I'm prototyping http://goo.gl/ZNpxTk
I've been feeling the burn myself—the desire to fully switch to handlebars templates in my Rails app. The expensive part would be building my API out more than I have, because I rely on associations in Rails view renders. However, gaining 1 template engine to rule front & back.
Instagram.com does something similar; it's a Django app.
To iterate a point in the article, a number of client-heavy sites built on Angular and Ember have been rendering their content on the server-side to be presented to crawlers like the Googlebot for SEO purposes.
It's returned in the request as HTML if the USER_AGENT matches Googlebot just like it would in a normally non-SPA web app.
If a crawler executes the web page without a full Javascript context it will miss out on the intended content.
That's old school way. Sometimes old ways are presented as new, which confuses me.
> then capture the outerHTML of an element as an HTML string to serve
That makes sense. Do the fancy building on the server and then convert it for transport
> React.js
That sounds interesting. You answered my question enough that I can do more research. Thanks.
I feel this tension is at the root of the CommonJS vs AMD discussions that have been taking place recently as well as issues related to npm, bower, and browserify.
Monomorphic code, while being very easily shared amongst different runtimes, still needs to aware of the mechanisms, strengths, and weaknesses of those runtimes!
Projects like browserify-cdn and sites built with on top of it like requirebin.org do a lot to bridge the gap but raise some interesting questions about wrappers like UMD.
I feel there is room for a better protocol for sharing code between the different environments.
I'm currently doing some research on the subject and plan on writing a spec and implementing some example interfaces.
BTW, projects like Bower head in the opposite direction and seem painfully unaware of their actual context...
I mean, installing a package manager to then install a package manager should raise some eyebrows, right?
This is a classic "impedance mismatch" like O/R mapping. At the end of the day, there may be no good, i.e. simple, solution. It is inherently difficult and messy.
GWT is/was a terrible amount of overhead baggage, but had some brilliant event systems and DOM tricks for its day.
And the Java server code compiles to JVM bytecode. Languages often compile to some other form to run, and the fact that the compilation target is different for different parts doesn't change that the programming language is the same.
http://vaadin.com
Vaadin is consistently rated one of the best web app frameworks. Why its not more widely known is beyond me.
GWT is very much alive and kicking, but it's primarily used on internal business applications with large and complex code bases. And what overhead baggage are you talking about? GWT is designed to reduce overhead though cross-compiled, browser-spesific builds, dead-code removal, and js-optimizing.
Also, you'll have to re-do the entire rendering on the client, then swap the server-generated DOM with the client-generated DOM. Its probably possible - but is it worth the effort?
http://www.meteor.com/blog/2013/11/06/david-greenspan-at-dev...
The cool thing is, other template languages (like Handlebars, Jade, etc.) can compile to this intermediate representation, which then gets rendered on any updates.
If the front-end community could agree on a protocol for how to represent these steps in, say, JSON, then we could be on our way to a world where you could use any rendering engine with any template library, on the client or the server.
That is, if the community could agree on a representation :)
Anyway, so problem currently is that client devices are slow and HTTP requests are expensive/slow. If these were not issues - I guess rendering on a client would be just fine?
If above is correct, I do not see good reason for smallish websites/apps/whateverucallit fallback on server rendering, as it looks like every single year mobile devices getting faster and faster. And we have SPDY on a way to mainstream.
Do I want to wait 3 seconds to get HTML or wait 100ms to get bootstrap code and see pieces rendering as data comes in? Probably doesn't matter, since it will take roughly same 3 seconds to render it on client side.
Ultimately, perceived responsiveness of webapp depends a lot on particular implementation. If you wait for all data required for page to render - yes, it will be slow. If you render pieces of page as data comes in - user sees that something going on and this is good enough. Why it should matter where data will be converted to presentation, on server or on a client? It is still waiting. And if client is not happy with it? Buy beefier hardware!
No server should take more than 100ms-500ms on a sufficiently cached page to process and to begin transferring, in non-edge cases. The only thing that could take that long is a shitty datacenter/vps, and as such, transfer speed/latency limits will encumber all types of requests.
In the end, you still have to transfer data from databases, so ignoring that, client-side template rendering seems like a non-issue to me. Surely it's never the latency issue unless you're serving at ~100+ requests per second, which translates to many millions of requests a day, and I don't believe 99% of websites are doing this.
Mostly Django user attempting to ask from outside the Node/server-side js community for an explanation of why we're invoking "isomorphic" here: As far as what's going on, are we just saying that the js for rendering the page is equally capable of talking to the API and doing the DOM work while running on the server as it is when downloaded, interpreted, JIT'd etc before fetching the actual request content? Does this mostly eliminate an extra RTT to the API if the js/web application server experience relatively zero RTT due to network/physical proximity to the API server? Does this incidentally make SEO possible while having fat clients and server-side initialization all in one setting and with mostly one code base?
Assuming I'm on track, working backwards towards understanding the implementation as it relates to "isomorphic", if a program's output state is a valid input state to initialize the program (we're talking fat, stateful MVC clients after all) state, then all that's needed to re-create the entire execution state of the current program is to copy itself into the output in such a way that it will be run upon receipt (we link js files in the page). I'm going to take a wild guess that the output state of the client doesn't have the necessary template tags etc used when a cold page is rendered, server or client-side, so the server has to serialize some of the state and pump it into the copy of the program to make it as if the client we're sending is the client that rendered the page, keeping the client's internal representation consistent with the state of the page.
If this is true, we're taking a program that cannot be initialized from it's own output and modifying it to be a program that achieves the same effect. JS is modifying JS, and is therefore said to be "isomorphic?" It still sounds like a glorified way to describe a serialized execution state, one that happens to involve a program in a language outputting a valid program in the same language, but the purpose is to achieve the effect, as far as the developer is concerned, that the output is a valid input, albeit with an intermediate technique to make the abstraction hold water.
If I'm on track, then I have to say it's rather as if we have a fat client, output of one render, serialized client state (because the DOM is not sufficient to re-create the program state or else our client js has to initialize from one format that's programmer friendly and one that's program-friendly), and necessarily a third-leg responsible for injecting the client js and serialized state as js into the output.
Standing to see the mauve dusk of my life against the impending rain of spears and arrows, I must ask if we can not simply call the js necessary to achieve the equivalent state of running everything client side a "continuation" and call the entire technique "client continuation programming?" with it implicitly understood that creating the continuation involves a third piece of program? I'm prepared to die. I just want to know.
Eh, saying "matured into" implies that the current state is somehow better or more desirable than the previous state, and somewhat implies that this was the expected / desired goal state. I reject all of those implications. I posit that it would be more correct to say that "the Web has been mangled, bent, distorted, twisted and hacked into a fully-featured application platform..."
A Web browser should be good at browsing, trying to make it into an application runtime is a "separation of concerns" violation of the first magnitude. It might work, but let's not pretend there aren't other choices, or forget to continue researching alternative approaches to delivering applications over the Internet.
Look at the first diagram in the article and you'll notice that the author shows 3 environments:
1. Client (obviously the browser is JS) 2. Application Server (the server-side rendering environment = what he says can now change to JS thanks to Rendr) 3. API Server (use whatever you want here - JS, Java, Ruby, Python...)
And, in production you will no doubt need a "static" server as well (for rendering privacy, tos, etc. pages). Plus all of the other production systems (like a queue, stream processing, and so on) that are not JavaScript environments.
If you check out his example code you'll see that he actually sets up example 04 (https://github.com/airbnb/rendr/blob/master/examples/04_entr...) with a subapp for a static page.
Also, if you look at the react-moment branch in the isomorphic tutorial repo (https://github.com/spikebrehm/isomorphic-tutorial/blob/react...) you'll see that he's proxying a dummy API server to a route on the application server.
I disagree about the complexity. I've build Angular apps with a RESTful backend that couldn't be simpler. I also haven't noticed any performance issues. It's faster than traditional sites for me. SEO is a problem though.