Caching¶
A website is fast before any cache : its JSX is compiled to string templates when a file is saved, each thread of the server keeps an engine per website with its code loaded, and a page reads its data next to the database. A page of a hundred rows renders in a tenth of a millisecond of JavaScript.
On top of that, the server keeps whole pages.
Pages kept by the server¶
export const config: PageConfig = {
cache: {
maxAge: 60, // kept 60 seconds
staleWhileRevalidate: 300, // then sent for 300 more while one request makes it anew
scope: 'public', // one page for every anonymous visitor
tags: ['products'], // dropped by ctx.revalidate('products')
query: ['page', 'sort'], // the parts of the query which make another page
},
};
scope |
Kept for | A signed-in visitor |
|---|---|---|
'public' |
Every anonymous visitor : one page | Gets a page of its own, never one kept for others |
'user' |
Each visitor : one page per visitor | Gets its own kept page |
'none' (default) |
Nobody |
cacheof a layout applies to the pages inside it ;cacheofsite.config.tsto every page which says nothing.- A page is kept under its website, the version of the website, its path, the parts of its query (
query, all of them by default, in their order), and the visitor for'user'. A save of the website drops every kept page : a new version is a new key. - The answer says what happened in
x-am-cache:MISS(made and kept),HIT(sent as kept),BYPASS(not kept, see below). - The preview of the panel never keeps pages.
- What is kept has a size in all (
ssr.cacheMbof the server, 64 MiB by default) : past it, the pages used longest ago go. A page larger than a quarter of it is not kept.
Dropping kept pages¶
export async function POST(ctx: PageContext) {
// ... a product is saved ...
await ctx.revalidate('products');
return { saved: true };
}
ctx.revalidate(...tags) drops the pages of these tags in this server. A pull of git and a save in the panel drop every page of the website on every server.
What is never kept for everyone¶
A page kept for everyone shows nothing of its visitor. The server keeps none which :
- was made for a request with messages of
ctx.flash; - set cookies, or keeps a message for the next page ;
- read what differs from one visitor to the next :
ctx.cookies,ctx.headers,ctx.ip,ctx.localeorctx.csrf. Such a page is sent (x-am-cache: BYPASS), not kept ; - did not answer
200.
What a loader writes into a page is up to it : never put a value of ctx.user into a page with scope: 'public' — a signed-in visitor never gets a public page, but keep the rule anyway.
A count in the header without losing the cache
The shop template shows the count of the cart in its header with a script, from a cookie which holds no secret : its pages stay the same for every anonymous visitor, and the server keeps them.
What browsers keep¶
- A page kept for everyone is sent with
cache-control: no-cache: browsers ask again (the page holds the CSRF token of its visitor), the server answers from its cache. - A page per visitor :
private, max-age=…. A page of a signed-in visitor otherwise :private, no-store. - A JSON endpoint with
scope: 'public'which read nothing of its visitor :public, max-age=…, stale-while-revalidate=…— a CDN may keep it. - Public files with the hash of their content (
asset('/app.css')) :immutable, a year. Without it : anETag, and304when nothing changed.
The settings of the server¶
| Setting | Default | What it is |
|---|---|---|
ssr.threads |
the cores | Threads which render pages |
ssr.enginesPerThread |
64 | Websites a thread keeps loaded |
ssr.memoryMb |
64 | Memory of an engine |
ssr.cpuMs |
2000 | Time of the code of one render |
ssr.timeoutMs |
30000 | Time of one render in all, the waits for data included |
ssr.cacheMb |
64 | Size of the pages kept, 0 for none |