Skip to content

Feature/no ref/landing page performance optimizations#26

Merged
urjitc merged 11 commits into
mainfrom
feature/no-ref/landing-page-performance-optimizations
Jan 16, 2026
Merged

Feature/no ref/landing page performance optimizations#26
urjitc merged 11 commits into
mainfrom
feature/no-ref/landing-page-performance-optimizations

Conversation

@urjitc

@urjitc urjitc commented Jan 16, 2026

Copy link
Copy Markdown
Member

Important

Optimizes landing page performance with dynamic imports, lazy loading, and enhances SEO using Next.js Metadata API.

  • Performance Improvements:
    • Dynamic imports for below-the-fold components in page.tsx to improve initial load time.
    • Implemented lazy loading and explicit sizing for images in Footer.tsx, FourWays.tsx, Hero.tsx, and ThreeSteps.tsx.
    • Added link prefetching in FinalCTA.tsx, Hero.tsx, Navbar.tsx, and Pricing.tsx for faster navigation.
  • SEO Enhancements:
    • Replaced client-side SEO component with Next.js Metadata API in page.tsx for better SEO management.
  • UI Enhancements:
    • Introduced BackgroundCard component in BackgroundCard.tsx for decorative background elements.
    • Updated FinalCTA.tsx, Hero.tsx, and Navbar.tsx to use BackgroundCard for improved styling.

This description was created by Ellipsis for a5e873b. You can customize this summary. It will automatically update as commits are pushed.


Summary by CodeRabbit

  • New Features

    • Added site-level SEO metadata (title, description, keywords, authors, social/open-graph, robots)
  • Performance Improvements

    • Dynamic SSR loading for below-the-fold sections
    • Added lazy loading and explicit sizes for images; link prefetching for key navigations
  • Style

    • New decorative background card system and a fixed grid background layer separating decorations from content
    • Refined navigation, footer, and CTA layout and loading behaviors

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel

vercel Bot commented Jan 16, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
thinkexv2 Canceled Canceled Jan 16, 2026 10:22pm

@coderabbitai

coderabbitai Bot commented Jan 16, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Landing page refactor: adds a shared BackgroundCard component, converts below-the-fold sections to dynamic SSR imports, adds Next.js metadata export, introduces a fixed decorative grid background layer, and applies image loading/size optimizations across landing components.

Changes

Cohort / File(s) Summary
Shared BackgroundCard System
src/components/landing/BackgroundCard.tsx
NEW: Reusable BackgroundCard component, BackgroundCardData interface, and exported cardColors palette; computes position, size, rotation, and translucent color CSS.
Hero
src/components/landing/Hero.tsx
Replaced inline background-card logic with imported BackgroundCard/cardColors; expanded card data; added image priority and responsive sizes; added prefetch on guest link.
FinalCTA
src/components/landing/FinalCTA.tsx
Replaced local background-card with shared BackgroundCard; uses BackgroundCardData[] and cardColors; renamed prop to isDesktopOnly; added prefetch on guest link.
Below-the-fold page composition
src/app/page.tsx
Replaced static imports with dynamic SSR-enabled imports for FourWays, ThreeSteps, Comparison, Pricing, FinalCTA, Footer; added exported metadata and a fixed decorative grid background layer with z-indexed content container.
Navbar & Navigation
src/components/landing/Navbar.tsx
Reworked container/motion wrapper hierarchy and desktop/mobile nav layout; adjusted CTA and account flows, moved/added prefetch and smooth-scroll handlers; preserved API surface.
Image loading & sizing
src/components/landing/FourWays.tsx, src/components/landing/ThreeSteps.tsx, src/components/landing/Footer.tsx
Added lazy loading and explicit sizes attributes to images (mobile 100vw, desktop 50vw where applicable); Footer logo changed from priority to loading="lazy"; removed inline step badge in FourWays.
Pricing CTA
src/components/landing/Pricing.tsx
Changed CTA composition to a Button using asChild with an inner Link; added prefetch attribute.

Sequence Diagram(s)

(omitted — changes are presentational and component composition; no multi-actor control flow requiring sequence diagrams)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hopped through code, stitched cards in a line,
Laid a grid that sparkles, set images to dine,
Prefetch for the pathways, metadata so bright,
Dynamic doors swing open to speed up the flight—
A jittery rabbit cheers the landing tonight! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main objective: landing page performance optimizations through dynamic imports, Metadata API, and component refactoring.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread src/components/landing/Hero.tsx Fixed

