I may be misunderstanding this, but isomorphic SSR sounds an awful lot like the Java Server Faces concept of a server side DOM that is streamed to the client. JSF was largely dropped by java developers because it ended up scaling poorly, which makes sense since it violates one of the main constraints that Roy Fielding proposed for the webs REST-ful architecture: statelessness.
An alternative approach is to retain the statelessness of the first option they outline (I don't understand why it isn't "true" SSR): use normal, server-rendered HTML, but improve the experience by using htmx (which I made) so that you don't need to do a full page refresh.
This keeps things simple and stateless, so no server side replication of UI state, but improves the user experience. From what I understand of the isomorphic solution, it appears much simpler. And, since your server side doesn't need to be isomorphic, you can use whatever language you'd like to produce the HTML.
In the sample code, there is no "streaming" going on -- the server simply uses the client code as a template to generate HTML and sends it as a normal HTTP response. In pseudocode:
import "client.js" as client
on request:
document = new ServerDOM(),
client.render(document, data),
respond with document.toHtmlString()
> I don't understand why it isn't "true" SSR
This article seems to be using the term SSR exclusively in the frontend framework sense, where client code is run on the server. It's not how I use the term but it is a common usage.
Another possible reason that the htmx approach isn't discussed: the any-server-you-want nature of htmx is terrible for selling Deno Deploy :]
Ah, I thought there was some sort of diff-and-send going on to the client.
I do know there are folks using htmx and deno (we have a channel on our discord) so I don't want to come across as oppositional! Rather, I just want to say that "normal" SSR (just creating HTML) can also be used in a richer manner than the plain HTML example given.
I'm working on a server side framework and someone told me it reminded them of Java Server Faces. I think the approach works really well and latency is low enough when you can deploy apps all over the world. Also they didn't have HTTP2 or websockets back then... What I'm doing is basically a clone of Preact, but server side Ruby, streaming DOM-patches to the browser...
Slightly off topic, but I found JSF the most productive out of any framework. It has some not so nice edge cases, but when you are “in the green” and you don’t need to scale to infinity (which, let’s be honest, is the case most often than not) it really is insanely fast to develop with. For internal admin pages I would hardly use anything else.
> Slightly off topic, but I found JSF the most productive out of any framework.
In my experience, it has been a horrible technology (even when combined with PrimeFaces) for complex functionality.
When you have a page that has a bunch of tabs, which have tables with custom action buttons, row editing, row expansion, as well as composite components, modal dialogs with other tables inside of those, various dropdowns or autocomplete components and so on, it will break in new ways all the time.
Sometimes the wrong row will be selected, even if you give every element a unique ID, sometimes updating a single table row after AJAX will be nigh impossible, other times the back end methods will be called with the wrong parameters, sometimes your composite components will act in weird ways (such as using the button to close a modal dialog doing nothing).
When used on something simple, it's an okay choice, but enterprise codebases that have been developed for years (not even a decade) across multiple versions will rot faster than just having a RESTful API and some separate SPA (that can be thrown out and rewritten altogether, if need be).
Another option in the space is Vaadin which feels okay, but has its own problems: https://vaadin.com/
Of course, my experiences are subjective and my own.
>When you have a page that has a bunch of tabs, which have tables with custom action buttons, row editing, row expansion, as well as composite components, modal dialogs with other tables inside of those, various dropdowns or autocomplete components and so on, it will break in new ways all the time.
Everything you're describing sounds like someone was able to create requirements for features without push back or thinking.
I think part of the design process is thinking and really asking, why do we have an editable table in a row, and how useful and core to our business is this.
> Everything you're describing sounds like someone was able to create requirements for features without push back or thinking.
This might be it! However, the composability of solutions still matters, for example, while I dislike certain other aspects of React, its approach to nesting components is a breath of fresh air, especially with JSX (as long as state management is manageable).
> I think part of the design process is thinking and really asking, why do we have an editable table in a row, and how useful and core to our business is this.
I might have structured that sentence badly: the tables had editable rows (say, the ability to edit contents in a row, like Excel, but only when an edit button is pressed, as well as sometimes other action buttons are present; which may or may not get interesting when you are doing that on multiple rows and have validations against already entered data), which might sometimes open modal dialogs. For example, if you need to select some data which doesn't quite fit into an autocomplete text field, you might bring up a modal dialog for selecting what you need, maybe have a search form and so on.
Personally, I'd say that development would often be easier regardless of technology, if requirements could be aligned with the available technologies (as well what can be done well and easily within them) and not vice versa. Then again, the final say is up to the poeople who are giving you money, so there's that.
I did meet a few bugs (though they were from a few PrimeFaces components), and the js interop is not too trivial, but otherwise I can’t share your experience.
That's perfectly fine, it might just be that the project had certain challenges in regards to complexity, or that the codebase might have been a bit peculiar.
But I think that's why it's nice to provide even single data points to a discussion sometimes.
What exactly do you mean with violating statelessness? Most web apps have state on the server, i.e. cookie sessions. The UI state doesn't have to be state on the server though, that can still be in memory in JS and/or part of the URL.
An alternative approach is to retain the statelessness of the first option they outline (I don't understand why it isn't "true" SSR): use normal, server-rendered HTML, but improve the experience by using htmx (which I made) so that you don't need to do a full page refresh.
This keeps things simple and stateless, so no server side replication of UI state, but improves the user experience. From what I understand of the isomorphic solution, it appears much simpler. And, since your server side doesn't need to be isomorphic, you can use whatever language you'd like to produce the HTML.