skip to content

Request-Time Rendering

HTML built on the server for every request: nothing is sent until the route's data and render finish, so output can be per-user. Asked because freshness costs first-byte time and money per view.

on this pageshow

questions

5

When a meta-framework renders a route's HTML on the server for every request, what does the browser receive and why does it help?

level: juniorimportance: must knowfreq 82%

answer

  1. HTML made for this visit
  2. the request is in hand
  3. data read before the response
  4. crawlers and first paint
  5. finished markup, not an empty shell

basics

~20 s

The browser receives a finished document: the framework matched the URL, ran that route's server-side data work and rendered markup before replying. Content is visible in the first paint, and machines that never run scripts can read it.

solid answer

~40 s

Rendering at request time means the HTML for a visit is produced after that visit arrives. The server matches the URL to a route, runs the route's server-side data work, renders the component tree to an HTML string, serialises the data the client will need, and only then writes the response. So the bytes that land already describe the page — headings, rows, prices — instead of an empty container waiting for a bundle. That buys three things: the browser can paint real content before application JavaScript runs; crawlers, link-preview fetchers and other non-scripting clients see the content in the response body; and because the request is in hand during the render, the output can carry this user's name, permissions or cart. The page is still not interactive until client script takes it over.

go deeper

for a junior

Be able to say it plainly: the server builds this page's HTML when the request arrives, using data read right then, and sends finished markup. Name the two everyday wins — content in the first paint, and crawlers that do not run scripts.

for a middle

Walk the chain in order — match route, run server data work, render to a string, serialise the data, write the response — and explain why nothing can be sent until the render completes.

for a senior

Talk about the consequences you have operated: first-byte time now carries data latency, every view costs a render, and per-user output constrains what any cache in front may store.

for a principal

Frame it as a spend: freshness and personalisation bought with per-view server cost and a slower first byte. Be ready to say which routes deserve that spend and how you would keep the answer from drifting.

