Server-generated JavaScript responses
37signals.com
37signals.com
> If your web application is all high-fidelity UI, it’s completely legit to go this route all the way. You’re paying a high price to buy yourself something fancy. No sweat. But if your application is more like Basecamp or Github or the majority of applications on the web that are proud of their document-based roots, then you really should embrace SJR
and I realized that he's completely right, the majority of the web is still document oriented "pages". If that's your case, don't try to be an "app" and the 37signals way works just fine for you. in other words, it would not be a good idea to make a blog be a Single Page App (I'm looking at you blogger).That's if there's truly some benefit. Server-side rendering has its place, but probably isn't important for apps on the very "app" side of the content-app spectrum. What makes me want very easy to use server-side rendering, even for apps, is the fact that so many of those apps have embedded content - say an email in Gmail - that it'd be great to reuse the same templating if it's later deemed important to have a link to a static version of the content "outside" of the app.
If you're using node.js then you can even use the exact same template rendering code.
This means it might well be faster from an end-to-end perspective to send JavaScript+HTML than JSON with client-side templates, depending on the complexity of those templates and the computational power of the client. This is double so because the server-generated templates can often be cached and shared amongst many users (see Russian Doll caching).
On top of that, you can't update the UI in a meaningful way until you get a response from the server.
That's also not even touching any security considerations that you need to make to use this technique: you can't implement a CSP, you've got to make damn sure you're properly escaping every piece of data [in a special way] that comes through, and you've got to make sure the response that you're sending can't be used in a script tag (i.e.: you need to add an intentional syntax error that you strip off) or an attacker could simply put a script tag on his own site pointing at a URL on your site that returns sensitive information.
TL;DR: Badasses only.
The way this is set up, you must wait for an HTTP request to complete before any UI updates. I don't care how much caching you do, that will always be slower than immediate client-side update.
I really think the best way is to have both - send HTML to the client on page load, and get JSON for every subsequent request.
I worked with someone who helped develop AJAX interfaces before it even had the name, back when XMLHTTPRequest was brand-new, and they built a product similar to this in philosophy -- must have been around 2000.
I worked with a similar model as well on a couple apps, until finally migrating entirely to client-side rendering, and I would never go back. The complexity of server-side code having to write out client-side to update things just defeats you after a while, it's hard to keep a separation of concerns, and things start to turn into spaghetti despite your best intentions. Refactoring becomes increasingly difficult.
But most of all, it's just like you say -- you can't do error handling, or change the interface before you receive a response from the server, or deal with simultaneous requests, or probably 20 other things.
I'm honestly really surprised to see someone recommending this today. Dealing with all these huge numbers of stand-alone snippets which update certain parts of pages in certain conditions, is just an organizational nightmare.
As was shown with Google+ widgets for performance optimization, I.G.'s talks on High Performance Websites and chatter from Polymer-using folks, deliver your first page, your template, using HTML. Pre-render things, but then make it interactive on-focus (if widget), or load your JS and continue loading data (mobile) or take your HTML and use it as starting point for a really nice template and loading framework for widgets (Polymer).
The point then is that JSON is rather useless. It's not optimized binary for machine consumption, neither is it display-optimized DOM, in which styles and content can mix and interact.
Oh and failure states are entirely possible to show. If you want a dumb failure state, code that for use when you introduce the loading spinner as a timeout helper. For more advanced failures, write the logic client-side as you would normally, then deliver and modify the HTML again as you would normally.
No one says that because your primary communication mechanism for server updates is HTML that you can't in turn use JS on the HTML to provide updates between updates, as it were.
Even wikipedia would work great as a client-side app with json, bu then you want to open 30 tabs and you can feel it lagging.
project: https://github.com/chrismccord/sync
As for the criticism of SPAs that you need to download the "entire" JavaScript library is loaded, this can be mitigated by lazy loading the dynamic bits. If you look at how Google+ behaves, it renders the page server side, and then loads controllers for various parts of the app on demand. For such a complex app it loads incredibly fast.
It might be a little bit before there's a server-side renderer for custom elements / Shadow DOM / template binding, plus patterns for deferred loading code, but personally I think that will be the way to go in the near future.
lazy loading the dynamic bits
Are you talking about RequireJS AMD?There won't be. These guys are just desperately clinging the past. They should be writing the Ruby on Rails for Opal instead of trying to extend the life of something that, frankly, has seen its day.
Care to expand? I'm confused what you mean.
With regards to Twitter's Time To First Tweet being slow under their Single Page App, I recall Alex Maccaw mentioning that their JavaScript library execution was inefficient, in that the client had to download a whole bunch of JavaScript before it would load the part of the app responsible for rendering the data.
I believe he was suggesting that if Twitter optimised the delivery so that parts of Twitter's JS were served after the rendering part of Twitter's JS code, then the time to first tweet could be faster.
In my opinion, delegating template compilation to the client offers a nice separation of concerns; the server is the API, and the client is the UI.
It would be interesting if there was benchmarking done into comparing these approaches, to see where server-side template compilation can be beneficial over client-side template compilation.
It is also what is recommended for Backbone, for example:
Doing it serverside with russian-doll caching means that each template only gets rendered once for a given set of inputs and (at least for most CRUD apps I've ever built) you have huge cache hit rates, so it'd mostly be people pulling static HTML out of memcache all day. Crazy fast.
Why couldn't you just memcache the json response for a given set on inputs?
Template rendering is never, ever the slow bit in a CRUD app. Ever. At its core it's simple string concatenation. Getting the data, the SQL, is almost always the slow bit unless you're doing some serious computation or file jiggery, which is still not template rendering.
And that's on a small VPS.
But even going to Basecamp, the entire time waiting in chrome (which is basically the entire server-side run time + a few ms) is between 150-200ms and that's on what I assume is a fairly busy server.
So I suspect you're doing something wrong.
The numbers in my comment are "without caching". Comparing them to Basecamp, which caches views and fragments heavily, is apples to oranges. Once I add caching, my typical response times for a cache hit are in the 10s of milliseconds.
You made an Amdahl's law argument that view caching is fruitless because rendering is an insignificant part of total response time. So I responded with uncached performance to show why Rails needs view caching.
It's no accident that Rails has comprehensive caching support; that the Rails team has worked hard to refine and optimize caching in each release; and that DHH writes about it so often (including in this article). You can't have performant Rails without view caching because rendering is dog slow.
So, someone using java or c# could very well say view render times don't matter, because for them that is true and their bottleneck is indeed the database.
https://groups.google.com/d/msg/rubyonrails-core/rwzM8MKJbKU...
I was under the impression that trying to validate that was ultimately as fragile as checking the user-agent string...
See http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypas...
Why, for example, would you use this over client-side templating and data-binding? Create the template once, grab some data with AJAX, bind it to the template...
This way, the rendering is done server side so the initial html comes with the first request, and ajax updates are still generated using the same server side code path, just sent back inside of some javascript.
Something about sending Javascript from the server seems like mixing up the application layers and creating dependencies that shouldn't' be there. I can see it perhaps if the code that you "own" is 100% on the server. Maybe I'm old school and it's just something that will have to sink in a bit before it makes sense to me.
I'm happy they continue to support methods like this though because I REALLY enjoy being able to put up a site that works perfect without javascript, gets crawled by everything and has a fantastic user experience for people with JS without having to worry about duplicating "MVC logic" on both sides, messing around with having to render something in 2 different template languages or add a lot of extra boilerplate.
Everything just works and is lightning fast.
I still don't get the benefit over using RJS (or SJR, or JSR, whatever) instead of render :json : with the former you have the javascript spreaded in your views, with the latter you can organize it inside the assets, which IMHO is a way better solution.
Some benefits I see are:
1. It just works perfectly with and without javascript which means your stuff gets crawled by search engines and it works great for people without JS. Then if you have JS enabled you get the enhanced UI.
In #1's case I do this all the time for search boxes. In admin dashboards that I make with rails I allow people to search for data.
It's trivial with rjs to implement a solution that works with no javascript and then if you have JS enabled you get your search results shown immediately without a full page reload.
2. You can tell the rjs code to use server side (erb) partials that you already have created so you don't need to have templates made for both.
Or in #2's case if you just use jquery without using any template engine it gets super messy trying to append elements to another element with inline html strings. All of that is eliminated by using your existing erb partials.
1. It doesn't depend from RJS/render :json, but from the fact that your controller responds to sync requests, in addition to the async ones.
2. You can tell to render :json to use server side (erb) partials:
render json: { html: render_to_string(partial: 'product') }
I do it all the timeDoes it still need to compute the output of the partial's string representation on every request?
http://synrc.com/framework/web/
It can do server side rendering but then pushes it via a websocket (well with fallback) to the client.
The use case I understand is mobile clients.
Of course, as JS on the server becomes more and more wide-spread, you might as well just use the same templates at both ends, but it' still more infrastructure than treating the client JS as just part of the view.
I discussed this back in 2011 on my blog: http://pilif.github.io/2011/04/ajax-architecture-frameworks-...
I'm personally not against SJR and I haven't really gone whole-hog into any JS framework (Angular/Ember/Backbone) ... but almost every RoR developer I've talked to is disabling Turbolinks on all their Rails 4 apps. I personally find it slow to load/render in dev mode, which leads me to believe it would be confusing for users in production.
Is anyone using/liking Turbolinks for Rails 4 apps?
Usually people: Click link
White screen / loading (computer is doing something)
Next page progressively shows up
Turbolinks is different
Click link
Nothing is happening...?
Next page appears all of a sudden
I actually liked turbolinks, makes the page feel much quicker, but just too many quirks to work around and I didn't really have time to dive into them.
It does a great job of eliminating the majority of page load times for apps with large amounts of CSS and JS. It definitely requires stricter control of Javascript, but what it enforces is an existing good practice (idempotent scripts) so it's hard to be annoyed.
I've also added a loading indicator in some places where I'm using it on a more "app-like" site.
In my brief thinking about this, one potential version would use HTML 5 attributes like AngularJS, but use HTTP/restful endpoints as "the model". I can imagine a few different approaches, but something like:
<div data-dyna-src="http://myserver/my-div-endpoint" data-dyna-method="poll 500ms"> ... </div>
Which would then poll the given endpoint and swap in new content in a pluggable-but-visually-pleasing manner. http://myserver/my-div-endpoint would serve up the partial of the div, so everything would be DRY. Basically move the model back to the server, but still buff up the presentation layer a bit.
You'd probably need a few different patterns: updateable divs, forms, updatable tables, progress bars, as well as some good default transitions and, of course, make the whole thing pluggable, and potentially provide for both HTML and script interchange at the end point (that's what our ad-hoc version does: it provides a data channel, an html channel and a raw script channel, but it feels like a hack.)
Anyway, if anything is going to save us from the oncoming javascript-filled dystopian hellscape, it's probably something like this.
Anyway this is clever from a traditional web development perspective but not from a contemporary one. I like to use AngularJS (with prerender.io when necessary for server side rendering). I write all the non HTML code for both the front and back end in ToffeeScript which is derived from CoffeeScript.
Web development is evolving, as it ever has, and I believe that the next step is pushing the view layer to the client, and caching data, not html, on every step of the way. The major hurdle here is SEO, but I hope that when the right framework comes, it will offer an elegant solution to this problem.
[0] http://37signals.com/svn/posts/3112-how-basecamp-next-got-to...
domain.com/posts.json
domain.com/posts/1.json
etc.
$('#messages').prepend('<%=j render @message %>')
.find('.delete').click(fn)
.end().find('.reorder').hover(fn,fn)
I suppose they work around this problem with event delegation.If you use something like angular, the whole mess becomes:
$scope.messages.unshift(message);https://github.com/xpdr/transponder
http://kontax.herokuapp.com/ - example app running on heroku
http://github.com/xpdr/kontax - example app on github
Most devs are still used to the Thin Client approach, so there is a productivity benefit to remain where you are familiar.
However, you can have just as many or more productivity enhancing libraries and practices in client side javascript as in the server side rails-like frameworks.
Looks like all this is really just a way to compensate for google lack of advanced technology on the crawling side ( i just loved that last sentence :))
2. Server creates or updates a model object. 3. Server generates a JavaScript response that includes the updated HTML template for the model.
Why does a template need to be updated? Isn't that part of the idea of templates, that they are fixed for changes in the model?
Yeah, cuz like no-one is doing that anymore. /s