22 ms·
The future of web software is HTML over WebSockets
- frompdx 6y agoThis seams really optimistic and kind of glosses over the subject of scaling out websocket connections apart from this. Anecdotally, the typical single Rails server process seems to be perfectly happy supporting nearly 4,000 active connections. And you can easily swap in the excellent AnyCable to bump that up to around 10,000+ connections per node by not relying on the built-in Ruby WebSocket server. That's not a lot of connections on it's own. If you are implementing a chat service you'll still need some form of pub/sub (or something) to glue all of that together when users connect to disparate nodes. Also How about client-side validations? Easy. On every input change, round up the form values and send ’em down the WebSocket. That's just server side validation. As a disclaimer, I haven't used any of the HTML over WS frameworks the author discusses, but I've spent a fair amount of time dealing with scaling socket connections. It definitely makes the question of scaling horizontally more challenging. I feel like this article really glosses over that aspect.
- mplewis 6y agoSure, it's server-side validation – which is great, and works well. And now it works without a full page submit and reload. That's a huge benefit.
- the-dude 6y agoWhich you can do already for over a decade with AJAX.
- sago 6y agoYup. And DHTML over a Java applet before XMLHttpRequest. 1999 at least, iirc.
- brod 6y agoEver since xmlhttprequest (and even before that with images) we've been able to do server-side validation without a full page reload. This "solution" completely ignores the purpose of client-side validation which is to a) reduce load on server-side resources, b) validate faster without the network latency and c) validate more securely and privately by not sending the content to the server.
- skullum 6y agoPhoenix live view (anything on BEAM really) maps each ws to a BEAM process so scaling to 10000+ connections is both cheap and built-in
- nickjj 6y agoBut LV is still in its infancy and there are very real implications of using websockets that are unrelated to open connections. Just the other day someone posted on the Elixir forums about live_redirect causing 2 network round trip connections[0]. Basically there was double the latency to transition between pages due to this "bug". I air quoted "bug" because it's working as intended, it's just not optimal. The creator of Elixir mentioned it was doable to fix the issue but when an issue was open on GitHub[1] it was shot down with a "this is a known tradeoff, you'll need the 2nd route trip for the websocket". I'm not sure what the state of the issue is but it currently stands as closed. I've pinged 80ms to servers where LV was being used and the delay was extremely noticeable (before I even knew about this double network round trip issue). It feels much worse than a Turbo Drive / Turbolinks driven site (which uses HTTP instead of websockets like LV does). In some cases LV feels slower than a regular site even with the DOM having to re-parse all of your assets. The only time LV feels like a net win to me is when you're on a local connection with 1ms of latency. I wanted to use LV a lot, but backed out because I kept running into bugs and missing features. Plus after feeling a LV site on a non-local connection I can't say that I would want to impose that experience on users. Especially folks who happen to connect from let's say Europe to the US, or even further away. The web is a global place. [0]: https://elixirforum.com/t/shortcomings-in-liveview-are-there-any-i-should-look-out-for/31831/47 https://elixirforum.com/t/shortcomings-in-liveview-are-there... [1]: https://github.com/phoenixframework/phoenix_live_view/issues/1334 https://github.com/phoenixframework/phoenix_live_view/issues...
- benzible 6y agoWhen did you last use it? Javascript hook support wasn't there early on. The state of the art is the "PETAL StacK" [1] which uses client-side JS for interactions that don't require a roundtrip [1] https://thinkingelixir.com/petal-stack-in-elixir/ https://thinkingelixir.com/petal-stack-in-elixir/
- ksec 6y agoIt is also important to note the latency in these connection. Generally speaking 4000 Active connection you are looking at 150ms+ for 98th percentile already. Which is bad to be frankly honest. ( Results were from 2016, so may be things has improved )
- burlesona 6y agoFWIW the article should have led with Phoenix LiveView, which really pioneered this approach, and is much better suited via its concurrency model for large scale streaming apps (like chat apps). Where Rails with “live view” tooling would work really well is building CRUD heavy sass apps that don’t need a persistent connection, just want really fast page refreshes and/or partial updates. The work the basecamp team did on Hey seems to be a good illustration of that.
- symlinkk 6y agoGood lord what a long winded article. Just get to the point.
- An0mammall 6y agoI just read the headline, that's enough for me...
- NanoWar 6y agoHow does it compare to let's say Blazor?
- jordanab 6y agoBlazor comes in two flavors: Blazor via WebAssembly and Blazor server-side over websockets/SignalR. The contents of this story directly relate to the latter one.
- Spivak 6y agoNice to see that we’re back to thin clients again but I don’t think it addresses why SPAs backed by JSON APIs caught on which is that you got dead simple cross-platform development when every UI was just a porcelain over your backend. The missing piece here is that you still need those platform-agnostic APIs and an absolutely clean separation of your backend with all the business logic and your presentation layer. But now your presentation layer mostly lives on your servers and is doing SSR and pushing data over websockets. It takes real discipline to not commingle the two because you’re right there you could just peak at the database a little smack. The other hard thing about this approach is that now your frontend presentation servers have to keep their own state since they are the clients now which means they need shared storage of some fashion and likely even shared persistent storage if you really want to take advantage.
- dynamite-ready 6y agoI agree. Also, server compute is expensive, while client side resources are relatively abundant, and designed for graphics processing... Unless your program absolutely requires server side rendering, then technically, it might be cheaper not to do it. Especially when sending messages over websockets.
- aeoleonn 6y agoAnother "The future of <thing> is what <some person> says it is" without much more than a few paragraphs of explanation. No diagrams. I don't see much of a comparison between costs/benefits of alternatives. Nice hypothetical. I didn't read it, because I've seen the format before and I'm getting a bit bored of it. Whereas if it cited some other engineers/technologists, some studies, some academics, etc., then perhaps I'd be more inclined to read this. But one person's opinion? Nah. I need an aggregate of opinions to be persuaded to read another "The future of thing..." article.
- hinkley 6y agoThe guy I learned about 'mis en place' from had coined a term, "retro-grouch" for people who loudly insist on a nostalgia for old technology. When the Trough of Disillusionment hits, us old farts pop out of the woodwork to say "see, told you so" whether we were right or wrong.
- burnished 6y agoDid you learn mis en place in a kitchen, or does it have a meaning in technology circles that I'm unaware of?
- blacksmith_tb 6y agoI work in an org where it is used to refer to the prep for a release, but with sort of a wink and a nod.
- hinkley 6y agoTurns out if you do skilled manual labor, the concepts translates. Bob was a bike mechanic. I don't know if he used the words, but he kept harping on us for not having our shit or tools together for a task ahead of time. When you're covered in grease is not a time to be digging for a wrench.
- sitkack 6y agohttps://en.wikipedia.org/wiki/Mise_en_place https://en.wikipedia.org/wiki/Mise_en_place I think it also relates to operational professionalism and having your tools and toolbox in order ala Adam Savage and Jamie Hyneman from Mythbusters. They both had very interesting relationships with order, process and tooling. I think structuring dev teams around a professional kitchen is really powerful model. All roles are critical, the sous chef, the busser, the prep cook, the dishwasher, everything.
- hinkley 6y agoI miss having beers with people. This whole saga feels like one of those things where "I've heard this story before, I think I'll sit this one out and hope it's not too long" situations. We all prioritize what tech we're going to spend our time on, but I think there's something qualitatively different between, "that could be interesting but I don't care", "That'll never work!", and, "I understand this enough to know it does not meet my criteria for job satisfaction, I'm out. Call me when the Trough of Disillusionment hits." So we come back around to Rails, 15 years on from its launch… I think turbolinks hit too close to the AngularJS launch, and got swamped. People who were trying to make everything happen with jQuery skipped straight to Angular. Now Elixir is trying to resurrect turbolinks-plus in Phoenix.
- aphextron 6y agoI know people loved turbolinks, but the very thought of it gives me nightmares. That kind of tight coupling between server side and client is everything the modern JS ecosystem evolved to get away from. I can see it being useful in a single developer full stack environment to get something up and running. But any kind of long term complicated application development in that paradigm just sounds painful.
- nickjj 6y ago> I know people loved turbolinks, but the very thought of it gives me nightmares. Is it really that bad? With Turbolinks 5 (and its successor Hotwire Turbo Drive) you can do nothing except add 1 line of JS to your application and reap massive wins in terms of page transition speeds. And this all works without changing 1 line of code on the back-end and it works with all tech stacks. IMO it's the biggest bang for your buck that you can do to make a website feel good with the least amount of effort. And now with Turbo Drive you can do the same with form submissions without needing any back-end code and it also works with every tech stack with no special libraries or work to be done server side. Then Turbo Frames builds upon that to partially update a segment of your page and Turbo Streams introduces websockets for when you want to broadcast stuff or do real-time updates. It's a great system. Use HTTP for everything except for when websockets makes sense.
- 6y ago
- treve 6y agoWe are heavy into REST and HATEOAS. This, coupled with React SPAs has worked really well for us. The HATEOAS client we use/build has an cache/event system that will emit to subscribers (via react hooks) when a resource is stale, and needs to be refreshed. After putting this all in place, I realized that now I just need the server to emit those 'stale' events via Websockets, and suddenly my SPA + API is a real-time multi user system with nearly no changes required in either server or client. This made me wonder, why aren't we just always pushing the entire resource state over websockets. Use websockets to let clients indicate which resources they are interested in, and let the server keep pushing state back to the client. This solves a number of problems that plain HTTP has: 1. We can't really push/subscribe well. It's not very natural. 2. The HTTP cache kinda sucks, because we don't have programmatic access. Simple example: Doing a DELETE on a resource should expire the cache of the parent collection. There's a good HTTP header to indicate this, but no good way to tell the browser cache to delete the cache entry, so we end up building our own caching layer. 3. Compound requests suck because HTTP caches and clients don't understand them. But we can still keep using REST fundamentals. Things have URIs, features are discoverable, relationships are expressed with links. Something about this also feels terribly wrong though. Do we really want to reinvent parts of HTTP over websockets? HTTP is highly optimized, what kind of performance problems are we gonna run into?
- Tenal 6y agoComing from a game networking side, why wouldn't you want to embrace a WebSockets world for everything? The upsides seem so incredibly intuitive for someone looking at it from the outside of traditional web development.
- afavour 6y agoScaling is almost always the answer.
- mathgladiator 6y agoScaling not just technically either, it's also the engineers. Most Web engineers have had their minds bent to the request response model with databases. The key reason is that a game lasts... minutes to hours (ignoring most MMOs), so the state machine makes sense and the risk of failure low. Web devs have to use a database which has state for years.
- hg35h4 6y agoEverything about this sounds terrible for mobile, lossy or even medium latency connections. Non-blocking background updates are unnoticeable, but imagine your website being jammed like a stuck video every time you click or scroll? He describes a "please wait buffering" future of web software. No thanks.
- dahdum 6y agoThat was my first thought too, the word "latency" isn't even mentioned in the article.
- antihero 6y agoAlso: > Do we really believe that every one of our users is going to have a device capable of digesting 100 kB of JSON and rendering a complicated HTML table faster than a server-side app could on even a mid-grade server? Yes. This really isn't hard. Pretty much any smartphone can do this with blissful ease. And it scales horizontally because your server can just worry about getting stuff from the database and handing it out.
- notjustanymike 6y agoExactly. Our app renders highly detailed 3D anatomy on the canvas. The largest model is a 1mb json file with 57mb(!!!) Of assets. We've never had a problem with mobile devices, they're shockingly capable.
- ehayes 6y agoTurbo[links], Stimulus, etc. ARE non-blocking background updates. It's HTML over the wire instead of JSON. [1] I don't think this is what you think it is. [1] https://hotwire.dev/ https://hotwire.dev/
- fayten 6y agoAs an alternative that still relies on REST instead of web sockets is intercooler.js. It's a nice little framework for annotating html to give it more power. This little library seemed to have some buzz at the time it was first released, but I haven't seen it brought up in years. I decided to look it up and Intercooler is still supported, but there is a successor now called htmx. I have not shipped anything with either, but I think they are both technologies worth taking a look at. It also looks like htmx is working on support for SSE and websockets. https://intercoolerjs.org https://intercoolerjs.org https://htmx.org https://htmx.org
- qbasic_forever 6y agohtmx is great, it's come up a few times on HN and has good commentary. There's a small set of web folks that look at all the ridiculous complexities of react, virtual DOM, etc. and nope right out back to good old server side rendering. htmx is perfect for primarily server rendered stuff. And ironically, now we see react going full circle back to investigate a server side approach with their recent react server component experiments.
- fayten 6y agoI fooled around with a Spark java, j2html, and Bulma css web app for a prototype back in 2017 (2018?) and it killed me how nice it was. The only tooling I needed was Intellij and the app started in milliseconds along with supporting hot reloading. Modern web development is a big reason, I left my job at the end of 2019 and went back to school. I'm tempted to try something with Javalin(a fork of Spark), j2html + htmx, and Tachyons css now. I think together those would make a beautiful stack. http://sparkjava.com http://sparkjava.com https://javalin.io https://javalin.io https://j2html.com https://j2html.com https://tachyons.io https://tachyons.io
- qbasic_forever 6y agoYep, and if you squint serverless stuff like AWS Lambda, knative, etc. is basically a slicker more modern take on plain old CGI scripts. I don't view that as a bad thing--the less friction there is between "here's a function/code block.. please run it on this web request" the better.
- mathgladiator 6y agoI have thoughts, and I agree but also disagree a bit. We are in the dark-ages with respect to streaming sockets, and I am the architect of one of the worlds largest WebSocket and streaming services. First off, unseating the operational benefits provided by request response is a huge challenge. It's possible, and I've done it. One of these days, my co-authors and I will present an OSDI paper with the broad strokes. It's very easy to list a lot of the challenges with scaling WebSocket, but each of them can be solved. I believe we will have a nicer world with QUIC --> Http/3 and the up and coming WebTransport discussion. SADLY, that will result in a decade long "caniuse" issue, so we should expect to see WebTransport polyfills to arrive... Second, HTML over WebSockets is nice, but what is better is reactive data binding over the socket. Let the browser maintain a DOM tree that templates over a JSON object, then reactive-ly update and it's an amazing experience. You have minimal data transfer, and minimal rendering updates. There is a great deal of power in having your UI be a stateless function over a giant JSON object. Finally, the big challenge is dealing with the server state in a meaningful way. The exceptionally nice property of using request response for everything is the shared-nothing stateless nature of the web server. It's exceptionally forgiving in both operational and developer issues. It's very easy to fuck up the implicit state tied to the connection, and this requires discipline to get right. It's very easy to ship unreliable software that then has issues based on the connection. Now, I'm a HUGE believer in that we need to use streams for everything, but it requires a mind shift. The key thing to tackle is dealing with the server side state, and this is where I have my shitty idea of a programming language for board games. In essence, I am building a DIY database such that people connect directly to the database and get that sweet giant JSON object along with a stream of updates. The DIY part is related to the fact that I invented a programming language to transact on the JSON object such that you get all the benefits of durability with the mental model of working within a single machine. http://www.adama-lang.org/ http://www.adama-lang.org/
- rraihansaputra 6y ago> Second, HTML over WebSockets is nice, but what is better is reactive data binding over the socket. Let the browser maintain a DOM tree that templates over a JSON object, then reactive-ly update and it's an amazing experience. You have minimal data transfer, and minimal rendering updates. There is a great deal of power in having your UI be a stateless function over a giant JSON object. I think a lot of the "best-practices" for SPA is trying to do this. But as streaming the data transfer is not yet common, the data is abstracted as a giant JSON object to be a parameter of the UI as a stateless function (React+Redux/MobX/etc, Vue+VueX). When enforced correctly on the project level, what's complicated _is_ syncing the data to the server. I think you'll like Supabase's subscription approach to reactively bind the JSON for the client. I think a separation between the info-web (document-content heavy) and the app-web (needing stateful data sync) will be more clearly defined in the next few years. Nobody likes trying to sync data between the client and server over HTTP calls; we just have to wait for streaming to be the norm for the app-web (and native apps, ofcourse).
- CyberRabbi 6y agoIm skeptical of all the benefits of the approach promoted here. * not everyone has “two codebases” many people have one codebase and two different application distributions, one for server and one for client. * you will still have “two codebases” you have just removed the rendering logic from you client codebase. * What is the distribution of latencies of rendering json into html on the client? Are there numbers to suggest this takes more than 100ms for many people? If not the proposed efficiency advantages are being overstated. If the article were suggesting removing client side logic completely these arguments would be stronger.
- vfclists 6y agoMore snake oil from the Internet industry as usual. It is almost 30 years since the web came into existence and somehow people harbour this illusion that those who control the standards or are responsible for implementing them are genuinely committed to delivering technology which will help the competition (ie the rest of the world) bypasses their app stores. It makes one wonder whether those who keep blabbing on about these wonderful new technologies are shills or just stupid. Do they believe that a company that patented round corners and tie batteries to a particular phone to prevent it from working on another of the same make to be committed to technologies that bypasses their app stores? Do they think companies which ban apps from their stores as a consequence of their political partisanship will create an easy and effective bypass for them? I see someone mention Blazor below? Why not Silverlight? Oh it is proprietary. Well there are only two players in the browser market now, Apple and Google, and somehow between the two of them they can't come up with an NPAPI replacement although one of them makes the other happy to the tune of $12bn a year. It is 10 years since these companies conspired to deprecate Flash on the grounds that it was buggy and performance was poor. 10 years on phones and computers are an order of magnitude more powerful, yet through some mysterious means the replacement technologies are still buggy, underperformant, need more refinement yada yada yada. Why do otherwise intelligent people continue to put with this fraud, or is more a matter of Stockholm Syndrome?
- mathgladiator 6y agoThey are neither shills nor explicitly stupid, just inexperienced (mostly young people) with a great deal of enthusiasm and energy.
- vfclists 6y agoJohn Gruber has been around too long for like this to appear on his blog, but then he is not the writer of this article and probably doesn't much exercise much of an editorial influence.
- deleted 6y ago[deleted]
- qbasic_forever 6y agoMake it HTML over WebRTC data channels and then we're talking about something special--totally P2P decentralized web browsing. Beaker Browser is working on stuff like this: https://beakerbrowser.com/ https://beakerbrowser.com/
- ampdepolymerase 6y agoDoes anyone still use ASP.NET Web Forms?
- appveyor 6y agoOh, ASP.NET Web Forms were awesome! I remember it was so easy to onboard new developers: built-in state management between requests, WYSIWYG editor, high-level controls abstracting from HTML. Maybe because I miss ASP.NET so much :) I started working on https://github.com/pglet/pglet https://github.com/pglet/pglet to have something like "ASP.NET on steroids" - server-side controls with React UI. However, it's not a HTML passing over WebSockets, but controls state which takes much less traffic with smaller latencies.
- MentallyRetired 6y ago`The dual approach of marrying a Single Page App with an API service has left many dev teams mired in endless JSON wrangling and state discrepancy bugs across two layers. ` Umm... not it hasn't? Separating the backend from the frontend allows for multiple frontends on multiple types of delivery. Outside of edge workers, how is HTML-over-websockets supposed to compete with a good ol CDN (jamstack) on TTR?
- exabrial 6y agoI have a brilliant idea, why not HTML over plain sockets?
- sitkack 6y agoTo a local server running in a Wasm env? Yes please! And by local, I mean running in the same page.
- anderspitman 6y agoI used to love WebSockets a lot more. At some point I got deeper into implementing HTTP servers and proxies, and realized how much of a special case WebSockets are to implement. They're cool, but I prefer Server-Sent Events on HTTP/2 whenever I can get away with it, which is pretty much always (binary data being a big exception, and even then I consider long-polling first). I think there's value in keeping our protocols as simple as possible to accomplish the task at hand.
- yingw787 6y agoI've used HTTP/2 SSE for TinyDev (docs.tinydevcrm.com) and I've encountered the need for a reverse proxy and the unidirectional dataflow to be kinda eh, even if it is great in theory. I haven't played around too much with WebSockets though, but IMHO money + traction carries a good deal of weight.
- tschellenbach 6y agoIsn't HTTP/2 SSE being deprecated?
- anderspitman 6y agoI sure hope not. Are you thinking of HTTP/2 server push?
- iomcr 6y agohttps://stackoverflow.com/questions/28582935/does-http-2-make-websockets-obsolete https://stackoverflow.com/questions/28582935/does-http-2-mak...
- jamescun 6y agoI've seen nothing to suggest SSE would be (or is even capable of being) deprecated on HTTP/2. You may be confusing it with HTTP/2 Push, where a server can inform a client of a future resource it will need, which is _de facto_ dead, with only a few real implementations beyond the bare minimum required by the HTTP/2 specification.
- qbasic_forever 6y agoI do have to laugh a bit at people being very quick to dismiss this idea when HTTP/2 is effectively the same idea--one long-lived bi-directional 'socket' to multiplex all requests. It adds a lot more niceties like the server proactively pushing assets on first load. Many folks might even be using it right now without really realizing or knowing it.
- DonnyV 6y agoThe problem a lot of developers have with SPA is that they literally shove the entire app into 1 page load. Which is where most of their problems come from. If you use a hybrid approach. Have the data you need to show the page right away cached in the html and then load any other data after while that page is being used. And you break the app up into multiple pages. It works perfectly fine. It actually makes it super easy to hand out work to a team of devs and minimizes stepping on each other.
- imbnwa 6y agoIsn't this how Amazon.com gets developed?
- keithwhor 6y agoI’m gonna be “that jerk on HN,” but this is that idea that just keeps getting rehashed every couple of years then fizzles out. The reason that it’s so attractive is because as developers we love to build and save time, and we think, “imagine what we could do if we didn’t have to ask for data from remote servers...” The problem is that stateful connections suck and create artificial complexity when you don’t need them. Instead of managing the state of your app you’re now managing the state of your app and a connection to a remote server. HTTP is a stateless protocol on top of a stateful socket connection. It wasn’t designed this way by accident. I’m all for new engineers building SPAs creating exciting new libraries, but HTML-over-websocket has been rehashed at least three times over my professional career so far and it’s not even that long. Don’t get me wrong — websockets have their use cases. Multiplayer online experiences pretty much require them. It’s just that HTTP isn’t fundamentally broken, and by engineering HTML over websockets you’ll almost universally find yourself building protocols to abstract the state away... re-engineering HTTP in the process. It’s certainly a fun project which I have personally worked on. But I’m not sure it has legs outside of that. Open to being proven wrong, the authors of HTTP aren’t infallible.
- keithwhor 6y agoAs a thought exercise; - What happens if the client’s internet connection temporarily drops? How do you handle client reconnections and retries? - What if the remote server crashes through no fault of your own (AWS server rack catches fire)? How do you ensure a consistent reconnection that preserves application state? These are just two questions that HTTP + Browsers solved decades ago. Websockets are this cool technology that seems powerful and exciting until you realize the “boring old stateless World Wide Web” was built over decades of iteration using stateful sockets as the backbone, did most of the work for you in tandem with browsers, and is ultimately a lot cooler and more sophisticated than a lot of us give it credit for.
- cogman10 6y agoHere's another one. How do you deploy a new version of your service? Imagine a few customers open up your site and leave for lunch. Or maybe just a random crawler or bot sitting watching for some piece of information they are scraping. These sorts of issues can be challenging with stateless connections. I can only imagine how daunting they are with persistent connections.
- carapace 6y agoThis is just crazy. > Want a hyper-responsive datalist typeahead that is perfectly synced with the database? On every keystroke, send a query down the WebSocket and get back precisely the changed set of option tags, nothing more, nothing less. > How about client-side validations? Easy. On every input change, round up the form values and send ’em down the WebSocket. Let your server framework validate and send back changes to the HTML of the form, including any errors that need to be rendered. No need for JSON or complicated error objects. If you're not Google-scale this is just a good way to DDOS yourself, no?
- nom 6y agoI gave the author the benefit of the doubt until I read this part. A request on every input change? Browser-side validation exists for a reason. Even at Google scale this leads to embarrassingly bad UX.
- erinan 6y agoThe answer as often is... "it depends". Should you run an unindexed query on every keystroke of a text input of a form for every user? No. But if you're not a junior dev, you'll know not to do those things and you'll know to debounce the text inputs, plus maybe only query the DB is the input text is longer than n characters for example. And you'll use a GIN index at first in your Postgres DB for fast text search. It might all sound a bit insane but I believe that everyone should give Phoenix/Liveview a try. That stack can scale and it works amazingly well even on a cheap Heroku dyno.
- _query 6y agoThis approach definitely has a lot of value for specific use cases. Specifically to get MVP done in a fast way. When you need to scale out, you can still add a SPA later on. If you combine the approach of WebSockets + dom patching with postgres pg_notify you get some real magic :) In the new IHP framework we provide something like that. We call it Auto Refresh: https://ihp.digitallyinduced.com/Guide/auto-refresh.html https://ihp.digitallyinduced.com/Guide/auto-refresh.html Auto Refresh is activated with a function call inside a controller action, like this: action ShowProjectAction { projectId } = autoRefresh do project <- fetch projectId render ShowView { .. } The only difference to a normal IHP action is that it has the `autoRefresh` call in front of the do-block. Once activated IHP will automatically track all tables your action is using e.g. in `SELECT * FROM ...` queries. Once the action sends a response IHP will start watching for any kind of `INSERT`, `UPDATE` or `DELETE` statement to all the tables used by your action using pg_notify. When the page is rendered a small JavaScript function will connect back to the IHP server using a WebSocket connection. Whenever an `INSERT`, `UPDATE` or `DELETE` happens to the tables used by your action IHP will rerun your action on the server-side. When the generated HTML looks different than the HTML generated on the initial page load it will send the new HTML to the browser using the WebSocket connection. The JavaScript listening on the WebSocket will use the new HTML to update the current page. It uses morphdom to only touch the parts of your current DOM that have changed. Here's how this looks in the real world: https://twitter.com/digitallyinduce/status/1320728833394380801 https://twitter.com/digitallyinduce/status/13207288333943808... <- This view has no app-specific Javascript. The auto refresh is enabled using a single function call and the framework takes care of all the technical details. Some use cases where this really shines: - interactive dashboards (e.g. showing the current status of job queue) - simple user chat systems (you can send messages using normal form submission, as long as auto refresh is enabled this works like a SPA) - building a twitter clone, the feed will automatically add new content as it's added to the database We're using this approach in production since last year and it saves an incredible amount of development time.
- netik 6y agoThere is so much wrong with this article I don’t know where to start. Apollo’s GraphQL with built in pub sub and JSON over websockets solves most of the issues brought up here with little work.
- Martinsos 6y agoDidn't Meteor offer a conceptually similar solution, in the sense that data is constantly synced, via sockets? But it didn't require us to think about sockets so much, which is great. There is a lot of talk at the start of the article how web development should be easier, how it should be less about the underlying architecture and that we shouldn't spend time on implementation details like state that SPA suddenly has to manage. On the other hand, I felt the rest of the article seemed pretty implementation focused, talking about details of how sockets could be used - I do have decent web dev experience but grasping the practicality of the concept based on what was described was beyond me. That said, I love the first part that is talking about simplifying the web app development, to make it similarly simple as it was 10 years ago, but I can hardly imagine that solution to that is replacing one piece of underlying technology with another piece. I imagine that instead, we need a higher level of abstraction that will hide all the implementation details that we don't care about and capture that what is common through time, so we don't have to care if we are using websockets or http or smth else underneath - instead we say how we want data to behave, and it gets done. Dealing with HTTP or sockets should be reserved for advanced use cases, not typical web apps. I am working on a concept of this, open-source web dev DSL, still in alpha though: https://wasp-lang.dev https://wasp-lang.dev , and while I can't be sure that it is the exact solution, I imagine something similar in the future, a DSL. At the end, frameworks are a step in that direction (embedded DSLs), it is just that they are not standalone languages and are therefore again pretty coupled with the language and architecture they are modeling.
- c-linkage 6y agoThis seems like X Windows protocol over HTTPS with JSON as the wire encoding. It's sad to think how much effort is spent reimplementing technologies because the IPv4 address space wasn't large enough. If IP address space were larger, we wouldn't have needed to rely on Network Address Translation (NAT). NAT became a poor-man's firewall and effectively blocked peer-to-peer connections making it difficult to host a server at home. This incentivized early ISPs to offer only asymmetric connections that pushed users towards a consumer-only service that crippled early Internet protocols. With the World Wide Web being "the" reason people got on to the Internet in the first place, early NAT-enabled routers focused only on HTTP tunneling, so completed protocols that required inbound connections were finally killed off. Who would have thought that a small IP address space could result in a mass protocol extinction event from which only HTTP and HTML would survive....
- schpaencoder 6y agoCouldn’t agree more
- zajio1am 6y ago> NAT became a poor-man's firewall and effectively blocked peer-to-peer connections making it difficult to host a server at home. Most ISPs (with the exception of very small ones) until recently assign one public IP address per customer and NAT is done on home router. With this setup it is not hard to host a server at home - it is just one rule on router to NAT all incoming connections to that server. Many SOHO routers support such setup. Alternatively, the server can just work as a router. > This incentivized early ISPs to offer only asymmetric connections that pushed users towards a consumer-only service that crippled early Internet protocols. Asymmetric connections are offered because many last-mile technologies (like ADSL and cable modem) are asymmetric on link-level - they use different bandwidth allocations for upstream and downstream.
- Skunkleton 6y agoThey are asymmetric because the are provisioned that way. IE it was done intentionally.
- Animats 6y agoIt can work, but it's harder than stateless. The web works with crappy code because the persistent state is in the database, which is of higher quality and stability than the applications. If you have persistent in-memory state server side for each client, the server has to maintain that state correctly. The server has to be much more bug-free. Also, every background tab in the user's browser now consumes server resources although idle. You do not need this for your 1 to 5 stars rating thing. Most web pages do not need this. They're rather banal. We have huge overkill in web technologies now. We have WebGL, which is little used, and WebAsm, which is little used, for when you really, really want to have full interactivity in the browser. There are a few nice applications using those, but only Google Earth is mainstream.
- pantelisk 6y agothe energy utilization of keeping sockets open for every tab, can get out of control quickly. Usually if users are expecting it to (eg multiplayer game, or collaboration apps) that might be fine. But fetching a tiny page and then keeping a socket active just in case 2 hours later somebody goes back and clicks on some link is not so great. Sure one could close the connection and re-open when the user comes back, but again it feels a bit too much for something that simple as websites. Nonetheless the idea is not bad. I just feel that HTTP/2 with its multiplexing is a nice middle ground and it comes for absolutely free.
- LunaSea 6y agoWebGL is not adequate for use cases besides games and VR because text is not really supported.
- mattlondon 6y agoWrangling with JSON? Not sure about React, but with Angular and tools like gRPC you don't see a single byte of JSON and the code that interacts with the APIs is automatically generated at compile-time and is type safe (with intellisense too!) It is pretty effortless these days IME. You can't make a mistake with the coding side of things calling an API as the actual mechanics is seamlessly hidden away - mistakes can only be made in the "business" side of things (and this HTML-approach won't save you there...) If you are using an "in house" framework (or just something ancient/niche like rails) then perhaps you don't benefit as much from modern bug-resistant frameworks and tooling I guess... In which case you're probably going to make more gains just by using a mainstream framework rather than trying something new/unusual/untested(?) like this. Good luck anyway!
- snejad123 6y agoI don't understand the benefit ??? This seems like unnecessary overhead for any startup software companies, costing both extra time and money while overloading your server right out the gates. Instead of expecting 100 requests per min from say like 20 users, I can now expect 1000s+ to my server because I'm sending every keystroke to the server ??? That means I'll need a super expensive instance to handle all those users and this is in the extremely conservative use-case of 20 users at once. No thanks.
- dynamite-ready 6y agoNot quite. With requests over HTTP, there's an overhead for every single request. For websockets, you make one fat handshake/upgrade request to start with, and then all successive "requests" (frames) have no headers. So depending on what you're doing, and how you do it, it can be more efficient.
- MaxBarraclough 6y ago> With requests over HTTP, there's an overhead for every single request. Doesn't this go away with HTTP/3 and wherever QUIC is used?
- deleted 6y ago[deleted]
- didip 6y agoStateful proxy and horizontally scaling them is not easy. I doubt this approach will be hugely popular.
- superkuh 6y agoThis is almost there. It just needs to go one step further and remove the websockets.
- bilekas 6y agoThis reminds me not of every proponent of new technology who can't get their head around knowing the right tool for the job, I think this article is actually positioned better than those.. I do like some of the points. But instead reminds me of a friend who went full gRPC learning, so far as to start contributing to the newer standard definitions of RPC, he used to turn around and say that all API's SHOULD be replaced with gRPC and argue as I would about how its not always needed etc, he knew enough to counter with good reasons instead or the reasons why it should be.. And sometimes thats the biggest hurdle, its not that it can do everything better, even easier. It's just the commitment devs/companies whoever will have to do it.. I'm guilty of not using the right tool for the job sometimes.. But I'm struggling to think of any protocol or implementation that has been fully replaced without huge intervention.. Even TSL/SSL implentations was (rightly) pushed heavily by browsers, no ssl, no sensitive data transfer. But on its own, I don't see any replacements today wiping out the old. I'm no fan of latest fads.. You show me a good standards doc thats got strict implementations, I'm on board! You show me a 'recommendation' based on some amazing points and valid critique, I'm not so enthusiastic..
- deleted 6y ago[deleted]
- redkoala 6y agoThere are severe limitations in what cloud vendors can support on concurrent web socket connections without rolling and maintaining your own. Persistent connections may fit for specific use cases where continuous real-time updates are needed but are a poor fit for most UI - backend interactions.
- rmrfrmrf 6y agoI used to love reading A List Apart in the 2000s and associate it with rise of Web 2.0 apps, so when I saw the domain, I wondered why I stopped reading. After reading, I almost laughed out loud that the author apparently felt the need to relitigate the rise of SPAs, throw in a shoutout to SEO, dunk on Java developers, tug on our heartstrings thinking of the kids in Africa with iPhone 4s crying while Safari parses 100kB of JSON (in 2005, this would have been a story about grandmas surfing the web on IE5), and, as a special treat, throw out a recommendation for Ruby on Rails in 2021. A List Apart appears to have pivoted to a sort of digital Renaissance fair, but for the year 2007.
- throw_m239339 6y agoThe author doesn't understand the stupidity of wanting to re-implement HTTP over raw sockets... No, the future of HTML software is just HTTP version X... not raw TCP-IP...
- bob1029 6y ago> the future of some web software Don't get me wrong - we use Blazor server-side for several critical webapps now, but I would be the last person to suggest you use it (or anything like it) for all web applications. For instance, a Netflix-scale operation + Blazor server-side would almost certainly be a really bad mix. For use cases where the maximum number of possible users is bounded by ~10-100k and within a 100ms latency domain, I think a very strong argument can be made for such technologies. The productivity uplift is pretty incredible when you can directly use your existing domain services to drive UI. We also like the security implications of these sorts of technologies. The incremental disclosure of the client app is an excellent selling point for many of our customers.
- pier25 6y agoTo me the future of web dev is SSR components with partial hydration on the client. Use components as if you were doing front end on the server. No more crappy server templating engines with poor composition and no interactivity. You go straight from the DB to the component. Then only the absolute minimum JS needed for interactivity is sent to the client. This is not so far away btw. I made this work on Svelte although hydration is clunky and it was a bit convoluted. Marko has been doing this since 2017 I believe and is running on Ebay. AFAIK Imba 2 will have partial hydration too.
- gijoeyguerra 6y agoI love starting with HTML and creating a design that composes HTML fragments (partial HTML). It creates affordances. But relying on WebSockets as the communication strategy really reduces the number of use cases where this is sustainable in many dimensions. Perhaps, instead of following all of the advice in this article, start with HTML fragments via Content Negotiation. Compose UI experiences over stateless HTTP first. Then build upon that foundation instead.
- theqult 6y agoYo dawg, I heard you like HTTP so we put HTTP into binary into HTTP, so you can browse while you browse
- dbotton 6y agoCommon Lisp https://github.com/rabbibotton/clog https://github.com/rabbibotton/clog Ada http://gnoga.com/ http://gnoga.com/ Already there :)
- CyanLite2 6y agoI'm building a new SaaS with Blazor Server-Side, and it's super productive and I simply don't get the fascination with WebAssembly. Sure, I use vanilla JS for things like field validations, but server-side rendering is so fast with it that its barely impercetible.
- sshumaker 6y agoThis approach also completely overlooks the fact that most sophisticated products are multi-client: web and native mobile app. In this world you want APIs that can mostly be shared across platforms, as mobile should operate as more of a thick client anyway given network latency. So supporting HTML over websocket as another client is pretty incongruous from an architectural perspective.
- ilaksh 6y agoHTTP/3 connections are supposed to stay open. So how much time does a websocket save?
- est 6y ago5 years later: the future of Web is HTML over WebRTC.
- johndoe42377 6y agoOh, decades old client-server model, who would have thought. Let me guess. Protocols should be binary and stateless, like telecom industry and Erlang is doing. Pure functions on a server side, share nothing, fail fast, all the principles behind Erlang all over again. What else? Oh, relational databases as storage backends. Can't believe it.
- Felz 6y agoI've been using a reactive websockets over HTML in Kotlin implementation that I wrote myself, and it's been the least unpleasant web development experience I've ever had. There really is a huge advantage when you don't have to marshal/unmarshal/validate a request for a simple callback on a button, and page loads can be much faster. That said, there is more operational complexity (though given my site is relatively small, not much yet). State that lives with the server dies with the server, so deployments can take longer if client sessions live for a while.
- DonnaFry94 6y agoI аm lоoking for sеx, but dо уоu wаnt? Соmе in hеre > https://oo.lc/kERN2 https://oo.lc/kERN2
- CamelRocketFish 6y ago> How about client-side validations? Easy. On every input change, round up the form values and send ’em down the WebSocket. Let your server framework validate and send back changes to the HTML of the form, including any errors that need to be rendered. No need for JSON or complicated error objects. Maybe in an ideal world where responses are 1ms this would work, but imagine real world, real-time validating user input (ie email) and the user needs to wait before they find out their input is valid.
- hnedeotes 6y agoInput formatting like, emails, phone, or things that you can know in the frontend, can all be done (and should be) on the client side (many even on html itself although it's a bit lacking in some cases, that would definitively be the ideal although I also don't think html is going to be able to cover all use cases ever - or that it should - but in the end it always seems to be missing just one tiny thing that forces you to write JS). What you may want to do is to submit changes in case you want to see if an email has been taken already, for instance, to display additional information while the user is writing and this no matter what technology is used would always require a round-trip? No saying that you need that, but it's up to you when implementing deciding on what is the UI/UX you need and take it from there, it's not like it forces you to do that. (sometimes articles take it a bit too far and end up showing anti-patterns, mixing problems it solves and problems it creates when misused)
- quattrofan 6y agoPlease don't let us come back to Rails
- joelbluminator 6y agoWho's "us" - you and your friends? please speak for yourself. I like Rails just fine.
- ilovwindows 6y agoThe biggest drawback of this pattern is, it won't support mobile and desktop apps.
- blodkorv 6y agoDont java with JSF2, Wicket or similar do this but with http?
- hgretg3443 6y agoYou can already do this with serverside Blazor.
- habosa 6y agoVarious forms of server-side rendering for JavaScript-heavy webapps are definitely picking up steam, but I don't see how they will gain popularity among the long tail of web developers because of one thing: cost. Simply put a client-side SPA is much cheaper to run than almost anything else because you're pushing as much computation as possible onto the client where you don't pay for it. You just need a good static host with a CDN like Netlify, Firebase, etc which is nearly free (for small sites, completely free). Developers who have tried this are not keen to go back to paying for servers to do this computation. Big companies can and will pay for this cost to improve user experience (see: Next.js popularity) but I just think a lot of solo hackers will shy away from it and that will affect momentum. This isn't really a critique of the technique one way or the other, just a prediction of how far the trend can go.
- ehnto 6y agoI think you're overestimating the computation that the client side does. For the majority of web applications the biggest workload is in querying the database, which for any site of non-trivial complexity will tend to come from some kind of server-side API. I also feel there is something to ownership of your tools and platform, and an application strung across several SaaS and a toolset that requires phoning out to different SaaS in order to work is anything but yours.
- joelbluminator 6y agoI don't quite buy it. Go with Rails if you like Ruby, Rspec, rapid development and the nice ecosystem around it. Most Rails apps are CRUD and don't really need streaming with websockets. Rails with stimulus is more than enough to create a good user experience, I don't see why you need to add the complexity of websockets.
- jack_riminton 6y agoI agree for the most part but features are increasingly demanding a ‘real-time’ feed or updates of sorts Turbo is actually a rather simple way of achieving this with rails https://turbo.hotwire.dev/handbook/streams https://turbo.hotwire.dev/handbook/streams Which is something that would be very clunky for stimulus
- joelbluminator 6y agoI can see a minority of features that would actually need it like the classsic chat room or some live feed of stocks. Sure if thats the case then Hotwire gives a nice solution. But throwing in streams just for validations? Come on. This is done just fine with Ajax/Rails Ujs etc. We're solving non problems here I think.
- loxias 6y agoThis is the worst and most depressing thing I have seen in a long time. Remember when we used to write software? The turtle stack is way too high.
- jillesvangurp 6y agoIf we pull our heads out of our behinds and look at the broader trends in e.g. the gaming industry, the trend is fully interactive applications rendered in your browser using WASM. All the big cloud companies and several gaming companies are doing that currently. They completely engineered away the browser limitations of only being able to run javascript and only being able to render DOM trees. That API was painful to deal with 20 years ago and it has not improved a whole lot. 20 years ago remote UI was painful. Now you can play the latest games at 60 fps on a cheap chrome book, ipad, or even a phone. The trends here are that computation can be remote and that real time, responsive interactive UI can be remote as well thus removing a lot of the need for a lot of complex local on device interactions. The only thing that goes over the wire to the server is low level input events; the thing that comes back is intended for a software renderer written in WASM and Web GL. You should not have to build your own renderer. Gaming companies ship existing games to things like Stadia or Nvidia Geforce, etc. Not saying that this is the future. But we seem stuck in a lot of abstractions and constraints imposed on us in the late nineties when Brendan Eich et al. gobbled together a scripting language in a hurry and HTTP 1.1 was frozen in time until SPDY became a thing only a few years ago. Most of the past 20 years is just increasingly more sophisticated hacks to work around andundo all of that. We are now at the point where you can play an FPS game running on a remote server or boot a virtual machine with an actual operating system in your browser. So, why are we still doing UX with our hands tied behind our backs? Is that really the state of the art? IMHO it's not even close to that. It wasn't the state of the art 20 years go. All it ever was was convenient for developers. And even that is debatable. We had graphical tools for clicking together UI in the nineties (Delphi, Visual Basic, JBuilder, etc.). That stuff worked great. OK, it resulted in a lot of ugly and unusable applications. But then most SAAS browser applications that replaced them aren't a whole lot better or less painful to deal with. Yesterday, I was in a design meeting where we looked at our latest Figma designs. Figma is a tool for clicking together UI just so you can create something that looks like an app that you then give to a developer so they can transform it into something that actually works. That process is completely manual (most Figma users don't generate code from it). UI frameworks and tools are terrible. All this manual work that you need to do to get from a slick click demo that runs in a browser to an application that looks exactly the same and works .... in the same browser. Am I the only one who thinks that is backwards? So moving some of that back into our servers is a baby step on the way to better tooling. But we have a long way to go.
- gonational 6y agoThe Future of APIs is SOAP over UDP. No kidding though, Poe's Law applies to this article. This shit has gotten out of hand. A List Apart used to be a serious publication; ideas like progressive enhancement and responsive CSS came right out of that publication. The fact that many folks think this is a good idea paints a bleak picture of the future of web development. The web worked well before (circa 2010, jQuery, Ajax, etc.). It was just too complicated to make very dynamic pages. We don't need more inventions. We need to use the inventions we have correctly. https://xkcd.com/2021/ https://xkcd.com/2021/ Instead we got Angular, et al. The ability to connect DOM elements to state management is great. This was another piece we needed. Unfortunately, this piece was introduced along side a pattern and framework. The former lent credibility to the latter two. This same thing happened when rails came out; rails introduced the ORM to the masses, and offered MVC along side it. The vertically integrated synergies created by these parts allowed rails to soar. In that case, it was a good thing; Rails changed the web for the better, by a long shot. The rabbit hole that reactive took front-end web developers down over the past decade has been more than destructive, because it happened just in time for the largest growth in new web developers ever. Primarily, this is the reason it was able to happen (the overall reduction in aggregate experience). These frameworks have taught us a lot of really great individual things, but as whole they have ruined many parts of the web, and they've destroyed the discipline of developers. Now a basic CRUD application is dynamic enough, for many developers, to warrant the use of such frameworks. You can say what you want about how tremendous this reactive framework or that reactive framework is, but you cannot deny the fact that 75% of websites have hundreds of percent more bugs, and nearly half the web renders a blank page for multiple seconds before anything shows up to the end-user. This is worse than the 1990s. Honest to God, I give up on more than 1/3 of e-commerce transactions these days, because some form of UI fuckery breaks my will. When I open a link and the whole page is white, despite seeing that everything has loaded, I literally close the tab before even having to see the monstrosity that they've created. What's worse is that many developers will create a reactive website that literally does not react; it just changes pages and re-reacts every time a new page loads. SMH... </rant> Tonsky writes great rants about the absolute state of things as well: https://tonsky.me/blog/disenchantment/ https://tonsky.me/blog/disenchantment/ https://tonsky.me/blog/tech-sucks/ https://tonsky.me/blog/tech-sucks/
- jeffmcmahan 6y agoSuppose I want to expand/contract a row view - toggle to see the details. The data is on the client and the HTML is already printed to the page; it just needs to be shown/hidden. You gunna hit the server to get back an HTML fragment that says <div class="show">? If yes, you're certifiably insane. If no, then you need client-side JS, and you're therefore going to strike a compromise between all-on-the-server and all-on-the-client, which will probably differ depending on the project. HTML over the wire is often a useful approach; it doesn't follow that "the future" is there.
- ydmitry 6y agoHow e.g.datepicker implementation will look like with this approach?
- da39a3ee 6y agoThis doesn't seem kind to people with slow (or expensive) network connections. Note that currently we are on the verge of a point in history where almost every person, even in rural communities in developing countries, has an internet enabled mobile device. In the SPA model yes, they will have to wait a long time to download the initial JS payload, but that can be cached. Thereafter, if UI updates don't need to talk to the server, they can be computed client-side and the UI can update instantaneously. But in the suggested model, a much larger class of client-side actions would trigger (blocking?) network requests.