## What request-time rendering means A route is rendered at **request time** when the server produces its HTML *after* a visitor asks for the URL, using data read during that same request. Nothing about that page existed beforehand: the markup for this visit is manufactured for this visit. The chain a typical meta-framework runs on the server looks like this: 1. **Match** the incoming URL, method and headers against the router to find the route. 2. **Run the route's server-side data work** — the loaders, resolvers or server-only functions the route declares. 3. **Render** the component tree to an HTML string using the data that came back. 4. **Serialise** that same data into the document, so the client can take the page over without fetching it a second time. 5. **Write** the status line, the response headers and the finished body. The response body does not exist until step 3 is done, so the visitor waits for the whole chain. That one property — in the simple case the response is held until the route's data and render finish — is where the rest of this topic's consequences come from. A framework that flushes the document in pieces is the deliberate exception, and it is a distinct mode. ## Why produce the HTML on the server at all The alternative is to send a near-empty document and let the browser download, parse and execute JavaScript that then fetches data and builds the DOM. Rendering per request buys: - **Content in the first paint.** The arriving bytes already describe the page, so text and layout can appear before any application script has run. - **Readers that do not execute scripts.** Search crawlers, link-preview fetchers, archiving tools and some assistive tooling read the response body. What is not in it may never be seen by them. - **A shorter path to the data.** The server usually sits close to the data source. A browser round trip to an API *after* the document lands adds a whole extra hop over the visitor's own connection. - **Per-user output.** Because the render happens with the request in hand, it can read that request's cookies, headers or session and put this person's greeting, permissions or cart count straight into the markup. - **Cheap work on weak devices.** Parsing HTML costs a phone far less than executing a large bundle that builds the same DOM. ## What the visitor actually experiences The wait moves. With a client-rendered shell the document arrives quickly and the visitor looks at an empty frame or a spinner while data is fetched. With a request-time render the visitor looks at the *previous* page (or a blank tab on a cold navigation) for longer, and then sees finished content in one step. Neither ordering is free; they trade a fast-but-empty first paint against a slower-but-complete one. | Property | Rendered on the server per request | |---|---| | When the data is read | During the request, for this visitor | | When the first byte can leave | After the route's data work and render finish | | Output per visitor | May legitimately differ per user | | Shared cacheability | Only when the response is identical for everyone and the headers say so | | Server work | One render per view, so it grows with traffic | ## What the client still has to do Server HTML is markup, not a running application. Event handlers, local state and client routing only exist once client JavaScript loads and takes the existing DOM over. How much script that takes — the whole route, only interactive islands, or none at all — is a separate subject with its own tradeoffs. Until it happens the page is readable and links work, but buttons wired up in JavaScript do not. ## Where meta-frameworks differ The mechanism is shared; the defaults and the vocabulary are not. Some frameworks render on every request by default and prerender only what you mark; others prerender by default and fall back to per-request rendering when a route's render touches something request-bound. Some run the render inside a long-lived server process, others start a short-lived function per request and pay a cold start on the first one. Some can begin writing the response before the render is complete rather than holding it; that is a distinct mode with its own rules. Expect to ask which of these a given project uses instead of assuming. ## Reading the mode honestly Request-time rendering does not make data fast — it moves the wait from after the document to before it, and slow data now shows up as a slow first byte. It does not remove client JavaScript. And it does not by itself make a page cacheable or uncacheable: that depends on whether the output is the same for everyone, which the route and its response headers decide.

  • If the HTML already contains the content, why does the document also carry a serialised copy of the same data?
    So the client can take the page over without re-fetching. Client code needs the values as data, not as text nodes, to re-render on interaction and to keep its state consistent with what was painted. The cost is that the same information ships twice, inflating the document.
  • Does rendering on the server for each request mean the page works without JavaScript?
    Only for reading and for plain links and form posts. The markup arrives complete, so content and navigation can work script-free, but anything whose behaviour lives in client code stays inert until the bundle loads. How much of the experience survives without script is a design choice, not an automatic property of the mode.
  • What kind of request input can this mode use that a build-time render cannot?
    Anything that only exists per visit: cookies and session identity, request headers such as language or client hints, the query string, and the visitor's geography as the hosting layer reports it. A render performed ahead of time has none of these, so its output must be the same for everyone.

A kitchen cooking each order when it is placed rather than plating dishes in advance: the food is exactly what this customer asked for, and they wait for it.

saying these in an interview costs you the question

  • Thinks the server sends HTML and no JavaScript at all
  • Believes the page is interactive as soon as it paints
  • Assumes server rendering makes slow data fast
  • Says every request-time page can sit in a shared cache
  • Confuses rendering per request with rendering ahead of time
  • Assumes the server always flushes markup while the render is still running
open as a page

Why does a route rendered on the server for each request send nothing to the browser until its data and render finish?

level: middleimportance: must knowfreq 70%

basics

~20 s

The response body is the rendered markup, and markup cannot be produced before the values it prints are known. So the request waits for the route's server data work plus render time, and the first byte carries both of those costs.

open as a page

Why does a route whose HTML is rendered per request cost more server work as its traffic grows?

level: middleimportance: should knowfreq 54%

basics

~20 s

Every view is its own render: one route match, one set of data reads, one tree rendered to a string, one serialisation. That work is repeated per visitor rather than amortised, so compute, upstream load and concurrency all track traffic almost linearly.

open as a page

A per-request rendered page that greets the signed-in user starts showing one person's name to other visitors after a CDN was added. Why, and how do you prevent it?

level: seniorimportance: should knowfreq 50%

basics

~20 s

A shared cache stored one visitor's personalised render and replayed it to everyone matching the same cache key, which is usually method plus URL and ignores the session cookie. Personalised responses must declare themselves uncacheable by shared caches, or vary the key.

open as a page

For a route rendered on every request, how do you set policy for what the render does when a data source is slow or unavailable?

level: principalimportance: should knowfreq 38%

basics

~20 s

Decide per data source, not per route: which reads are essential to the page and which are decoration. Essential reads justify holding the response to a bounded deadline then failing; optional ones get a short timeout and render without them.

open as a page