Live data from Hacker News

If Not SPAs, What?

macwright.com

201–210 of 456 posts

Re: If Not SPAs, What?

#201
post #149
post #78

I'm building an app with a TALL stack now (Tailwind, Alpine.js, Laravel, and Livewire) and I am incredibly productive. Very little build step required (to compile Tailwind to reduce the size based on which classes are used in .blade.php files). CRUD, Image uploads etc are so easily done I am such a fan. I was skeptical at first, but now I love this way of building web apps. No idea how well it scales, but for a simpl…

For all the speed bumps PHP 7 delivered Laravel typically scores lower than Django and Rails on Techempower benchmarks. This and the reality that PHP roles typically pay 20% less than Ruby, Python or Node has led me to ignore Laravel.

I haven't built anything that requires significant performance tweaking other than some caching and SQL optimisations. Maybe PHP 8 will bring an even better performance when it gets released

> HP roles typically pay 20% less

Yeah, true. Hence why I am a React dev professionally

Re: If Not SPAs, What?

#202

I have a theory. In the old days web development was looked down upon by "real" programmers. But then the WWW really took off and people started moving over from the C/Java world into the world of JavaScript. These are the people that insanely complicated web development when they tried to make it as complicated as the development world they came out of.

Do you have evidence? Vue and Svelte, IIRC, were authored by designers. Not C or Java programmers. Perhaps React has a different history.

> I have a theory

Pretty sure they were just sharing thoughts.

Re: If Not SPAs, What?

#203
> How do they do this? Well, a lot of WebSockets, in the case of Reflex and LiveView, as well as very tightly coupled server interactions. As you can see in the LiveView demo, which I highly recommend, these frameworks tend to operate sort of like reactive DOM libraries on the front end – in which the framework figures out minimal steps to transform from one state to another - except those steps are computed on the server side and then generically applied on the client side. They also do a lot more data storage & state management on the server-side, because a lot of those interactions which wouldn’t be persisted to the server are now at least communicated to the server.

Reminds me of Wicket's AJAX support, which is still the best web development experience I've ever had. You keep the state in the server-side session, when the user pushes a button you update that state and re-render those parts of the DOM that changed because of it. It dovetails nicely with the whole framework being properly component-oriented - rather than the page-oriented MVC style, you make encapsulated, reusable widgets that know what their own state is and how to render themselves based on it, and the actual top-level page becomes almost an afterthought.

Re: If Not SPAs, What?

#204
post #134

Earlier quoted context omitted.

> developing became more and more inefficient Anecdotally I find the opposite to be true. I've been writing frontend code for over a decade, but I've never moved faster and wrote less buggy code than now. Is that because I've become a better developer? Sure, a little bit. But by and large, I don't believe that ultimately is the reason. I think it's the maturity in the technology. My growth as a programmer is hardly l…

> Frontend tooling has never been better than it is today. What's the library or design pattern to consume a REST API in React or any of the mainstream front-end frameworks? The only thing I'm aware of is Ember Data but Ember is apparently not cool anymore, and I couldn't find a suitable replacement. I'm asking because in all the projects I've been involved with, consuming the backend API always felt like a mess with…

> I'm asking because in all the projects I've been involved with, consuming the backend API always felt like a mess with lots of reinventing the wheel (poorly) and duplication of code. I can't believe in 2020 there's not some kind of library I can call that will give me my backend resources as JSON and transparently handle all the caching, pagination, error handling (translate error responses to exceptions), etc and people have to do all this by hand when calling something like Axios.

If you look at 20 REST API's you'll probably see 30 different patterns for pagination, search/sort, error responses, etc. There have been a couple attempts to standardize REST such as OData but I think it's safe to say that they haven't been very successful. It's kind of challenging to build standard reusable front end tools when everyone builds back ends differently.

Re: If Not SPAs, What?

#205
post #172

It's interesting to me that in video games we talk less about frameworks than we do engines. Doing a few tutorials, I was shocked at how little code I had to write these days with something like Unity or Godot. Breakout indie success stories are often lead by artistic types, since it seems harder to teach a typical programmer to draw than to teach an artist enough code to get by. And I think the scene is richer for i…

