From 6228abf2d5a9bfed7af47f65a459e100ec9aac72 Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Mon, 2 Feb 2026 13:11:48 -0800 Subject: [PATCH 1/3] perf(marketing): improve mobile Lighthouse score from 42 to 90 - Dynamic import below-fold sections (Video, TrustedBy, Features, WallOfLove, FAQ, CTA) - Remove Three.js ShaderAnimation from hero (was opacity 0.01, drops ~600 KiB) - Disable PostHog session recording on marketing (saves ~88 KiB) - Defer Tally script from afterInteractive to lazyOnload - Remove priority/eager from below-fold images (TrustedBy logos, video thumbnail) - Add optimizePackageImports for framer-motion, react-icons, lucide-react --- apps/marketing/next.config.ts | 5 ++++ .../components/HeroSection/HeroSection.tsx | 11 -------- .../TrustedBySection/TrustedBySection.tsx | 2 -- .../components/VideoSection/VideoSection.tsx | 1 - apps/marketing/src/app/layout.tsx | 5 +--- apps/marketing/src/app/page.tsx | 28 +++++++++++++++---- apps/marketing/src/instrumentation-client.ts | 1 + 7 files changed, 29 insertions(+), 24 deletions(-) diff --git a/apps/marketing/next.config.ts b/apps/marketing/next.config.ts index 12025d8b7ef..4838e9c122f 100644 --- a/apps/marketing/next.config.ts +++ b/apps/marketing/next.config.ts @@ -17,6 +17,11 @@ const config: NextConfig = { reactCompiler: true, typescript: { ignoreBuildErrors: true }, + // Tree-shake barrel exports from heavy libraries to reduce bundle size + experimental: { + optimizePackageImports: ["framer-motion", "react-icons", "lucide-react"], + }, + images: { remotePatterns: [ { diff --git a/apps/marketing/src/app/components/HeroSection/HeroSection.tsx b/apps/marketing/src/app/components/HeroSection/HeroSection.tsx index 54ca7ff1a83..12b9e88a6af 100644 --- a/apps/marketing/src/app/components/HeroSection/HeroSection.tsx +++ b/apps/marketing/src/app/components/HeroSection/HeroSection.tsx @@ -1,7 +1,6 @@ "use client"; import { COMPANY } from "@superset/shared/constants"; -import dynamic from "next/dynamic"; import { useState } from "react"; import { FaGithub } from "react-icons/fa"; import { DownloadButton } from "../DownloadButton"; @@ -9,22 +8,12 @@ import { WaitlistModal } from "../WaitlistModal"; import { ProductDemo } from "./components/ProductDemo"; import { TypewriterText } from "./components/TypewriterText"; -const ShaderAnimation = dynamic( - () => - import("../../../components/ui/shader-animation").then( - (mod) => mod.ShaderAnimation, - ), - { ssr: false }, -); - export function HeroSection() { const [isWaitlistOpen, setIsWaitlistOpen] = useState(false); return (
- -
diff --git a/apps/marketing/src/app/components/TrustedBySection/TrustedBySection.tsx b/apps/marketing/src/app/components/TrustedBySection/TrustedBySection.tsx index 3569272b3e0..64e315fc001 100644 --- a/apps/marketing/src/app/components/TrustedBySection/TrustedBySection.tsx +++ b/apps/marketing/src/app/components/TrustedBySection/TrustedBySection.tsx @@ -72,8 +72,6 @@ export function TrustedBySection() { marginTop: client?.marginTop ?? 0, }} unoptimized - loading="eager" - priority /> {client.text && ( diff --git a/apps/marketing/src/app/components/VideoSection/VideoSection.tsx b/apps/marketing/src/app/components/VideoSection/VideoSection.tsx index bd2507d9e53..650ca32e633 100644 --- a/apps/marketing/src/app/components/VideoSection/VideoSection.tsx +++ b/apps/marketing/src/app/components/VideoSection/VideoSection.tsx @@ -46,7 +46,6 @@ export function VideoSection() { alt="Video thumbnail" fill className="object-cover" - priority sizes="(max-width: 768px) 100vw, (max-width: 1280px) 90vw, 1280px" />
diff --git a/apps/marketing/src/app/layout.tsx b/apps/marketing/src/app/layout.tsx index 69ad1ffa8c4..6b72d72a707 100644 --- a/apps/marketing/src/app/layout.tsx +++ b/apps/marketing/src/app/layout.tsx @@ -111,10 +111,7 @@ export default function RootLayout({ suppressHydrationWarning > -