@ellipsis-dev ellipsis-dev Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed everything up to 6610672 in 2 minutes and 56 seconds. Click for details.
  • Reviewed 933 lines of code in 9 files
  • Skipped 0 files when reviewing.
  • Skipped posting 8 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. src/app/page.tsx:9
  • Draft comment:
    Dynamic imports use { ssr: true } which renders these components on the server. Confirm if SSR is needed for below‐the‐fold components for the desired performance benefits.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% The comment is asking the PR author to confirm if SSR is needed for below-the-fold components. This falls under asking the author to confirm their intention, which is against the rules. The comment does not provide a specific suggestion or point out a clear issue with the code.
2. src/components/landing/BackgroundCard.tsx:20
  • Draft comment:
    If BackgroundCard is purely decorative, consider adding aria-hidden='true' to improve accessibility.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 35% vs. threshold = 50% This is a new file being added, so all the code is technically "changed". The comment is about accessibility, which is a valid concern. However, I need to consider the rules: "Do NOT comment unless there is clearly a code change required" and "Do NOT make comments that are obvious or unimportant." The comment is conditional ("If... is purely decorative, consider..."), which makes it somewhat speculative. However, looking at the evidence, it does appear to be decorative. The suggestion is actionable and would improve accessibility. This seems like a legitimate code quality improvement that is clear and actionable. The comment uses conditional language "If... consider..." which could be seen as speculative rather than definitive. The rules state not to make speculative comments. Also, whether something is "purely decorative" might require understanding the broader context of how this component is used, which I don't have access to. While the comment uses conditional language, the evidence strongly suggests this is decorative (placeholder content, background positioning, opacity, component name). The suggestion is a clear, actionable accessibility improvement. However, the conditional phrasing does make it less definitive than ideal, and it's possible the author intentionally left it without aria-hidden for a reason I can't see. This is a borderline case. The accessibility suggestion is valid and actionable, but the conditional phrasing makes it somewhat speculative. Given the rule to err on the side of deleting comments when unsure, and the fact that this requires assumptions about the component's purpose, I'll give it a moderate-low score.
3. src/components/landing/FourWays.tsx:95
  • Draft comment:
    The numbered badge wrapper has been removed. Verify this UI change is intentional as it alters the visual indicator for each step.
  • Reason this comment was not posted:
    Comment looked like it was already resolved.
4. src/components/landing/FourWays.tsx:121
  • Draft comment:
    The Image component uses a sizes attribute with a fallback of '0vw'. Verify this value as it may lead to suboptimal image sizing on larger screens.
  • Reason this comment was not posted:
    Comment looked like it was already resolved.
5. src/components/landing/Hero.tsx:114
  • Draft comment:
    The demo Image’s sizes attribute uses a fallback value of '0vw' for desktop. Confirm this is intended since it might result in an unexpectedly small computed size.
  • Reason this comment was not posted:
    Comment looked like it was already resolved.
6. src/components/landing/Navbar.tsx:60
  • Draft comment:
    For improved accessibility, consider adding a role='navigation' to the element.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
7. src/components/landing/Pricing.tsx:25
  • Draft comment:
    Consider externalizing the pricingTiers data into a separate configuration file to enhance maintainability as the pricing structure evolves.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
8. src/components/landing/FourWays.tsx:120
  • Draft comment:
    The value in the sizes attribute is set as "(max-width: 768px) 100vw, 0vw". Please double-check if "0vw" is intended, as it might be a typo.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% The comment asks the author to "double-check" if 0vw is intended, suggesting it "might be a typo". However, this is clearly intentional - the mobile image (line 114-132) is hidden on desktop with md:hidden, so setting sizes to 0vw for desktop viewports is the correct optimization to prevent loading the image when it won't be displayed. The desktop image (line 134-153) has the inverse pattern. This is a standard Next.js Image optimization pattern. The comment is asking the author to verify something that is clearly correct, which violates the rule about not asking authors to confirm their intention or double-check things. Could there be a scenario where the md:hidden class isn't working as expected, making the 0vw problematic? Perhaps the comment author knows something about the responsive design that I'm missing from just this file. Even if there were edge cases with md:hidden, the comment doesn't identify a specific issue - it just asks the author to double-check. The pattern used here (0vw for hidden breakpoints) is a standard Next.js optimization. The comment is speculative and asks for confirmation rather than identifying a clear problem. This comment should be deleted. It asks the author to "double-check" and verify intent on code that is clearly correct - using 0vw in sizes for viewports where the image is hidden (md:hidden) is a standard Next.js optimization pattern. This violates the rule against asking authors to confirm their intention.

