perf: open large HTML messages with one request instead of two

This commit is contained in:
Linus Rath
2026-10-15 06:05:22 +02:00
parent 2ee59aa41b
commit 15c3acd779
2 changed files with 27 additions and 1 deletions
+22
View File
@@ -172,4 +172,26 @@ describe('JMAPClient truncated body refetch (#884)', () => {
expect(emails.find((e) => e.id === 'email-1')?.bodyValues?.html1.value).toBe('full-1');
expect(emails.find((e) => e.id === 'email-2')?.bodyValues?.html1.value).toBe('full-2');
});
it('getEmail fetches a body just over the list cap in one request', async () => {
// Opening one message needs all of its body; at the list-sized 256 kB cap
// a 300 kB newsletter came back truncated and was fetched twice.
const client = await createConnectedClient();
const html = '<html>' + 'x'.repeat(300_000) + '</html>';
fetchSpy.mockImplementation(async (_input, init) => {
const call = JSON.parse((init as RequestInit).body as string).methodCalls[0][1];
const cap = call.maxBodyValueBytes as number;
return mockFetchResponse(200, {
methodResponses: [['Email/get', { list: [{
...truncatedEmail(),
bodyValues: { html1: { value: html.slice(0, cap), isTruncated: html.length > cap } },
}] }, '0']],
});
});
const email = await client.getEmail('email-1');
expect(fetchSpy).toHaveBeenCalledTimes(1);
expect(email?.bodyValues?.html1.value).toBe(html);
});
});
+5 -1
View File
@@ -27,6 +27,10 @@ import { toInertBlob } from "@/lib/file-preview";
// / #884). Bounded well above the default so it stays rare in practice while
// still guarding against unbounded memory use on a malicious/oversized body.
const TRUNCATED_BODY_REFETCH_MAX_BYTES = 8_000_000;
// Opening one message needs its whole body, so its fetch takes more than the
// list-sized cap: a newsletter just over 256 kB came back truncated and was
// fetched a second time. Larger bodies still take the refetch above.
const OPEN_EMAIL_MAX_BODY_BYTES = 1_000_000;
// Names of nodes created over WebDAV come back percent-encoded from
// FileNode/get (see decodeFileNodeName / #869). Normalize at the boundary so
@@ -2369,7 +2373,7 @@ export class JMAPClient implements IJMAPClient {
fetchTextBodyValues: true,
fetchHTMLBodyValues: true,
fetchAllBodyValues: true,
maxBodyValueBytes: 256000,
maxBodyValueBytes: OPEN_EMAIL_MAX_BODY_BYTES,
}, "0"],
]);