perf(web): remove homepage video from the LCP path

This commit is contained in:
Amruth Pillai
2026-07-28 08:35:07 +02:00
parent 30812f8a8e
commit 1e665fbe7e
6 changed files with 59 additions and 8 deletions
+2 -2
View File
@@ -16,7 +16,7 @@
<link rel="apple-touch-icon" href="/apple-touch-icon-180x180.png" type="image/png" sizes="180x180 any" /> <link rel="apple-touch-icon" href="/apple-touch-icon-180x180.png" type="image/png" sizes="180x180 any" />
<link rel="manifest" href="/manifest.webmanifest" crossorigin="use-credentials" /> <link rel="manifest" href="/manifest.webmanifest" crossorigin="use-credentials" />
<title>Reactive Resume</title> <title>Reactive Resume — A free and open-source resume builder</title>
</head> </head>
<body> <body>
<!-- Keep #app empty: main.tsx only mounts React when rootElement has no children. --> <!-- Keep #app empty: main.tsx only mounts React when rootElement has no children. -->
@@ -56,6 +56,6 @@
clip: rect(0 0 0 0); clip: rect(0 0 0 0);
} }
</style> </style>
<script type="module" src="/src/main.tsx"></script> <script type="module" data-cfasync="false" src="/src/main.tsx"></script>
</body> </body>
</html> </html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

@@ -0,0 +1,48 @@
// @vitest-environment happy-dom
import type { PropsWithChildren } from "react";
import { render } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { i18n } from "@lingui/core";
import { I18nProvider } from "@lingui/react";
type LinkProps = PropsWithChildren<{
to: string;
}>;
vi.mock("@tanstack/react-router", () => ({
Link: ({ children, to, ...rest }: LinkProps) => (
<a href={to} {...rest}>
{children}
</a>
),
}));
vi.mock("@/components/animation/comet-card", () => ({
CometCard: ({ children }: PropsWithChildren) => <div>{children}</div>,
}));
vi.mock("@/components/animation/spotlight", () => ({
Spotlight: () => <div data-testid="spotlight" />,
}));
i18n.loadAndActivate({ locale: "en", messages: {} });
const { Hero } = await import("./hero");
describe("Hero", () => {
it("shows a poster and waits for user interaction before loading the video", () => {
const { container } = render(
<I18nProvider i18n={i18n}>
<Hero />
</I18nProvider>,
);
const video = container.querySelector("video");
expect(video).toHaveAttribute("poster", "/videos/timelapse-v1.webp");
expect(video).toHaveAttribute("preload", "none");
expect(video).toHaveAttribute("src", "/videos/timelapse-v1.mp4");
expect(video).toHaveAttribute("controls");
expect(video).not.toHaveAttribute("autoplay");
});
});
+5 -5
View File
@@ -29,15 +29,15 @@ export function Hero() {
<video <video
loop loop
muted muted
autoPlay controls
playsInline playsInline
preload="none"
width={1146} width={1146}
height={720} height={720}
src="/videos/timelapse.mp4" poster="/videos/timelapse-v1.webp"
src="/videos/timelapse-v1.mp4"
aria-label={t`Timelapse demonstration of building a resume with Reactive Resume`} aria-label={t`Timelapse demonstration of building a resume with Reactive Resume`}
// Reserve the intrinsic aspect ratio so the box height is known before the video className="aspect-[1146/720] w-full rounded-md border object-cover"
// metadata loads — otherwise it reflows the centered hero column and causes CLS (~0.10).
className="pointer-events-none aspect-[1146/720] w-full rounded-md border object-cover"
/> />
<div <div
+4 -1
View File
@@ -18,7 +18,10 @@ export const Route = createFileRoute("/_home/")({
const canonicalUrl = getCanonicalRootUrl(appUrl); const canonicalUrl = getCanonicalRootUrl(appUrl);
return { return {
links: [{ rel: "canonical", href: canonicalUrl }], links: [
{ rel: "canonical", href: canonicalUrl },
{ rel: "preload", href: "/videos/timelapse-v1.webp", as: "image", fetchPriority: "high" },
],
scripts: [createRootStructuredDataScript(canonicalUrl)], scripts: [createRootStructuredDataScript(canonicalUrl)],
}; };
}, },