Workflow ID: wflow_bytizW5hcbC3GHLi

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

@greptile-apps

greptile-apps Bot commented Jan 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR implements comprehensive performance optimizations for the landing page:

  • Server Component Migration: Converted page.tsx from Client Component to Server Component, replacing client-side SEO component with Next.js Metadata API for faster initial render and better SEO
  • Code Splitting: Added dynamic imports with SSR for below-fold components (FourWays, ThreeSteps, Comparison, Pricing, FinalCTA, Footer) to reduce initial bundle size
  • Image Optimization: Added priority attribute to above-fold images, loading="lazy" to below-fold images, and responsive sizes attributes for proper image sizing
  • Link Prefetching: Added prefetch attribute to critical navigation links (/guest-setup, /dashboard) for faster subsequent navigations
  • Component Refactoring: Extracted shared BackgroundCard component from Hero and FinalCTA to reduce code duplication

Minor Issues:

  • Unused import getCardAccentColor in Hero.tsx should be removed

Confidence Score: 4/5

  • This PR is safe to merge with one minor cleanup needed
  • The performance optimizations follow Next.js best practices and are well-implemented. Dynamic imports with SSR maintain SEO while improving performance. Image optimizations with priority/lazy loading and sizes attributes are appropriate. The only issue is a minor unused import that should be cleaned up before merging.
  • src/components/landing/Hero.tsx needs the unused import removed

Important Files Changed

Filename Overview
src/app/page.tsx Converted to Server Component with dynamic imports for below-fold content; replaced client-side SEO with Metadata API. Good performance optimizations but removed wrapping fragment unnecessarily.
src/components/landing/BackgroundCard.tsx New shared component extracted from Hero and FinalCTA. Clean implementation with proper TypeScript types.
src/components/landing/Hero.tsx Refactored to use shared BackgroundCard component, added priority and sizes to images, added prefetch to CTA link. Has unused import getCardAccentColor.

Sequence Diagram

sequenceDiagram
    participant Browser
    participant NextServer as Next.js Server
    participant PageTSX as page.tsx (Server Component)
    participant Hero as Hero Component
    participant Navbar as Navbar Component
    participant Dynamic as Dynamic Components

    Note over Browser,Dynamic: Initial Page Load with Performance Optimizations

    Browser->>NextServer: GET / (landing page)
    NextServer->>PageTSX: Render Server Component
    
    Note over PageTSX: Generate SEO metadata via Metadata API<br/>(no client-side JS needed)
    
    PageTSX->>Navbar: Render (static import - above fold)
    PageTSX->>Hero: Render (static import - above fold)
    
    Note over Hero: Images with priority attribute<br/>and responsive sizes
    
    PageTSX->>Dynamic: Prepare dynamic imports (SSR: true)
    Note over Dynamic: FourWays, ThreeSteps, Comparison,<br/>Pricing, FinalCTA, Footer
    
    NextServer-->>Browser: HTML with above-fold content<br/>+ prefetch hints for critical links
    
    Note over Browser: Browser displays Hero immediately<br/>with optimized images
    
    par Parallel Asset Loading
        Browser->>Browser: Load priority images (Hero demo)
        Browser->>Browser: Prefetch /guest-setup, /dashboard
    end
    
    Browser->>Browser: Parse HTML for below-fold components
    
    par Below-fold Component Hydration
        Browser->>Dynamic: Hydrate FourWays (lazy images)
        Browser->>Dynamic: Hydrate ThreeSteps (lazy images)
        Browser->>Dynamic: Hydrate Comparison
        Browser->>Dynamic: Hydrate Pricing
        Browser->>Dynamic: Hydrate FinalCTA
        Browser->>Dynamic: Hydrate Footer (lazy logo)
    end
    
    Note over Browser: Below-fold images load with<br/>loading="lazy" as user scrolls
Loading

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

9 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment thread src/components/landing/Hero.tsx Outdated
import Image from "next/image";
import { Button } from "@/components/ui/button";
import { getCardColorCSS } from "@/lib/workspace-state/colors";
import { getCardAccentColor } from "@/lib/workspace-state/colors";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syntax: unused import - getCardAccentColor is not used anywhere in this file

