Random notes from Navigate the Future of Frontend
theres a tension between tool being highly capable and highly suitable. by suitable we mean well fit for a specific domain/purpose/context.
the trade offs are NOT 1-1 tho. there are subtle paths where you gain capability without losing suitability, and vice versa. so this is tricky.
the client has limited compute, but it happens right in front of the user providing immediate feedback.
the server has wide, parallel compute, but it happens far away from the user, causing network latency.
the store is similar for storage.
the client has limited storage, but it happens right in front of the user providing immediate access.
the server has wide, parallel storage, but it happens far away from the user, causing network latency.
we write code in one repo and deploy to client and server
next-gen bundlers make this possible
when we move to thicc clients, we had to suspend rendering until we had all files, we parsed all files, executed code, then rendered (and maybe even fetched some data)
this caused TTFB (time to first byte) to be high and a slow LCP (largest contentful paint)
with suspense, we can have phased loading stages -> instead of a popcorn of loading spinners.
RSC (React Server Components) can stream virtual DOM for in-place transitions.
aka suspense solves the problem of consistent rendering when it is async and can be streamed in any order
this can give us "partial pre-rendering"
suspense + RSC + next-gen bundlers = partial pre-rendering
framework-defined infrastructure is the idea that the framework can define the infrastructure for you. this is a big deal because it means you can focus on the app and not the infrastructure.
streaming!
to avoid network waterfalls, we chose to have statically defined routes.
and once you have statically defined routes, its easy to have file-system-based-routing. (another option is a configuration file)
this creates a hierarchical tree structure of routes.
"backend for frontends" is a design pattern familiar in a service-oriented backend environment
the idea is there is a custom backend for each frontend.
this is made even more powerful with RSC (React Server Components)
BFF allows for
move all this stuff out of the client means we can do more with caching!
a MAJOR source of complexity in any system is state management
BIG part of the work in frontend is keep its state in sync with the server.
(we'd love love love to have local first when building applications and using stuff like CRDTs)
traditionally, we'd POST on form submit, redirect to a new page, and then GET/fetch the new page/data.
Remix and SvelteKit send writes with form data to route level server actions.
next and solidstart allow for server actions to be called anywhere in the component tree, this makes them more like RPCs ->
this request-response model has coarse-grained updates at the route (or nested route) level.
this is a decent default for a large percentage of experiences, however, there are times when we want fine-grained cache-management/updates/client side data loading.
TODO: when is it better to use server actions vs client side data loading?
aligned to teams that work in full-stack vertical slices or steel threads
server-driven UIs are a natural fit for server components. they allow for native mobile apps to use the same server components as the web app. react-strict-dom is a good example of this.
generative UIs are a natural fit for server components. this happens when you need to have the data before you know what components to render, think CMS content types. also this wild example where you have AI function calling a server component to generate a UI.