5 ms·
I’ve been doing web FE in various capacities for about a decade. First jQuery, then backbone, then Angular, then ClojureScript with React, now React and Apollo.
by wildermuthn 6y ago
I’ve been doing web FE in various capacities for about a decade. First jQuery, then backbone, then Angular, then ClojureScript with React, now React and Apollo.
While I get the criticism about what might seem like an anarchic state of JavaScript, at each transition point there have been clear, demonstrable, and worthwhile changes.
Backbone addressed jQuery spaghetti code. Angular addressed backbone boilerplate. React addressed state complexity, and GraphQL finally forced backend engineering to coordinate with frontend engineering (i.e., making full-stack engineering efficient).
People don’t switch tooling and frameworks for fun (well, not primarily), but because the pain of learning something new is worth the benefit of reducing unnecessary complexity.
What I don’t think non-FE engineers often appreciate is just how essentially complex user-dictated mutable state is. Even with immutable data structures (which I love), you can’t get around the fact that a web-app is, by its very nature, a canvas that changes according to human activity. The difference between FE and BE is the difference between painting with fingers and flipping a switch with fingers. Updating a user’s role on the BE is a single SQL operation, but for the FE, it might mean countless changes to the user experience. It’s the difference between storing data and using data. And if there’s anything to conclude from the overwhelming amount of work done on FE tooling, it’s not that people love to try new things (although we do), it’s that the struggle is real.
Side-note: BE gets a taste of FE complexity when dealing with syncing live mutable data among multiple clients. That’s a beast, and the point where everyone realizes that full-stack is the only sensible way to work.
- viraptor 6y ago> GraphQL finally forced backend engineering to coordinate with frontend engineering I'm curious what do you mean here? The way I see it is the exact opposite - front-end making new kind of queries without having to coordinate with backend. With positive effects (faster results) and negative ones (so this new query takes a minute to resolve and it's in production - fix it now!)
- wildermuthn 6y agoMy view on this may be idiosyncratic and wrong, as I haven’t read about other teams doing this intentionally. Having said that... The most powerful but underused feature of GraphQL is that it abstracts away the details about the BE database model, which is for the FE (i.e., the product and user experience) an unnecessary implementation detail. A poorly designed GraphQL schema (and my teams did a lot of this at first) often look like denormalized REST endpoints. This is particularly true in Relay (do people still use Relay?) In such a case, you’re right that FE-BE coordination doesn’t change much. Additionally, FE stores like Redux are still central to managing derived data necessary for component rendering. However, a well-designed GraphQL schema looks like the shape of data required for component rendering, i.e., for the user experience. Example: having top-level queries for “users” vs. “profiles”. The first has all the data about a user, the second has all the data required to render a user profile page, which almost always includes more data. Let’s say there is a profile photo. A denormalized scheme just defines a "user.profileImage" as an Image type and returns data from a DB relationship of a similar sort (knex and other tools make this easy). While this might seem fine, it is the start of the same old story — BE being blissfully unaware of the use of its data in the context of the user experience. Perhaps when a user has no profile photo a default one should be shown based on their “organization” profile photo. No problem, just pull “user.organization.profilePhoto”? Well, okay, but maybe that is missing too, and we... go down a FE rabbit hole when all we really want is a stupid URL to an image! The alternative I’m suggesting, one that forces FE and BE (ideally one team) to talk about the user experience, is to have a “profile.photo” schema that is resolved on the server. The result of this pattern is a GraphQL schema that accurately describes the user experience. I took the dumbest example possible, but in short, this pushes a lot of complexity to the server where it truly belongs. The FE should be as light, dumb, and functional as possible. The BE should understand comprehensively how their data is going to be used in order to design data models that are efficient. Moving from a denormalized GraphQL schema to a UX GraphQL schema is a liberating experience for everyone involved. The BE cares about the product as much as the FE. This gets them that much closer to the user, where they ought to be. And to your point, this enables the BE to identify potential resolver bottlenecks (and to design for them rather than hacking around them) before such problems ever appear.
- erikpukinskis 6y ago
- aidos 6y agoAgreed. It becomes really messy moving all that state around. Still in its infancy but we’ve settled on a model where we use Hasura to sync the whole datastore to the frontend as a mobx graph. It’s relatively easy to then drive the frontend off layers of computations on that graph. We’ve also put a transaction layer on mutations of the models so they’re automatically batched and sent as a single request / dB transactions. It’s liberating to get to a place where I can just update models in the frontend and have that reflected everywhere because, as you point out, there’s enough to coordinate in all the bits you have to mutate. Edit: we borrowed the idea from how linear.app does it
- paulryanrogers 6y agoWhere and how does conflict resolution happen?
- aidos 6y agoThe clients are all up to date on changes fairly much instantaneously. And then updates from a client are synchronous in terms of setting all data and having that bundled and sent as a single request which is executed as a single dB transaction (we only send the specific fields that were updated). If two people do something at the same moment, then it’s last request wins. We have dB constraints to keep the data consistent. It’s not a perfect model, but it’s pragmatic and works well for our use.
- bartread 6y ago> People don’t switch tooling and frameworks for fun (well, not primarily), but because the pain of learning something new is worth the benefit of reducing unnecessary complexity. This is sometimes true, but not always. For example, it's also sometimes true that teams switch to technology X because X has become popular, and without necessarily understanding the benefits and drawbacks. In some cases a choice is made to switch to X because whatever the team is currently using is "dead"/has gone unsupported. I think these reasons, along with others such as significant breaking changes between major versions that we've seen with some frameworks and libraries, better hint at sources of frustration over "churn" in JavaScript.
- ballenf 6y agoI think the switches are driven by recruiting just as much as the old thing being “dead” in itself. There’s a sweet spot in the middle of a tech’s popularity where people are cheaper. Very late or early expertise is more expensive. You also are getting people who might be more inclined to learn new things. And that may be a proxy for a good hire.
- samblr 6y agoThis post from stateofjs has to be taken with a spoon of salt! "Next.js is amongst the top backend framework" - Anybody can tell its popular for frontend!
- wernst 6y agoI’m sure they’re well aware and had to draw the classification line somewhere. Next definitely fits in both but IMO really differentiates itself on the backend with SSR.
- austincheney 6y agoThis is the biggest problem I have with being paid for front end development. In the corporate world the only focus is on the tools and how to write code. Thoughts of product development and product quality are almost exclusively absent. That is so incredibly frustrating. As a paid professional you would hope your people know how to write code (do their jobs) and churn out original solutions to new problems. Instead it feels like being in a preschool learning to read and being ecstatic that anything gets released.
- judofyr 6y agoWhile I think it's important to fight against the "FE is easy; BE is real programming" stigma, I think you're going bit too much in the other direction. You're painting FE almost as the most difficult thing that exists. However, it's not like GUI applications is a new thing. GUI applications which talks to the Internet is not exactly groundbreaking either. > Updating a user’s role on the BE is a single SQL operation Exactly! Updating a user's role on the BE is actually a really difficult task: You need to persist the data in a safe way and ensure that it's consistent with other concurrent actions that happens. These hard problems have been worked on for 50 years and what we've ended up with is a set of solid tools (SQL databases that provides transactions). It's thanks to these tools that BE becomes easy. These tools have also been built on top of each other. A new tool often "extends" an older tool instead of "replacing" it. It comparison, look at some of the "progress" in the tooling in the front-end world: One of the biggest recent change in state management is React Hooks. This is a concept which has zero precedence in any language or literature. It's something they invented out of thin air and behaves like nothing else out there. The documentation has a big list of gotchas you need to watch out for. Does it has its advantages? Sure, it's nice for many things. But of course there's going to be rough edges when introducing such novel concepts. Cocoa has been successfully using view controllers for state management for 20 years (or more?). They've made some tweaks over the years (e.g. segues), but it's mainly stayed the same. Is state management perfect in Cocoa? No. Do you hear Cocoa developers complain about state management? Yes. Do they spend every year talking about the "new best way to handle state"? Nope. I understand that it's not completely comparable (different platforms etc), but of course state management becomes a recurring problem when you end up switching out the state management library every second year (Redux anyone?).
- nojvek 6y agoYou are right about JS fragmentation. After doing 10+ years of frontend, my theory is that frontend welcomes a lot of new self learnt programmers mostly because the browser is the runtime and almost every device has it. This means it’s pretty easy to stitch a few things and get something useful in the hands of customers. Npm makes it very easy to create new packages and libraries. All though not a significant % of community has computer science background and deeply understand what goes under the hood. StateOfJS contains stats of new programmers : old ones. Things that stay the same after a long period of time and stay successful have been reasoned from first principles to satisfy its constraints in the most efficient way possible. E.g svelte was built up this way, to track changes and propagate dom mutations in a very efficient way while still keeping the invariant of view= state of function. My point is that many things in JS are made without such fundamental analysis, so you see churn. I’m a fan of esbuild since it’s built from fundamentals (parse the AST from source only once and utilize all cores while doing it, it saturates available disk bandwidth since go is amazingly efficient at it) Those ideas are here to stay for a long time.
- amw-zero 6y agoMy personal criticism of the web FE community is not that the tools haven’t solved problems, it’s that these problems have been solved before and that is not acknowledged. For example, a single-page app is the exact same thing as a native frontend. It’s a stateful, long-running process that communicates with a backend. This is not a new paradigm, but it is treated as one in the web community. Another example is declarative UI. Microsoft had XAML and data binding well before Backbone, Angular, and React. I personally love where web UI is at today, but I get the sense that we think it’s full of these unique problems when it’s really not.
- deleted 6y ago[deleted]
- erikpukinskis 6y agoXaml was released two years before Backbone, and only five years before React. It’s a contemporary of those efforts not a predecessor. And according to the ECIS, it was created in part as a poison pill for the web UI platform. Not sure if you were around in the early part of the web’s history but Microsoft had a demonstrated pattern of using pseudo-standards to destroy competitors. But I guess, I am left unsure of what you’re suggesting. That Facebook should have ported XAML to the web instead of creating React? That would have been... faster? Better?