Suggested change
import { getCardAccentColor } from "@/lib/workspace-state/colors";
import type { CardColor } from "@/lib/workspace-state/colors";
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/landing/Hero.tsx
Line: 6:6

Comment:
**syntax:** unused import - `getCardAccentColor` is not used anywhere in this file

```suggestion
import type { CardColor } from "@/lib/workspace-state/colors";
```

How can I resolve this? If you propose a fix, please make it concise.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 9 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="src/components/landing/BackgroundCard.tsx">

<violation number="1" location="src/components/landing/BackgroundCard.tsx:31">
P2: `isMobileOnly` currently hides the card on mobile and shows it on desktop (`hidden md:block`). If the intent is to show this card only on mobile, it should be visible on small screens and hidden on md+ (e.g., `md:hidden`).</violation>
</file>

<file name="src/components/landing/FourWays.tsx">

<violation number="1" location="src/components/landing/FourWays.tsx:141">
P2: The sizes media query treats 768px as `0vw`, but the image becomes visible at the md breakpoint (min-width 768px). This makes the browser pick a tiny srcset candidate at 768px and upscale it. Adjust the breakpoint so the visible range gets a non‑zero size.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

transform: `rotate(${card.rotation}deg)`,
opacity: 0.5,
}}
className={`rounded-md border border-foreground/20 shadow-xl ${isMobileOnly ? 'hidden md:block' : ''}`}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: isMobileOnly currently hides the card on mobile and shows it on desktop (hidden md:block). If the intent is to show this card only on mobile, it should be visible on small screens and hidden on md+ (e.g., md:hidden).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/components/landing/BackgroundCard.tsx, line 31:

<comment>`isMobileOnly` currently hides the card on mobile and shows it on desktop (`hidden md:block`). If the intent is to show this card only on mobile, it should be visible on small screens and hidden on md+ (e.g., `md:hidden`).</comment>

<file context>
@@ -0,0 +1,49 @@
+                transform: `rotate(${card.rotation}deg)`,
+                opacity: 0.5,
+            }}
+            className={`rounded-md border border-foreground/20 shadow-xl ${isMobileOnly ? 'hidden md:block' : ''}`}
+        >
+            {/* Card content placeholder */}
</file context>

