When Pages Arrive Out of Order: Rethinking Web Architecture as Behavior, Not Labels
Hatched by Jaeyeol Lee
Apr 15, 2026
9 min read
2 views
78%
Hook: What if the web is not a site or an app, but a choreography of time, network, and state?
We have been arguing about websites versus web apps as if they were species. That argument misses the point. The more useful question is not what we call them, but how they behave under the twin pressures of network reality and user expectation: how much interactivity do they demand, how much can they rely on a server, and how do they handle information that arrives late, out of order, or never?
Treating web projects as discrete categories leads to brittle design. Thinking of them as combinations of dynamism, network dependency, and temporal mutability gives a design map you can actually use. Add the idea that some updates arrive out of order and you get a lens that unifies static pages, realtime collaboration, local-first apps, and streaming UIs into one coherent practice.
Setup: The two false binaries that hide the real tradeoffs
People tend to sort experiences into two buckets: mostly static documents, or interactive applications. That split is seductive because it is simple, but it obscures the mechanisms that actually shape user experience. Two simple axes reveal the complexity: dynamism, which measures how much the UI changes in response to state and input, and network dependency, which measures how much the experience requires a live, authoritative server.
Plot any site on these axes and you get four quadrants that are more useful than the “site versus app” label:
- Static and offline: informational pages, simple documentation, single-file content. These favor full page swaps or server-rendered HTML with minimal client logic.
- Static and online: transactional sites that reach out to servers for discrete operations, such as checkout flows or search. They combine predictable UI with server-driven actions.
- Dynamic and online: realtime experiences where the server mediates updates between clients, such as messaging or dashboards.
- Dynamic and offline: local-first apps that can operate without a central server for extended periods, such as note-taking or embedded device UIs.
These quadrants are not taxonomy endpoints. They are waypoints on a continuum. Many real products move between them during a single session. A news site is mostly informational until a reader comments. A progressive web app can be both local and online depending on connectivity. This fluidity is where architecture choices matter.
Two additional forces push developers toward certain patterns: JavaScript and streaming.
JavaScript is often used as a tool for perceived dynamism: animations, incremental loading, and micro-interactions that signal liveness. But adding script is not a binary solution. Modern techniques such as server-driven components and resumability blur where behavior lives, enabling small amounts of client-side code to deliver rich interaction while keeping server authority intact.
Streaming brings a separate concern: the order and mutability of the data you send. When a response is streamed out of order, you can render a UI before you have every piece of information. That gives speed and memory benefits, but it imposes constraints: once a chunk is sent, it cannot be taken back. That changes how you think about updates, errors, and eventual consistency.
Exploration: What out-of-order streaming reveals about design constraints
Imagine two cases.
Case A: You render a long article with embedded interactive figures. You stream the article markup progressively, so a user sees the headline and first paragraphs immediately. Later you stream the interactive visualization code and data. The visualization can mount and enhance the already-visible content.
Case B: You render a live dashboard where metrics refresh frequently. You stream initial values quickly, then stream incremental updates as they arrive out of order. Clients must reconcile later updates with the initial state.
The key difference is not streaming itself, but the relationship between sent bytes and the evolving truth of the system. When you stream static content, the user experience benefits from early paint and progressive enhancement. When you stream dynamic state, you create a temporal sequence that the client must interpret and reconcile.
This produces several practical tensions:
-
Immutability versus mutability: Sent data is effectively immutable. You can stream a chunk early, but you cannot retroactively change those bytes. To change what the user sees you must send additional patches or instruct the client to replace content.
-
Latency versus correctness: Streaming early reduces time-to-first-paint. But if later updates change critical facts, the user experiences a brief inconsistency or a visible patch. For transactional flows this can be unacceptable. For news reading it is often fine.
-
Memory versus composability: Streaming large files avoids holding everything in memory. It also forces a design where portions are self-contained and composable, rather than requiring a global rewrite.
-
Coordination versus autonomy: Local-first apps make clients autonomous, but conflict resolution must be handled without a central authority. Streaming from a central server simplifies coordination but sacrifices offline autonomy.
These tensions are not merely engineering concerns; they are product decisions. Choosing where your product sits on the dynamism and network axes constrains whether streaming out-of-order is a boon or a liability.
Synthesis: A three-axis model for designing web behavior
To reason about these tradeoffs, add a third axis to the dynamism and network dimensions: temporal mutability, which measures how tolerant your experience is to out-of-order or late-arriving updates and how easy it is to patch the view after initial render.
Visualize a design cube with three axes:
- X axis: dynamism, from static text to rich, stateful interaction.
- Y axis: network dependency, from fully local to fully server-reliant.
- Z axis: temporal mutability, from append-only immutable streams to fully replaceable state that accepts out-of-order patches.
Every product occupies a region of this cube. The region determines practical strategies for streaming, state reconciliation, and user expectations.
Concrete placements:
-
A blog post: low dynamism, low network dependency, low temporal mutability. It benefits from progressive streaming that paints content first and enhances later. Out-of-order streaming here is more about progressive loading than state reconciliation.
-
An e-commerce checkout: medium dynamism, high network dependency, low temporal mutability. Early streaming of UI skeletons is fine, but key facts such as price and inventory cannot be allowed to be stale. Patches must be authoritative and validated.
-
A chat app: high dynamism, high network dependency, high temporal mutability. Messages arrive in different orders, edits happen, and deletions occur. Design for incremental, idempotent updates and reconcile with server-supplied sequence metadata.
-
A local-first notes app: medium dynamism, low network dependency, high temporal mutability. Clients are autonomous and must resolve conflicts using CRDTs or operational transforms. Streaming from cloud backups is append-only; local edits may later be merged.
This cube informs technical choices. For each axis, there are patterns that help you operate within the constraints.
Pattern catalog:
-
Progressive render plus enhancement: Stream critical HTML for immediate read, then stream behavior and data to enhance. This suits low temporality and low mutation scenarios.
-
Idempotent incremental updates: Send updates that can be applied multiple times without harm. Use versioning or causal metadata so the client knows whether an update is new or obsolete. This suits highly dynamic, server-mediated flows.
-
Patch-based reconciliation: Instead of attempting to mutate prior chunks, send patches or deltas that transform the client's local representation. Keep patches small and composable.
-
Local-first conflict resolution: For apps that must work offline, embed conflict resolution logic in the client using CRDTs, and sync periodically. Treat server streams as one source of reconciliation, not the single source of truth.
-
Append-only streaming with tombstones: If you cannot change previously sent bytes, model changes as new events: edits, deletions, or annotations that refer to previous items. This is helpful when streaming large immutable assets or event logs.
These patterns are not exclusive. A single product may mix them. The important insight is that your architecture must answer a normative question: how do you want your users to experience time?
Actionable insight: How to choose architecture and streaming strategy
Design decisions should start with user expectations and failure modes, not with labels or frameworks. Use the cube to drive development choices using the checklist below.
Checklist for architecture and streaming:
- Where does my product sit on the dynamism axis? Is the experience primarily read, transactional, or collaborative?
- How dependent is it on a live server? Do offline capabilities matter for core use cases?
- How tolerant is the UX to out-of-order, late, or patched updates? Do users need absolute consistency, or is eventual correctness acceptable?
- What are the visible failure modes for early streaming? If a streamed chunk is wrong, can the client patch gracefully? Will the user trust the product after a visible correction?
- Which pattern minimizes cognitive load for users while meeting constraints: progressive enhancement, idempotent updates, patches, CRDTs, or append-only events?
Apply these answers to choose concrete techniques:
-
If low mutability and offline-friendly: prefer server-rendered HTML streamed progressively, with small client behavior added for interactivity. Use resumability to avoid heavy hydration costs.
-
If high mutability and server-reliant: build an incremental update protocol with causal metadata and idempotent operations. Accept that some content will be patched visibly.
-
If local-first: invest in conflict-free data structures and design sync as a best-effort background process. Use append-only change logs for predictable merging.
-
If streaming large assets: structure the asset as a sequence of independent chunks so the client can render, stream, or discard parts without global memory pressure.
Concrete example: designing a dashboard that streams metrics and serves offline first.
- Start with an initial snapshot streamed to the client for fast paint.
- Stream metric updates as discrete, idempotent events with sequence numbers and timestamps so the client can apply them in order, or discard stale ones.
- If offline mode is required, persist local edits and queue them as asynchronous operations. Use a CRDT or merge policy for non-conflicting fields. When syncing, treat the server stream as authoritative for events that have not been edited locally.
Key Takeaways
-
Web projects are defined by behavior, not by the label site or app. Think in terms of dynamism, network dependency, and temporal mutability when making architecture choices.
-
Out-of-order streaming gives speed and memory advantages, but it imposes a model where sent bytes are effectively immutable. Solve mutability with patches, idempotent updates, or append-only events.
-
Use a simple design cube to position your product and pick patterns. Match streaming and state strategies to user expectations about latency and correctness.
-
For realtime and collaborative apps, build incremental, idempotent update protocols and consider causal metadata. For local-first apps, invest in client-side conflict resolution and treat the server as a synchronizer, not the sole authority.
-
Always design for visible failure modes: if a late update will visibly change the UI, ensure the patching experience is clear, fast, and trustworthy.
Conclusion: Rethink names, design for time
Calling something a website or a web app is like calling a vehicle a car or a truck. The categories are useful for marketing but useless for engineering. The web is a medium for delivering behavior across imperfect networks and imperfect devices. The real design work happens at the intersection of interactivity, connectivity, and time.
When you accept that streamed bytes are commitments, that updates may arrive out of order, and that local autonomy sometimes matters more than central coordination, you stop picking frameworks and start designing behavior. That shift changes priorities: speed without confusion, autonomy without chaos, and updates that feel natural rather than patched on.
Next time you plan an interface, do not ask whether it is a site or an app. Ask how it should age in the hands of imperfect networks and real humans. Build the experience around that answer, and the technical choices will follow.
The web is not about pages or programs. It is about time, truth, and the stories we stream to users. Plan for the order you want them to remember.
Sources
Hatch New Ideas with Glasp AI 🐣
Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)
Start Hatching 🐣