Precompress the bundle, validate the shell, and pass byte ranges on
The web build now writes a Brotli and a gzip copy of each compressible file, and the static handler serves the best one the browser accepts. The bundle was gzipped again for every request and Brotli was never offered; the main chunk is 122 KB with Brotli against 144 KB gzipped. index.html and every static file carry an ETag, and a matching If-None-Match gets a 304. The shell and the worker are revalidated on every load and were downloaded whole each time. Attachment downloads pass a plain byte Range to Stalwart and relay a 206, so a PDF viewer or a video element can read in pieces where the server allows it. On the reader's own device a blob is cached as immutable, since its id names its content. The upstream session and account-info caches drop entries past their age on a timer; they lost an entry only on sign-out or refusal, not when a session expired. The mock answers byte ranges.
This commit is contained in:
@@ -233,6 +233,23 @@ export interface AccountInfo {
|
||||
|
||||
const infoCache = new Map<string, { info: AccountInfo; fetchedAt: number }>();
|
||||
const INFO_CACHE_MS = 30 * 60_000;
|
||||
|
||||
/*
|
||||
* Both caches are keyed by session, and used to lose an entry only when that
|
||||
* session signed out or was refused -- not when it simply expired, which is how
|
||||
* most sessions end. An entry past its age is never used again, so dropping
|
||||
* those on a timer is all it takes to stop them accumulating.
|
||||
*/
|
||||
export function sweepUpstreamCaches(now = Date.now()): void {
|
||||
for (const [id, v] of sessionCache) if (now - v.fetchedAt >= SESSION_CACHE_MS) sessionCache.delete(id);
|
||||
for (const [id, v] of infoCache) if (now - v.fetchedAt >= INFO_CACHE_MS) infoCache.delete(id);
|
||||
}
|
||||
setInterval(() => sweepUpstreamCaches(), SESSION_CACHE_MS).unref();
|
||||
|
||||
/** How many sessions the caches hold; for tests. */
|
||||
export function upstreamCacheSizes(): { sessions: number; info: number } {
|
||||
return { sessions: sessionCache.size, info: infoCache.size };
|
||||
}
|
||||
const EMPTY_INFO: AccountInfo = { locale: null, edition: null, permissions: [] };
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user