How often do you deal with blitting textures into vram when working on your web applications? If not very often, that means you're building on top of a stack of software that includes a rendering engine, equivalent in many ways to Unity or Godot.

> you're building on top of a stack of software that includes a rendering engine

Yes that's pretty much a web browser, isn't it? There are many types of engines, such as a business logic engine. The distinction between engine and framework is a little vague but what I'm getting at is the low-code interacting-components design approach, rather than code first. I'm wondering why that hasn't taken off.

People use Godot to create GUI apps, which has problems with the final product but in terms of workflow it works to make something functional.

Re: If Not SPAs, What?

#206
post #134

Earlier quoted context omitted.

> developing became more and more inefficient Anecdotally I find the opposite to be true. I've been writing frontend code for over a decade, but I've never moved faster and wrote less buggy code than now. Is that because I've become a better developer? Sure, a little bit. But by and large, I don't believe that ultimately is the reason. I think it's the maturity in the technology. My growth as a programmer is hardly l…

> These inexperienced people are put in charge of designing codebases that don't scale and become spaghetti. I think this is one area where front end tooling can be painful for the average dev. The bar to writing idiomatic JS for a given framework can get pretty high quickly, especially when you look at some of the really popular tools out there (i.e. redux). Front end work has become so much harder to grok because t…

What most people have in mind as "idiomatic JS" isn't that. It's usually meant to refer to some patterns that appeared and started getting popular around 8 years ago. And often, code written in this not-idiomatic way works _against_ the language and/or the underpinnings of the Web in general. It's just that the circles promoting the pseudo-idioms have outsized and seemingly inescapable influence.

Re: If Not SPAs, What?

#207
post #171

IMO, TurboLinks + service workers are the way to go. Not many people know this, but a service worker (previously called "local server") allows you to run a little web server in the user's browser that intercepts requests to your own web site. (There's no open IP port.) The service-worker web server can proxy requests to the remote server, and even build/store entire pages on the client side, enabling offline support.…

I have literally never had a worse experience developing than with serviceworkers. Accidentally cache your index.js file? You are now stuck with your serviceworker forever (unless you do some chrome voodoo). The promise is there, but it’s just a gigantic footgun.

If you build your SPA to an index.js file and serve it without a timestamp you're screwed when it gets cached too.

Re: If Not SPAs, What?

#208

I have a theory. In the old days web development was looked down upon by "real" programmers. But then the WWW really took off and people started moving over from the C/Java world into the world of JavaScript. These are the people that insanely complicated web development when they tried to make it as complicated as the development world they came out of.

AngularJS was designed by a Java guy, so the argument has a little merit.

But honestly, this is because mature backend frameworks can be REALLY nice.

Re: If Not SPAs, What?

#209
post #160
post #84

The Phoenix LiveView pattern is one that I thought was the near-ideal interactive page architecture 20 years ago, long before Elixir and even before XHR was standardised. (We had other methods for AJAX and server-sent events to achieve it in those days.) It surprises me that there are so few implementations using this pattern today. The Meteor pattern is another good one for the user, if you like things better optimi…

The basic issue was that the coroutine package was segfaulty and maintained by a man so lovely to interact with that the node.js core team eventually invented libuv (to replace his ev library) primarily so they never had to talk to him again. Perl now has http://p3rl.org/Future::AsyncAwait which is (like any async/await system) a bit more restricted than a full coroutine but works beautifully. If you threw a github r…

Thanks for the suggestions!

But I've found Coro highly reliable and effective, including under stressed and complex loads, for about 6 years. Never found it segfaulty. It also performed well, and the API design always impressed me with its cleanliness and good documentation.

Also I make extensive use of coroutine-local variables (like `thread_local` in C11) which operate at the same speed as normal `my` lexicals. I.e. as fast as possible. It's just a good way that ordinary non-async modules can be trivially made async-safe, without performance loss, and without becoming tied to async or not-async (they become equally flexible for both uses, which is valuable). (The module to make them run that fast isn't public, but the API it relies on to work is part of Coro. `Future::AsyncAwait` doesn't provide the necessary API at the moment.)