Comment thread src/components/landing/FourWays.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/components/landing/BackgroundCard.tsx`:
- Around line 18-32: In BackgroundCard, the isMobileOnly prop is currently
applying the inverted Tailwind classes (`hidden md:block`) which hides the card
on mobile; update the class logic in BackgroundCard to use the correct
visibility classes for mobile-only (e.g., `block md:hidden`) or rename the prop
to isDesktopOnly and keep the existing classes—adjust the className expression
around the isMobileOnly prop accordingly so the intent matches the applied
Tailwind classes.

In `@src/components/landing/Navbar.tsx`:
- Around line 66-92: The animated motion.div currently sets borderWidth and
borderColor but not a border style, so the border won't render; update the
motion.div (the animate prop on the div with className "relative flex h-16
items-center justify-between px-6") to include a borderStyle of "solid" (e.g.,
set borderStyle: isScrolled ? "solid" : "solid" or only when isScrolled) so the
animated borderColor/borderWidth becomes visible.
🧹 Nitpick comments (1)
src/components/landing/Navbar.tsx (1)

126-154: Avoid nested interactive elements in CTA links.
Link wrapping Button nests interactive elements. Prefer Button asChild with Link inside to preserve semantics (also applies to the same CTA pattern in Hero.tsx and FinalCTA.tsx).

♻️ Suggested refactor
-                  <Link href="/guest-setup" prefetch>
-                    <Button
-                      onClick={() => posthog.capture('navbar-get-started-clicked', { location: 'desktop' })}
-                      size="sm"
-                      className="rounded-md bg-foreground font-medium text-background transition-all hover:bg-foreground/90"
-                    >
-                      Get Started
-                    </Button>
-                  </Link>
+                  <Button
+                    asChild
+                    onClick={() => posthog.capture('navbar-get-started-clicked', { location: 'desktop' })}
+                    size="sm"
+                    className="rounded-md bg-foreground font-medium text-background transition-all hover:bg-foreground/90"
+                  >
+                    <Link href="/guest-setup" prefetch>
+                      Get Started
+                    </Link>
+                  </Button>
-                  <Link href="/dashboard" prefetch>
-                    <Button
-                      onClick={() => posthog.capture('navbar-dashboard-clicked', { location: 'desktop' })}
-                      size="sm"
-                      variant="outline"
-                      className="rounded-md font-medium transition-all hover:bg-foreground/5"
-                    >
-                      Dashboard
-                    </Button>
-                  </Link>
+                  <Button
+                    asChild
+                    onClick={() => posthog.capture('navbar-dashboard-clicked', { location: 'desktop' })}
+                    size="sm"
+                    variant="outline"
+                    className="rounded-md font-medium transition-all hover:bg-foreground/5"
+                  >
+                    <Link href="/dashboard" prefetch>
+                      Dashboard
+                    </Link>
+                  </Button>

Comment thread src/components/landing/BackgroundCard.tsx Outdated
Comment thread src/components/landing/Navbar.tsx

@ellipsis-dev ellipsis-dev Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed 1955a3c in 1 minute and 5 seconds. Click for details.
  • Reviewed 22 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 2 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. src/components/landing/FourWays.tsx:120
  • Draft comment:
    Mobile image: Using sizes="100vw" is simpler now. Confirm that the container is actually full-width to avoid loading an oversized image.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50% None
2. src/components/landing/FourWays.tsx:141
  • Draft comment:
    Desktop image: Simplified sizes="50vw" works if the image consistently occupies half the viewport. Verify this matches the layout’s rendered width.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50% None

Workflow ID: wflow_nPnWXwCJdlZVKDOl

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

@sonarqubecloud

Copy link
Copy Markdown

@ellipsis-dev ellipsis-dev Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed a5e873b in 37 seconds. Click for details.
  • Reviewed 13 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. src/components/landing/Hero.tsx:122
  • Draft comment:
    Updated container's max-width from 5xl to 6xl. Please confirm this matches the intended design and maintains consistency with other containers.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50% None

Workflow ID: wflow_NEMPbYGvgtfcM7E5

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

@urjitc
urjitc merged commit 60b1dae into main Jan 16, 2026
5 checks passed
@urjitc
urjitc deleted the feature/no-ref/landing-page-performance-optimizations branch January 16, 2026 22:22
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Dev Board Jan 16, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/landing/Hero.tsx (1)

103-133: Avoid eager-loading both demo images.

Both variants are marked priority, causing unnecessary downloads regardless of CSS visibility. Next.js's priority prop preloads images independent of display properties, so both /demo.png requests occur even though only one is visible at any breakpoint, wasting bandwidth and degrading LCP.

Replace with a single responsive image using dynamic Tailwind classes and a sizes query, or remove priority from the hidden variant.

💡 Refactor to single responsive image
-          {/* Mobile Demo Image - Only visible on mobile */}
-          <div className="relative w-full md:hidden">
-            <div className="relative w-full max-w-md mx-auto px-4">
-              <div className="relative aspect-[4/3] w-full overflow-hidden rounded-md border border-foreground/20 shadow-2xl">
-                <Image
-                  src="/demo.png"
-                  alt="ThinkEx Demo"
-                  fill
-                  priority
-                  sizes="100vw"
-                  className="object-cover"
-                />
-              </div>
-            </div>
-          </div>
-
-          {/* Desktop Demo Image - Hidden on mobile */}
-          <div className="relative w-full hidden md:block">
-            <div className="relative w-full max-w-5xl mx-auto px-4">
-              <div className="relative aspect-[16/9] w-full overflow-hidden rounded-md border border-foreground/20 shadow-2xl">
-                <Image
-                  src="/demo.png"
-                  alt="ThinkEx Demo"
-                  fill
-                  priority
-                  sizes="80vw"
-                  className="object-cover"
-                />
-              </div>
-            </div>
-          </div>
+          {/* Responsive Demo Image */}
+          <div className="relative w-full">
+            <div className="relative w-full max-w-md md:max-w-5xl mx-auto px-4">
+              <div className="relative aspect-[4/3] md:aspect-[16/9] w-full overflow-hidden rounded-md border border-foreground/20 shadow-2xl">
+                <Image
+                  src="/demo.png"
+                  alt="ThinkEx Demo"
+                  fill
+                  priority
+                  sizes="(max-width: 768px) 100vw, 80vw"
+                  className="object-cover"
+                />
+              </div>
+            </div>
+          </div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant