perf: prefetch email theme previews during earlier onboarding steps (#1655)

This commit is contained in:
Konsti Wohlwend 2026-06-23 15:46:03 -07:00 committed by GitHub
parent 59f6e53f7e
commit a6c46db72c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 10 additions and 2 deletions

View File

@ -234,6 +234,7 @@ describe("ProjectOnboardingWizard", () => {
throw new Error("Stripe account info should not load on the app selection step.");
});
const listEmailThemes = vi.fn(async () => []);
const getEmailPreview = vi.fn(async () => "");
const getStripeAccountInfo = vi.fn(async () => null);
render(
@ -265,6 +266,7 @@ describe("ProjectOnboardingWizard", () => {
app: {
setupPayments: vi.fn(async () => ({ url: "https://example.com" })),
listEmailThemes,
getEmailPreview,
getStripeAccountInfo,
useEmailThemes,
useStripeAccountInfo,
@ -280,6 +282,7 @@ describe("ProjectOnboardingWizard", () => {
);
expect(listEmailThemes).toHaveBeenCalledOnce();
expect(getEmailPreview).not.toHaveBeenCalled();
expect(getStripeAccountInfo).not.toHaveBeenCalled();
expect(useEmailThemes).not.toHaveBeenCalled();
expect(useStripeAccountInfo).not.toHaveBeenCalled();

View File

@ -33,6 +33,7 @@ import {
import { AuthPage, type AdminOwnedProject } from "@hexclave/next";
import { type AppId } from "@hexclave/shared/dist/apps/apps-config";
import { type EnvironmentConfigOverrideOverride } from "@hexclave/shared/dist/config/schema";
import { previewTemplateSource } from "@hexclave/shared/dist/helpers/emails";
import { runAsynchronously, runAsynchronouslyWithAlert } from "@hexclave/shared/dist/utils/promises";
import { Suspense, useCallback, useEffect, useMemo, useRef, useState } from "react";
@ -187,7 +188,10 @@ export function ProjectOnboardingWizard(props: {
}
runAsynchronously(async () => {
await project.app.listEmailThemes();
const themes = await project.app.listEmailThemes();
await Promise.allSettled(themes.map((theme) =>
project.app.getEmailPreview({ themeId: theme.id, templateTsxSource: previewTemplateSource })
));
}, { noErrorLogging: true });
}, [isLinkExistingMode, project.app, status]);

View File

@ -828,7 +828,8 @@ export class _HexclaveAdminAppImplIncomplete<HasTokenStore extends boolean, Proj
}
async getEmailPreview(options: { themeId?: string | null | false, themeTsxSource?: string, templateId?: string, templateTsxSource?: string }): Promise<string> {
return (await this._interface.renderEmailPreview(options)).html;
const result = Result.orThrow(await this._emailPreviewCache.getOrWait([options.themeId, options.themeTsxSource, options.templateId, options.templateTsxSource], "write-only"));
return result.html;
}
// IF_PLATFORM react-like
useEmailPreview(options: { themeId?: string | null | false, themeTsxSource?: string, templateId?: string, templateTsxSource?: string }): string {