> Perl now has http://p3rl.org/Future::AsyncAwait which is (like any async/await system) a bit more restricted than a full coroutine but works beautifully

I'm not convinced. Future::AsyncAwait is a different paradigm, and doesn't do the things I find Coro useful for.

Async/await has the "function colour" problem - every module that might logically "block" has to be re-engineered with a new, async version of the same module. Same applies to any function which might call another to any depth in the call graph which then "blocks". People have argued that the "function colour" problem with async/await isn't really a problem. I'd argue that it's fine if you've designed around it from the start and you don't intend to use code in both async and non-async environments.

That re-engineering can be done, but it's a massive change to existing modules, and then you end up with something that can only be used in an async/await program.

Whereas Coro is non-invasive. I use the same modules in an async server or in a classic process-forking server (without loading Coro and no concerns about async issues), as well as standalone processes (scripts). I choose appropriately depending on the service characteristics (e.g. async is poorly suited to some kinds of loads such as computationally heavy request processing). Also for some things it's good to have the confidence that comes from not loading any fancy stuff, e.g. in security code and standalone scripts.

For that dual-use functionality, as far as I can tell with Future::AsyncAwait I'd need to write two separate versions of most things.

It turns out a lot of things might call something that, via a deep and opaque call chain, might block somewhere. E.g. any code that loads a config file when it's first run. Anything that uses a template, and calls out to a template compiler. Anything that compiles and loads code lazily. Anything that does something as trivial as stat() on a file.

In practice for my web stuff that means nearly everything (as you can imagine from my GP comment). I also make heavy use of JSX-ish templates instead of custom Perl code. It's just cleaner, and they can be targeted to other languages, even compiled to C for speed. Template components end up inheriting the same async properties as the server they are running in. A page may refrence subresources, microservice calls, data fetches or file reads. All fetched or calculated in parallel (calling other services or using multiple cores if necessary), which is good for latency.

There's also a software engineering impact. As soon as you get deep into complex logic like filesystems, and especially with memory allocation inside those, which triggers nested filesystem access, it's just too much work to engineer everything in an async state machine way. That's why the Linux kernel was unable to do correct asynchronous I/O through AIO functions for many years, and that's why everything end up choosing threads instead of AIO in userspace too: libuv that you mentioned is a great example!

> update it to more recent+reliable perl tech

I think "reliable" is misleading. Coro is highly reliable (for me anyway), while Future::AsyncAwait has documented gotchas.

For "more recent", the Perl community has picked its path. In my view it's a less useful path, and I'm disappointed Perl core didn't choose to implement a coroutine mechanism. But it didn't.

With Coro all the modules just work without anything Coro-specific in them. (Just a few coro-local-data annotations, which are ignored when Coro isn't loaded.) It's neat!

As I use the same code in async and non-async contexts, I really don't see me using Future::AsyncAwait and writing two versions of each module.

> If you threw a github repo up somewhere I can think of a few people who might be interested

I never did get that framework to a point where I'm happy to publish, because it's entangled with commercial and private code. Cleaning up the separation seemed like a goal once, but I think I'd be wasting my time now. It's a great shame when you have a big personal library of Really Useful Modules, but sometimes you just have to start again. The ideas live on!

Re: If Not SPAs, What?

#210
post #122

Earlier quoted context omitted.

Kubernetes is the biggest joke. I remember working with a sysadmin who worked for The Guardian provisioning servers remotely as demand spiked. This is pre-AWS. He used Puppet and remarked that you would only ever need what he was using for managing massive fleets of servers. Then Kubernetes and Docker arrived, which were intended for even bigger deployments in data centres. Before you knew it, just as with SPA's, Kub…

Also never underestimate the power of a single bare-metal server. Today everyone seems to be in the clouds (pun intended) and has seemingly accepted the performance of terrible, underprovisioned VMs as the new normal.

Stackoverflow -- the website that every developer uses probably all the time -- is an example of a site running on a very small number of machines efficiently.

I'd rather have their architecture than 100's of VMs.

Post reply on HN