Wasm-service: Htmx, WebAssembly, Rust, ServiceWorker proof of concept
github.com
github.com
To show this easily, try this in a Firefox Private Browsing window: service workers are disabled there, so the request goes through to the server, which responds 405 Method Not Allowed.
So in order to make this approach reliable, you’ll need to run that code on your server, not just in the service worker. This is totally viable, but an approach that has seen surprisingly little experimentation. (I myself have a grand scheme that’s actually fairly fleshed out, but I’ve only touched it once in the last year and a half, so don’t hold your breath. My scheme is predicated upon aggressively not requiring client-side scripting, but using it only for completely optional enhancement; and upon running the same source code in a worker, in a service worker, at the edge or on the origin server, with only a teeny bit of JavaScript on the main thread.)
Beyond that, I don’t know, but I would expect things like some lower-powered and -storaged devices rejecting service workers, and maybe privacy modes too, though in that case they could possibly be allowed with just background stuff neutered.
It’s similar to a large part of the reason why Local Storage and Indexed DB were historically disabled in Private Browsing: why store stuff when it’s only going to be deleted immediately?
Browsers have mostly headed in the direction of removing distinguishing features from their Private Browsing modes, partly to thwart detection of that mode, and partly because many things started to carelessly depend on the gated functionality. Firefox still doesn’t allow writing to Indexed DB (and only made Local Storage work far later than Chromium), and I’ve definitely encountered sites that just assumed it would work, and so fell over in early initialisation.
And so for this specific subthread: it’s ossification at work. If something is supposed to be able to change but never actually changes, you find when you try to change it that you can’t do so any more because people have built too much stuff that assumed it wouldn’t change.
https://bugzilla.mozilla.org/show_bug.cgi?id=1320796
Firefox will eventually catch up. The possibilities for this approach are actually quite interesting, and go far beyond the much less useful scheme you outlined that relegates it strictly to just being an optimization.
I’ll tweak my statement slightly: for regular site functionality, service workers must be optional. Depending on service workers for anything that does not inherently require them (like background sync or receiving push messages) is bad.
Or access to CacheStorage, and acting as an offline server when the network is unavailable. Perfectly reasonable to depend on if your use case requires it.
But that doesn't rule it out in some special case. Special cases are special. (I recently wrote a Chrome-only web app because it requires access to the serial port.)
I say: feel free to use service workers, but do not feel free to depend on service workers. They must be optional in general-purpose websites.
At any rate, this is more of a StackOverflow question than an HN question, and the details of what works will differ from project to project.
https://stackoverflow.com/questions/51597231/register-servic...
I don't agree with this because you're essentially defending writing websites and apps for specific browsers. "Oh, this doesn't work in your browser because it requires [specific tech|devs to test in more than one browser|whatever]" is a lame excuse in a world where progressive enhancement has been an accepted approach to developing web software for twenty years.
As a tech demo to show something is possible it's fair enough, but in the real world this shouldn't ever happen.
There's another flaw I see with using Service Workers in this way. After a period of time where the Service Worker is inactive (a minute or so on Firefox), the browser will shutdown the Service Worker. When it shuts down, all variables in the Service Worker scope are freed and I assume the WebAssembly server instance as well. How would you maintain server state, in this scenario?
I may be a minority weirdo, but I have set dom.serviceWorkers.enabled to false.
Why? Because legit sites aren't broken by this and I always clear all browsers cache and databases on close (several times per day). IMHO service workers are used mostly for long-lived tracking, to supercede the cookie, and I also dislike background processing for things I just don't care about.
So for me... service workers are disabled. They just don't work. And it turns out the web works just fine.
I’m… not sure what to say.
https://github.com/jon49/Soccer
https://github.com/jon49/WeightTracker
So we used to have react/vue/whatever. You click button, and the front end computes the new DOM. No server needed.
Then, we decide to use htmx, where the server actually computes the new DOM elements, and the client is just a dumb client that displays whatever the server gives.
And now, we give the users browser all of the information to act like a server, intercept the call, and compute what the server would have responded with (saving since network packets and lag).
Did I understand that correctly?
And yea, I also saw that talk about HTMX on HN yesterday... didn't really understand the advantage then either.
I have seen the transition away from server side to SPA, from SPA back to server side. Now people are doing server side in the browser. This industry will never become boring if we keep continuing those cycles.
For personal offline first web apps I build I do it this way, except with JS:
Submillisecond uses lunatic to run Rust code compiled to WebAssembly on the backend. We are working on a LiveView-like library now. And one thing I would love to give developers for free is an offline-first experience. You write everything in Rust, compile it to WebAssembly, run it as a regular backend on lunatic, but also allow for moving the whole server into the browser for a offline experience. If SQLite is used for the DB, it could also potentially run in the browser.
This doesn't need to move the whole app into the browser, but could do so just for more latency sensitive workloads that don't fit LiveView well. Like form validation on every keypress, etc.
Another option would be, instead of putting SQLite on the front is to use a repo pattern and if it is on the front end use IndexedDB, if it on the back end use SQLite or some other custom implementation for their repo.
Being involved in a lot of SPA's these days I can't help think that we spend way too much time building complex frontends and managing state.
Anyone feel the same way? HTMX feels fresh.
The code looks a bit complicated though. Some explanation of what’s going on would be helpful.
So you have a client side app that is 100% static HTML + WASM service worker in the browser, making calls off to some external API as it needs data but otherwise generating static HTML in the browser blob.
I wonder how much slower or faster this would be than a JavaScript heavy UI with traditional server side rendering. You would at least remove the RTT latency
What problem would that solve, and how is that any different than how websites already work today?
There's going to be server-side business logic that can't be "moved" to execute over on the client-side, for security/architectural reasons. On the client, websites already today use JS/WASM.
I have no idea if this would be faster or not than the typical SPA type approach we have with react et al. For simple pages probably not much difference, but for large complex pages ...who knows.
E.g. imagine if you used emscripten to compile PHP or RoR or something into a WASM blob and have a service worker intercept the calls and have the wasm blob "serve" the static HTML without ever leaving the browser (apart from API calls to the server for e.g. database access). Replace PHP/RoR with your server-side thing of choice (homebrew or otherwise)
Bit of a thought experiment I suppose. Not a serious thing but kinda interesting.
How is this different from or better than current WASM-based frameworks?
One of the examples https://github.com/security-union/yew-beyond-hello-world
After a Django+React project demanded 24 hour days from my team, I achieved the insight that with pure Django pages, you call (request) using strings containing function name and parameters like `/articles/page/2` and get an output (response) and the runtime (browser) can memoize (cache) the result since the whole process is... functional. Some of my react pages had a dozen ways of reaching illegal states, many caused by network calls. The former became the ideal to strive for. Hence why I think fake web servers via service workers will be popular for bug free (heh) offline first apps.
I was considering using htmx + wasm for my website. Combined with my one-sqlite-db-per-user infrastructure it may enable me to do some fancy edge computing :)
Glad to see a PoC showing that the htmx + webassembly part of it is possible!
Can we render on server , then upgrade to render on client progressively?
Also can we load other wasm using server push in the background . You get runtime plugins then
It has tools both to emit TypeScript definitions from Kotlin, and to generate Kotlin types from TS libraries ("Dukat" tool)
Go I do not have much experience with unfortunately
Can you say why? I don't agree/blanket statements like this seem sorta silly.
PS: I also mentioned language guarantees in my parent post ;)
Just because "it is cool"?
It definitely is not needed for blogs, wikis, news sites etc. This would be for web applications.